如何在openGL中正确显示球体
How to display a sphere correctly in openGL
我对openGL/glust了解不多,但我以前曾成功地将其用于2D中一些非常简单的事情。现在我想能够在三维中绘制球体。我正在尝试模拟粒子碰撞,所以在图形端我真正需要做的就是绘制球体。这是我失败的尝试
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;
}
希望我所有的问题都源于一个非常基本的错误。。。出于某种原因,这会创建一个椭圆形。而且,尽管椭圆很大(可能是屏幕的八分之一宽和高),但如果我把半径降低到.73,它就会消失,我猜是因为它太小了,看不见。我该如何制作它,使这个球体像你所期望的那样呈现圆形,这样我就可以看到给定体积中发生的一切,比如一个10x10x10的盒子,就像你站在一个四处飞行的粒子盒子旁边凝视它一样,或者一个合理的近似值。现在很难说我到底在看什么(我知道我站在1,1,1,看着原点,但很难准确把握我看到的是什么)此外,偶尔当我运行它时,整个屏幕都是黑色的。然后,当我清理、构建并再次运行时,一切都很好。这不是一个很大的问题,但很烦人,我很想了解发生了什么。此外,当切片和堆栈的数量较低时,如果半径较大,它看起来会很好,但当半径较小时,它会变得非常扭曲,我认为这很奇怪。。。
这里的主要问题是Z剪裁。场景的初始Z范围为(-1,1),因此您只能看到实际球体的一部分,通过更改其大小,您将超出Z范围。
图像
我在代码中看到了几个问题。掌握GLUT工作流程的实际工作方式是很好的。
让我们看看代码做错了什么。
Main
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);
现在,您将timerProc函数设置为在50毫秒内调用。
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;
}
- OpenGL Glut显示功能在Mojave上显示黑屏
- 我在 OpenGL 中显示图像时遇到问题
- 无法获取要在 OpenGL ES2 中显示的 RGB 纹理
- OpenGL程序不显示三角形
- OpenGL 不显示 2D 线
- 如何显示具有 opengl 纹理的灰度图像
- SDL + OpenGL ES 2.0 使用着色器显示纹理
- 如何使用 openGL 在屏幕上显示加载的纹理
- 在Opengl中绘制一条不显示C++的线
- 写入渲染缓冲区并使用单个渲染调用使用 OpenGL 显示
- OpenGL -- 多个 glDrawArrays() 调用仅显示第一个的结果
- OpenGL显示空白的白屏
- OpenGL符号突出显示visual studio Mac代码中的错误
- 未显示 OpenGL 三角形
- 仅显示 OpenGL 最近的顶点绘制
- 无法在 Qwidget 中显示 OpenGL
- 每次移动(速度)时刷新显示(openGL)
- 如何显示opengl的结果
- 在显示openGL后删除文本
- 更新窗口显示OpenGL/GLUT c++