了解 opengl 的 (glut) 调整大小
我正在 opengl 教程的在线版本上阅读贝塞尔曲线的示例代码。
我很好奇示例中如何处理调整大小,因为我想我可能会在我自己的程序版本中使用它,我将我的问题放在它的注释中:
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei) w, (GLsizei) h); // what's GLsizei? Why is it called inside glViewPort?
glMatrixMode(GL_PROJECTION); // is it necessary to reset the projection matrix?
glLoadIdentity();
if (w <= h) // is this calculation universal, could I use it on another program?
glOrtho(-5.0, 5.0, -5.0*(GLfloat)h/(GLfloat)w,
5.0*(GLfloat)h/(GLfloat)w, -5.0, 5.0);
else
glOrtho(-5.0*(GLfloat)w/(GLfloat)h,
5.0*(GLfloat)w/(GLfloat)h, -5.0, 5.0, -5.0, 5.0);
glMatrixMode(GL_MODELVIEW); // why do I set to GL_MODELVIEW at the end?
glLoadIdentity(); // why does it get a reset?
}
完整代码:
#include <stdlib.h>
#include <GL/glut.h>
GLfloat ctrlpoints[4][3] = {
{ -4.0, -4.0, 0.0}, { -2.0, 4.0, 0.0},
{2.0, -4.0, 0.0}, {4.0, 4.0, 0.0}};
void init(void)
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_FLAT);
glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, &ctrlpoints[0][0]);
glEnable(GL_MAP1_VERTEX_3);
}
void display(void)
{
int i;
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 1.0, 1.0);
glBegin(GL_LINE_STRIP);
for (i = 0; i <= 30; i++)
glEvalCoord1f((GLfloat) i/30.0);
glEnd();
/* The following code displays the control points as dots. */
glPointSize(5.0);
glColor3f(1.0, 1.0, 0.0);
glBegin(GL_POINTS);
for (i = 0; i < 4; i++)
glVertex3fv(&ctrlpoints[i][0]);
glEnd();
glFlush();
}
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei) w, (GLsizei) h); // what's GLsizei? Why is it called inside glViewPort?
glMatrixMode(GL_PROJECTION); // is it necessary to reset the projection matrix?
glLoadIdentity();
if (w <= h) // is this calculation universal, could I use it on another program?
glOrtho(-5.0, 5.0, -5.0*(GLfloat)h/(GLfloat)w,
5.0*(GLfloat)h/(GLfloat)w, -5.0, 5.0);
else
glOrtho(-5.0*(GLfloat)w/(GLfloat)h,
5.0*(GLfloat)w/(GLfloat)h, -5.0, 5.0, -5.0, 5.0);
glMatrixMode(GL_MODELVIEW); // why do I set to GL_MODELVIEW at the end?
glLoadIdentity(); // why does it get a reset?
}
void keyboard(unsigned char key, int x, int y)
{
switch (key) {
case 27:
exit(0);
break;
}
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize (500, 500);
glutInitWindowPosition (100, 100);
glutCreateWindow (argv[0]);
init ();
glutDisplayFunc(display);
glutReshapeFunc(reshape); // el reshape funciona correctamente
glutKeyboardFunc (keyboard);
glutMainLoop();
return 0;
}
I'm reading the sample code for the bezier curve on the online version of opengl's tutorial.
I'm curious about how is resize being handled in the example cause I figure I might use it on my own version of this program , I placed my questions on its comments:
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei) w, (GLsizei) h); // what's GLsizei? Why is it called inside glViewPort?
glMatrixMode(GL_PROJECTION); // is it necessary to reset the projection matrix?
glLoadIdentity();
if (w <= h) // is this calculation universal, could I use it on another program?
glOrtho(-5.0, 5.0, -5.0*(GLfloat)h/(GLfloat)w,
5.0*(GLfloat)h/(GLfloat)w, -5.0, 5.0);
else
glOrtho(-5.0*(GLfloat)w/(GLfloat)h,
5.0*(GLfloat)w/(GLfloat)h, -5.0, 5.0, -5.0, 5.0);
glMatrixMode(GL_MODELVIEW); // why do I set to GL_MODELVIEW at the end?
glLoadIdentity(); // why does it get a reset?
}
Full code:
#include <stdlib.h>
#include <GL/glut.h>
GLfloat ctrlpoints[4][3] = {
{ -4.0, -4.0, 0.0}, { -2.0, 4.0, 0.0},
{2.0, -4.0, 0.0}, {4.0, 4.0, 0.0}};
void init(void)
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_FLAT);
glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, &ctrlpoints[0][0]);
glEnable(GL_MAP1_VERTEX_3);
}
void display(void)
{
int i;
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 1.0, 1.0);
glBegin(GL_LINE_STRIP);
for (i = 0; i <= 30; i++)
glEvalCoord1f((GLfloat) i/30.0);
glEnd();
/* The following code displays the control points as dots. */
glPointSize(5.0);
glColor3f(1.0, 1.0, 0.0);
glBegin(GL_POINTS);
for (i = 0; i < 4; i++)
glVertex3fv(&ctrlpoints[i][0]);
glEnd();
glFlush();
}
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei) w, (GLsizei) h); // what's GLsizei? Why is it called inside glViewPort?
glMatrixMode(GL_PROJECTION); // is it necessary to reset the projection matrix?
glLoadIdentity();
if (w <= h) // is this calculation universal, could I use it on another program?
glOrtho(-5.0, 5.0, -5.0*(GLfloat)h/(GLfloat)w,
5.0*(GLfloat)h/(GLfloat)w, -5.0, 5.0);
else
glOrtho(-5.0*(GLfloat)w/(GLfloat)h,
5.0*(GLfloat)w/(GLfloat)h, -5.0, 5.0, -5.0, 5.0);
glMatrixMode(GL_MODELVIEW); // why do I set to GL_MODELVIEW at the end?
glLoadIdentity(); // why does it get a reset?
}
void keyboard(unsigned char key, int x, int y)
{
switch (key) {
case 27:
exit(0);
break;
}
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize (500, 500);
glutInitWindowPosition (100, 100);
glutCreateWindow (argv[0]);
init ();
glutDisplayFunc(display);
glutReshapeFunc(reshape); // el reshape funciona correctamente
glutKeyboardFunc (keyboard);
glutMainLoop();
return 0;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
GLsizei
是一个类型,而不是一个函数。因此,它没有被调用;它正在被铸造;它将int
转换为GLsizei
。它基本上是一个int
,但它清楚地表明您正在使用它的大小(我认为)。 (我是一名 Python 程序员,所以这是一个猜测)这不会重置矩阵,除非后面跟着
glLoadIdentity()
调用。相反,它将 OpenGL 矩阵运算的当前目标设置为指定的矩阵。这样,OpenGL 就知道您想要影响哪个矩阵。我之前在 OpenGL superible 中见过这种计算(或者至少是类似的东西);你为什么不和自己谈谈,看看它会做出什么决定以及为什么? (提示(我认为):它试图保持视口正方形以避免拉伸)
最后,它将其设置回 GL_MODELVIEW 因为该矩阵处理变换,例如平移和旋转,用于在屏幕上定位顶点。应该在每一帧重置它,以便您的代码可以假设坐标平面当前位于 (0,0);这简化了关于翻译到哪里的计算。
另请注意,
reshape
不是由 OpenGL 调用,而是由 GLUT 调用。 OpenGL 与平台无关,不处理窗口;这就是为什么你需要 GLUT。如果您是 OpenGL 新手,您应该从头开始学习 - 后面的教程将假定您具备此类知识。
GLsizei
is a type, not a function. Therefore, it's not being called; its being casted; it's converting anint
into aGLsizei
. It's basically anint
, but it makes it clear that you're using it for a size (I think). (I'm a Python programmer, so this is a guess)This does not reset the matrix, unless it is followed by a
glLoadIdentity()
call. Instead, it sets the current target of OpenGL's matrix operations to the matrix specified. This way, OpenGL knows what matrix you're trying to affect.I've seen that calcuation before in the OpenGL superbible (or at least something like it); why don't you talk yourself through it and see what it's deciding and why? (Hint (I think): it's trying to keep the viewport square to avoid stretching)
At the end, it sets it back to GL_MODELVIEW since that matrix handles transformations, like translation and rotation, which are used to position vertices onscreen. It should be reset every frame so that your code can assume that the coordinate plane is currently at (0,0); that simplifies calculations about where to translate to.
Also note that
reshape
is not called by OpenGL, but by GLUT. OpenGL is platform-independent and does not handle windowing; this is why you need GLUT.If you're new to OpenGL, you should work through it from the beginning - later tutorials will assume this sort of knowledge.