我在运行一个简单的程序时遇到了一些麻烦:(代码低于文本)
我想打印一个带有[50,50],[ - 50,-50],[50,-50],[ - 50,50]坐标的正方形。
我在init()中设置glOrtho矩阵,然后在我的显示功能中打印带有上述坐标的正方形作为glVertex2f(例如glVertex2f(50.0,-50.0))它是正确的方法还是glVertex2f不把真实坐标作为值?
无论如何这里是代码:(编译得很好,但它在图形窗口中没有显示任何内容)
#include <iostream>
#include <stdlib.h>
#ifdef __APPLE__
#include <GLUT/glut.h>
#else
#include <windows.h>
#include <GL/glut.h>
#endif
#define SCR_WID 640
#define SCR_HEI 480
#include "imageloader.h"
using namespace std;
//*****************************CUSTOM FUNCS***********************************//
void init()
{
glViewport(0,0,SCR_WID,SCR_HEI);
glPushMatrix();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho((double)SCR_WID,0.0,(double)SCR_HEI,0.0,-5.0,-20.0);
glMatrixMode(GL_MODELVIEW);
}
//*****************************CALLBACKS (win 1)******************************//
void resizeFunc(int w, int h)
{
glutReshapeWindow(SCR_WID,SCR_HEI);
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0,1.0,1.0);
glBegin(GL_QUADS);
glVertex2f(1.0,1.0);
glVertex2f(-1.0,1.0);
glVertex2f(1.0,-1.0);
glVertex2f(-1.0,-1.0);
glEnd();
glutSwapBuffers();
}
void key(unsigned char key, int x, int y)
{
if (key == 'q' || key == 27 )
exit(0);
glutPostRedisplay();
}
//**********************************main func*********************************//
int main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitWindowSize(SCR_WID,SCR_HEI);
glutInitWindowPosition(10,10);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutCreateWindow("TestGlut");
glutReshapeFunc(resizeFunc);
glutDisplayFunc(display);
glutIdleFunc(display);
glutKeyboardFunc(key);
init();
glutMainLoop();
return EXIT_SUCCESS;
}
答案 0 :(得分:0)
你的初始化函数有点奇怪
glViewport(0,0,SCR_WID,SCR_HEI);
默认视口已经是完整窗口,因此这是多余的。
glPushMatrix();
你永远不会在其他地方以任何其他方式调用glPopMatrix
或操纵矩阵堆栈,那你为什么要这样做呢?
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho((double)SCR_WID,0.0,(double)SCR_HEI,0.0,-5.0,-20.0);
在glLoadIdentity
之前立即拨打glOrtho
是一种浪费。 glOrtho
会覆盖当前的矩阵,因此之前无关紧要。同样glLoadIdentity
将矩阵值重置为它的默认身份矩阵,这在程序启动时也是如此,所以它是多余的。
此外,glOrtho params是“靠近远处的右下方顶部”。您通过在左侧和底部放置一个比右侧和顶部更大的数字来反转X轴和Y轴。最好这将为您提供一个投影,将(0,0)坐标放在屏幕的右下方,这是非常不寻常的。最后,您的近处和远处平面完全位于负Z空间中。这意味着将始终排除仅使用两个值(glVertex2f
正在使用时)指定的顶点,因为它们的z坐标隐含为0。
void resizeFunc(int w, int h)
{
glutReshapeWindow(SCR_WID,SCR_HEI);
}
如果您要忽略输入的宽度和高度,为什么还要使用调整大小功能呢?
glBegin(GL_QUADS);
glVertex2f(1.0,1.0);
glVertex2f(-1.0,1.0);
glVertex2f(1.0,-1.0);
glVertex2f(-1.0,-1.0);
glEnd();
除了这些坐标将产生剪切顶点(因为它们的Z值隐式为0,因此位于近/远剪辑区域之外)这一事实之外,您将在规范化剪辑坐标中指定它们。如果你纠正了genpfault提到的Z形问题(通过交换顶点3和4),那么这些将占用整个屏幕如果你正在使用默认的投影矩阵。通过使用屏幕像素尺寸设置正交矩阵,您创建了一个宽2像素,高2像素的正方形,位于屏幕的右下角。
void key(unsigned char key, int x, int y)
{
...
glutPostRedisplay();
}
为什么呢?如果你想让你的程序连续渲染,而不仅仅是当某人遇到一个键时,那么你应该在一个空闲函数中使用glutPostRedisplay(),而不是在keypress函数中。
int main(int argc, char *argv[])
{
...
glutIdleFunc(display);
...
}
不要将空闲功能设置为显示功能。如果您希望程序设置动画,请创建一个调用glutPostRedisplay
的实际空闲函数。