OpenGL 显示一个正方形而不是一个立方体

Posted

技术标签:

【中文标题】OpenGL 显示一个正方形而不是一个立方体【英文标题】:OpenGL displaying a square instead of a cube 【发布时间】:2020-07-05 13:21:29 【问题描述】:

我开始在 OpenGL 中使用 tinker,我想绘制一个立方体。我去看了一个教程,跟着那个教程,只得到了这个奇怪的正方形。

这是我的代码。

#include <GLFW/glfw3.h>
void drawCube() 
    float rotate_x 193 ;
    float rotate_y 112 ;
    glBegin(GL_POLYGON);

    glColor3f(1.0, 0.0, 0.0);     glVertex3f(0.5, -0.5, -0.5);      
    glColor3f(0.0, 1.0, 0.0);     glVertex3f(0.5, 0.5, -0.5);      
    glColor3f(0.0, 0.0, 1.0);     glVertex3f(-0.5, 0.5, -0.5);     
    glColor3f(1.0, 0.0, 1.0);     glVertex3f(-0.5, -0.5, -0.5);      

    glColor3f(1.0, 1.0, 1.0);
    glVertex3f(0.5, -0.5, 0.5);
    glVertex3f(0.5, 0.5, 0.5);
    glVertex3f(-0.5, 0.5, 0.5);
    glVertex3f(-0.5, -0.5, 0.5);

    glColor3f(1.0, 0.0, 1.0);
    glVertex3f(0.5, -0.5, -0.5);
    glVertex3f(0.5, 0.5, -0.5);
    glVertex3f(0.5, 0.5, 0.5);
    glVertex3f(0.5, -0.5, 0.5);

    glColor3f(0.0, 1.0, 0.0);
    glVertex3f(-0.5, -0.5, 0.5);
    glVertex3f(-0.5, 0.5, 0.5);
    glVertex3f(-0.5, 0.5, -0.5);
    glVertex3f(-0.5, -0.5, -0.5);
    
    glColor3f(0.0, 0.0, 1.0);
    glVertex3f(0.5, 0.5, 0.5);
    glVertex3f(0.5, 0.5, -0.5);
    glVertex3f(-0.5, 0.5, -0.5);
    glVertex3f(-0.5, 0.5, 0.5);
    
    glColor3f(1.0, 0.0, 0.0);
    glVertex3f(0.5, -0.5, -0.5);
    glVertex3f(0.5, -0.5, 0.5);
    glVertex3f(-0.5, -0.5, 0.5);
    glVertex3f(-0.5, -0.5, -0.5);

    glLoadIdentity();
    glRotatef(30, 0.0, 1.0, 0.0);

    glEnd();


int main(void)

    GLFWwindow* window;

    /* Initialize the library */
    if (!glfwInit())
        return -1;

    /* Create a windowed mode window and its OpenGL context */
    window = glfwCreateWindow(640, 480, "Triangle", NULL, NULL);
    if (!window)
    
        glfwTerminate();
        return -1;
    

    /* Make the window's context current */
    glfwMakeContextCurrent(window);

    /* Loop until the user closes the window */
    while (!glfwWindowShouldClose(window))
    
        /* Render here */
        glClear(GL_COLOR_BUFFER_BIT);

        drawCube();
        /* Swap front and back buffers */
        glfwSwapBuffers(window);

        /* Poll for and process events */
        glfwPollEvents();
    

    glfwTerminate();
    return 0;

我正在使用 GLFW 来执行此操作,并且我正在 Visual Studio 2017 社区版中构建它。 我还尝试在 drawCube() 的末尾旋转它。 我遵循的教程是 https://www.wikihow.com/Make-a-Cube-in-OpenGL,但我对其进行了一些调整以使用 glfw。

【问题讨论】:

【参考方案1】:

您正在绘制一个具有 24 个顶点的多边形。由于 OpenGL 要求多边形是凹面和平面的(您的数据不是),它会绘制一些随机的东西。

