gpt4 book ai didi

c++ - 如何在 openGL 中正确显示球体

转载 作者:行者123 更新时间:2023-11-28 06:56:35 26 4
gpt4 key购买 nike

我对 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 处看着原点,但很难准确把握我在看什么)另外,偶尔当我运行它时,整个屏幕都是黑色的。然后,当我清理并构建并再次运行时,一切都很好。这不是一个大问题,但很烦人,我很想了解发生了什么。另外,当切片和堆叠的数量较少时,如果半径大它看起来很好,但是当半径小时它变得非常扭曲,我认为这很奇怪......

最佳答案

您在这里遇到的主要问题是 Z 裁剪。场景的初始 Z 范围是 (-1, 1),因此您只能看到实际球体的一部分,通过改变其大小,您会超出 Z 范围。

Image

我在代码中看到了几个问题。了解 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);

现在您将 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;
}

关于c++ - 如何在 openGL 中正确显示球体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23092055/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com