显示素材问题(opengl)



我在运行一个简单的程序时遇到了一些问题:(文本下方的代码)

我想打印一个坐标为[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;
}

您的init函数有点奇怪

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);

glOrtho之前立即调用glLoadIdentity是一种浪费。glOrtho覆盖当前矩阵,所以它以前是什么并不重要。此外,glLoadIdentity将矩阵值重置回单位矩阵的默认值,这是程序启动时的情况,因此它是双重冗余的。

此外,glOrtho参数是"左下右上近远"。通过为左侧和底部输入比右侧和顶部大的数字,可以反转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(),而不是在按键函数中。

int main(int argc, char *argv[])
{
...
glutIdleFunc(display);
...
}

不要将空闲功能设置为显示功能。如果你想让你的程序动画化,制作一个实际的空闲函数,调用glutPostRedisplay

最新更新