我不太了解openGL / glut,但我在成功之前已经使用它来处理2D中的一些非常简单的事情。 现在我希望能够在3D中绘制球体。我正在尝试模拟粒子碰撞,所以我真正需要在图形端做的就是绘制球体。 这是我的失败尝试
void renderScene()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
// Set the camera
gluLookAt(1.0f, 1.0f, 1.0f,
0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f);
glutSwapBuffers();
}
void timerProc(int arg)
{
glutTimerFunc(50,timerProc,0);
// Reset transformations
glLoadIdentity();
// Set the camera
gluLookAt(1.0f, 1.0f, 1.0f,
0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f);
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glColor3f(0.0,0.0,0.0); //color = black
glPushMatrix();
glTranslated(0,0,0);
glutSolidSphere(.74, 500, 500);
glPopMatrix();
glutSwapBuffers();
}
int main(int argc, char **argv)
{
srand(time(NULL));
init();
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(50,30);
glutInitWindowSize(glutGet(GLUT_SCREEN_WIDTH)-80,glutGet(GLUT_SCREEN_HEIGHT)-60);
mainWindow=glutCreateWindow("New Window"); //global variable
WIDTH=glutGet(GLUT_WINDOW_WIDTH); //global variable
HEIGHT=glutGet(GLUT_WINDOW_HEIGHT); //global variable
glutDisplayFunc(renderScene);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
glutTimerFunc(50,timerProc,0);
glutMainLoop();
return 0;
}
希望我的所有问题都源于一个非常基本的错误...... 出于某种原因,这会产生一个椭圆形。而且,虽然椭圆形相当大(可能大约是屏幕宽度和高度的1/8),但如果我将半径降低到0.73它会消失,我猜测它因为它太小而无法看到。 我怎么能这样做,这个球体会像你期望的那样显示圆形,所以我可以看到在给定体积中发生的所有事情,例如一个10x10x10的盒子,就像你站在旁边一样一盒飞来飞去并窥视它的粒子,或者是一个合理的近似值。现在很难说出我到底在看什么(我知道我站在1,1,1看着原点,但很难准确掌握我所看到的) 此外,偶尔当我运行它时,整个屏幕只是黑色。然后,当我清理并建立并再次运行时,它很好。这不是一个非常令人担忧的问题,但令人讨厌,我很想知道发生了什么。 此外,当切片和堆叠的数量较少时,如果半径很大,它看起来会很好,但是当半径很小时会变得非常扭曲,我觉得这很奇怪......
答案 0 :(得分:1)
你在这里遇到的主要问题是Z裁剪。场景的初始Z范围是(-1,1),因此您只能看到实际球体的一部分,并且通过改变其大小,您将超出z范围。
我在代码中看到了几个问题。 掌握GLUT工作流程的实际效果是很好的。
让我们看看代码做错了什么。
int main(int argc, char **argv)
{
srand(time(NULL));
init();
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(50, 30);
glutInitWindowSize(glutGet(GLUT_SCREEN_WIDTH) - 80,
glutGet(GLUT_SCREEN_HEIGHT) - 60);
mainWindow = glutCreateWindow("New Window"); //global variable
WIDTH = glutGet(GLUT_WINDOW_WIDTH); //global variable
HEIGHT = glutGet(GLUT_WINDOW_HEIGHT); //global variable
glutDisplayFunc(renderScene);
在此定义显示功能。每次窗口内容必须无效时调用它。在这种情况下,它仅在开始时无效。 renderScene函数没有做任何真棒,只是清除屏幕。所以你在开始时就会出现黑屏。
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
此刻无需混合。你可以完全跳过这一部分。
glutTimerFunc(50, timerProc, 0);
现在设置要在50毫秒内调用的timerProc函数。
glutMainLoop();
正如文档所述: glutMainLoop 进入GLUT事件处理循环。在GLUT程序中,该程序最多应调用一次。一旦被调用,该例程将永远不会返回。它将根据需要调用已注册的任何回调。
return 0;
}
void renderScene()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
这是您清除屏幕的唯一地方。 Timer Func不会这样做。
glLoadIdentity();
您正在重置矩阵。
// Set the camera
gluLookAt(1.0f, 1.0f, 1.0f,
0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f);
设置矩阵。 (准确地说是一个矩阵)
glutSwapBuffers();
没有绘制任何东西你交换缓冲区。
}
每次重绘窗口框架时都会调用场景渲染功能。
此功能确实依赖于renderScene首先清除的屏幕。 void timerProc(int arg) { glutTimerFunc(50,timerProc,0);
// Reset transformations
glLoadIdentity();
// Set the camera
gluLookAt(1.0f, 1.0f, 1.0f,
0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f);
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
不清除此时间。只设置颜色。
glColor3f(0.0, 0.0, 0.0); //color = black
glPushMatrix();
glTranslated(0, 0, 0);
glutSolidSphere(.74, 500, 500);
glPopMatrix();
glutSwapBuffers();
}
只需设置矩阵即可。适当的Z范围。
void resetTransformations() {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1, 1, -1, 1, -1000, 1000);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(1.0f, 1.0f, 1.0f,
0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f);
}
void renderScene()
{
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Reset transformations
resetTransformations();
// Just to see some triangles
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glColor3f(0.0, 0.0, 0.0); //color = black
glPushMatrix();
glTranslated(0, 0, 0);
glutSolidSphere(0.74, 500, 500);
glPopMatrix();
glutSwapBuffers();
}
int main(int argc, char **argv)
{
srand(time(NULL));
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(50, 30);
glutInitWindowSize(256, 256);
mainWindow = glutCreateWindow("New Window"); //global variable
WIDTH = glutGet(GLUT_WINDOW_WIDTH); //global variable
HEIGHT = glutGet(GLUT_WINDOW_HEIGHT); //global variable
glutDisplayFunc(renderScene);
glutIdleFunc(renderScene);
glutMainLoop();
return 0;
}