如果你想绘制一个立方体,你要么必须分别为每个面分割绘图调用glBegin(GL_POLYGON)glEnd()(如教程在第 4 节的第二个代码示例中所示),或者你可以更改原始模式为GL_QUADS

请注意,您使用的 OpenGL 版本(固定功能管道)已经过时了 10 多年。您可能需要考虑切换到(至少)OpenGL 3.3 核心配置文件并使用着色器。

【讨论】:

不,这不起作用。它只是以法国国旗的形状显示 3 种颜色 你到底做了什么改变,结果现在看起来如何?另请注意,您不能在glBeginglEnd 之间调用glRotatef。这会给你一个GL_INVALID_OPERATION 错误。【参考方案2】:

    相机

    我没有看到您在任何地方设置矩阵...所以我敢打赌,无论您如何调整渲染的轴对齐数据,您的矩阵都是导致二维视图的单位。

    gluPerspective 用于GL_PROJECTION。为新手正确设置透视 3D 视图有点棘手(因为它在 -Z 方向查看,这与单位矩阵完全相反)所以你的网格在可视区域中。

    CULL_FACE

    对于初学者,请尝试glDisable(GL_CULL_FACE),因为您的数据很可能包含缠绕错误,并且您将不知道您已经拥有或不知道哪些面孔。

    立方体网格

    现在您正在使用glVertex 对其进行硬编码,调用它更容易为点和面(四边形或三角形)使用单独的数组。此外,正如 BDL 指出的那样,您在 glBegin/glEnd 调用中使用了禁止的命令,它们被忽略并由于错误处理而减慢速度。

    照明

    为了更好地感受 3D,您还应该为每个面添加法线并启用灯光。否则你需要用不同的颜色给每张脸上色才能看到“3D”。

看看我的:

complete GL+GLSL+VAO/VBO C++ example

只需忽略高级内容(GLSL、VAO/VBO...)并查找视图设置和立方体网格数据。您只需要使用 for 循环而不是 VAO/VBO 来渲染它。这里的例子:

glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_COLOR_MATERIAL);
#ifndef vao_indices
glBegin(GL_QUADS);
for (int i=0;i<6*4*3;i+=3)
    
    glNormal3fv(vao_nor+i);
    glColor3fv (vao_col+i);
    glVertex3fv(vao_pos+i);
    
glEnd();
#else
int i,j,k;
const GLfloat vao_nor[]=
    
//   nx   ny   nz
     0.0, 0.0,-1.0,
     0.0, 0.0,+1.0,
     0.0,-1.0, 0.0,
    +1.0, 0.0, 0.0,
     0.0,+1.0, 0.0,
    -1.0, 0.0, 0.0,
    ;
glBegin(GL_QUADS);
for (j=0;j<6*4;j++)
    
    i=vao_ix[j]; i+=i+i;
    k=j>>2; k+=k+k;
    glNormal3fv(vao_nor+k);
    glColor3fv (vao_col+i);
    glVertex3fv(vao_pos+i);
    
glEnd();
#endif
glDisable(GL_COLOR_MATERIAL);
glDisable(GL_LIGHTING);
glDisable(GL_LIGHT0);

在链接的 QA 中以两种模式(索引和直接)使用来自 gl_simple 的网格。

【讨论】:

以上是关于OpenGL 显示一个正方形而不是一个立方体的主要内容,如果未能解决你的问题,请参考以下文章

Modern OpenGL - 渲染矩体/矩形体/立方体/正方体/长方体

在QT环境下用OpenGL绘制一个边长为5的立方体,并为立方体贴上自定义纹理。写出实现该功能的具体

引擎测试:在屏幕上渲染立方体 (OpenGL)

[计算机图形学 with OpenGL] Chapter10 OpenGL三维观察程序示例

OpenGL围绕自身而不是原点(0,0,0)旋转对象(一组立方体)

如何在 OpenGL 中更改视角?