我正在绘制一些形状(如圆),使它们与窗口的高度和宽度相对应。由于窗口始终从给定尺寸开始,因此它们被正确地绘制出来,但当窗口被调整大小时,它会破坏纵横比。
无论窗口大小如何,我该如何正确地绘制这些形状?
调整视口
glViewport(0, 0, width, height)
调整剪刀矩形(仅在启用GL_SCISSOR_TEST
时)
glScissor(0, 0, width, height)
调整投影矩阵
对于传统(固定功能管线)OpenGL,您可以按照以下方式进行操作:
glFrustum(left * ratio, right * ratio, bottom, top, nearClip,farClip)
或者glOrtho(left * ratio, right * ratio, bottom, top, nearClip,farClip)
或者gluOrtho2D(left * ratio, right * ratio, bottom, top)
(假设left,right,bottom
和top
都相等,且ratio=width/height
)
gluPerspective(60, (double)width/(double)height, 1, 256);
您需要设置一些窗口处理函数,每当OpenGL窗口被调整大小时就会调用。您需要分别处理aspectRatio>1和aspectRatio<= 1的情况。否则,在屏幕调整大小后可能会导致几何体脱离屏幕。
void windowResizeHandler(int windowWidth, int windowHeight){
const float aspectRatio = ((float)windowWidth) / windowHeight;
float xSpan = 1; // Feel free to change this to any xSpan you need.
float ySpan = 1; // Feel free to change this to any ySpan you need.
if (aspectRatio > 1){
// Width > Height, so scale xSpan accordinly.
xSpan *= aspectRatio;
}
else{
// Height >= Width, so scale ySpan accordingly.
ySpan = xSpan / aspectRatio;
}
glOrhto2D(-1*xSpan, xSpan, -1*ySpan, ySpan, -1, 1);
// Use the entire window for rendering.
glViewport(0, 0, windowWidth, windowHeight);
}
有很多方法可以做到这一点。 以下示例向您展示了我在我的项目中如何实现它以及它的工作原理。 该示例仅显示一个矩形框,当窗口调整大小时不会改变其大小。您可以直接将其复制并粘贴到您的项目中(请注意,我是OpenGL初学者)。
#include<windows.h>
#include<glut.h>
GLfloat x1=100.0f;
GLfloat y1=150.0f;
GLsizei rsize = 50;
GLfloat xstep=1.0f;
GLfloat ystep=1.0f;
GLfloat windowWidth;
GLfloat windowHeight;
void scene(void){
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0f,0.0f,0.0f);
glRectf(x1,y1,x1+rsize,y1-rsize);
glutSwapBuffers();
}
void setupRc(void){
glClearColor(0.0f,0.0f,1.0f,0.0f);
}
void changeSize(GLsizei w,GLsizei h){
if(h==0)
h=1;
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if(w>=h){
windowWidth=250.0f*w/h;
windowHeight=250.f;
}
else{
windowWidth=250.0f;
windowHeight=250.f*h/w;
}
glOrtho(0.0f,windowWidth,0.0f,windowHeight,1.0f,-1.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void main(void){
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
glutCreateWindow("Rectangle");
glutReshapeFunc(changeSize);
glutDisplayFunc(scene);
setupRc();
glutMainLoop();
}
我也在学习OpenGL。昨天我遇到了这个问题,但是一直没有找到正确的答案。今天,我终于解决了这个问题。在我的小程序中,当改变窗口的宽度或高度时,对象会改变大小。以下是我的代码(请原谅我的错误):
#include <GL/freeglut.h>
void fnReshape(int ww, int hh)
{
GLdouble r;
if(hh == 0)
hh = 1.0;
if(hh > ww)
r = (double) hh / (double) ww;
else
r = (double) ww / (double) hh;
glViewport(0, 0, ww, hh);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if(hh > ww)
glFrustum(-1.0, 1.0, -1.0 * r, 1.0 * r, 2.0, 200.0);
else
glFrustum(-1.0 * r, 1.0 * r, -1.0, 1.0, 2.0, 200.0);
}
//////////////////////////////////////////////////////////////////
void fnDisplay(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0., 0., -5.);
glBegin(GL_QUAD_STRIP);
glColor3f(0., 0., 1.0);
glVertex3f(-1., -1., 0.);
glVertex3f(-1., 1., 0.);
glVertex3f(1., -1., 0.);
glVertex3f(1., 1., 0.);
glEnd();
glutSwapBuffers();
}
////////////////////////////////////////////////////////////
int main(int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA |GLUT_DOUBLE);
glutInitWindowSize(500, 500);
glutCreateWindow("Sample window");
glClearColor(1.0, 0, 0, 1.0);
glutDisplayFunc(fnDisplay);
glutReshapeFunc(fnReshape);
glutMainLoop();
return 0;
}
glScissor()
设置了剪辑矩形,则裁剪也会影响重绘区域。请参见此处。 - zwcloud