c++ - OpenGL 使用 glNewList 和 glDrawElements

标签 c++ opengl

我的代码正在编译和工作,但我不确定它是否正常工作。问题是,在我的 init 函数中,我启用了顶点数组,然后定义了一个 glNewList,最后我禁用了顶点数组。

void init(){

    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glClearDepth(1.0);

    glEnableClientState(GL_VERTEX_ARRAY);
    glVertexPointer(3, GL_FLOAT, 0, vertices);

    doubleStar = glGenLists(1);
    glNewList(doubleStar, GL_COMPILE);
        glPushAttrib(GL_CURRENT_BIT);
        glPushMatrix();

        glColor3f(0, 0, 0.7);

        // outside
        glPushMatrix();
            glDrawElements(GL_TRIANGLE_STRIP, 8, GL_UNSIGNED_INT, indices);
            glDrawElements(GL_TRIANGLE_STRIP, 8, GL_UNSIGNED_INT, &indices[8]);
        glPopMatrix();

        // inside
        glPushMatrix();
            glRotatef(30, 0, 0, 1);
            glScalef(0.4, 0.4, 0.4);            
            glDrawElements(GL_TRIANGLE_STRIP, 8, GL_UNSIGNED_INT, indices);
            glDrawElements(GL_TRIANGLE_STRIP, 8, GL_UNSIGNED_INT, &indices[8]);
        glPopMatrix();

        glPopMatrix();
        glPopAttrib();
    glEndList();

    glDisableClientState(GL_VERTEX_ARRAY);

    glutDisplayFunc(display);

}

在我的显示函数中调用 glCallList:

void display(){

    glClear(GL_COLOR_BUFFER_BIT);
    glClear(GL_DEPTH_BUFFER_BIT);

    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();

    // top left
    glPushMatrix();
        glTranslatef(-0.5, 0.5, 0);
        glRotatef(15, 0, 0, 1);
        glScalef(0.5, 0.5, 0.5);
        glCallList(doubleStar);
    glPopMatrix();

    // top right
    glPushMatrix();
        glTranslatef(0.5, 0.5, 0);
        glRotatef(-15, 0, 0, 1);
        glScalef(0.5, 0.5, 0.5);
        glCallList(doubleStar);
    glPopMatrix();

    // bot left
    glPushMatrix();
        glTranslatef(-0.5, -0.5, 0);
        glRotatef(-15, 0, 0, 1);
        glScalef(0.5, 0.5, 0.5);
        glCallList(doubleStar);
    glPopMatrix();

    // bot right    
    glPushMatrix();
        glTranslatef(0.5, -0.5, 0);
        glRotatef(15, 0, 0, 1);
        glScalef(0.5, 0.5, 0.5);
        glCallList(doubleStar);
    glPopMatrix();

    glFlush();
    glutSwapBuffers();

}

执行显示时数组已经关闭!所以我不确定这在任何情况下都行得通。另一方面,我读到如果您使用 GL_COMPILE 标志调用 glNewList,编译时的状态将被保存。因此,可能是因为在编译时启用了顶点数组,然后在调用列表时将启用。
所以,问题是:这在任何情况下都行得通吗?这是一个好方法吗?

这里是完整的代码:

#include <GL/glut.h>
#include <cmath>

void init();
void diplay();

static const GLfloat rInt = 0.7;
static const GLfloat rExt = 1;

static const GLuint indices[] = 
{

    4, 1, 3, 0, 5, 2, 4, 1,
    10, 7, 9, 6, 11, 8, 10, 7

};

static const GLfloat vertices[] =
{
    0, rInt, 0,
    -cos(M_PI_2/3)*rInt, -sin(M_PI_2/3)*rInt, 0,
    cos(M_PI_2/3)*rInt, -sin(M_PI_2/3)*rInt, 0,

    0, rExt, 0,
    -cos(M_PI_2/3)*rExt, -sin(M_PI_2/3)*rExt, 0,
    cos(M_PI_2/3)*rExt, -sin(M_PI_2/3)*rExt, 0,

    // 6

    0, -rInt, 0,
    -cos(M_PI_2/3)*rInt, sin(M_PI_2/3)*rInt, 0,
    cos(M_PI_2/3)*rInt, sin(M_PI_2/3)*rInt, 0,

    0, -rExt, 0,
    -cos(M_PI_2/3)*rExt, sin(M_PI_2/3)*rExt, 0,
    cos(M_PI_2/3)*rExt, sin(M_PI_2/3)*rExt, 0

};

static GLuint doubleStar;

int main(int argc, char** argv){

    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
    glutInitWindowSize(600, 600);
    glutInitWindowPosition(64, 64);
    glutCreateWindow("Mosaico estrella");

    init();

    glutMainLoop();

    return 0;

}

void display(){

    glClear(GL_COLOR_BUFFER_BIT);
    glClear(GL_DEPTH_BUFFER_BIT);

    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();

    // top left
    glPushMatrix();
        glTranslatef(-0.5, 0.5, 0);
        glRotatef(15, 0, 0, 1);
        glScalef(0.5, 0.5, 0.5);
        glCallList(doubleStar);
    glPopMatrix();

    // top right
    glPushMatrix();
        glTranslatef(0.5, 0.5, 0);
        glRotatef(-15, 0, 0, 1);
        glScalef(0.5, 0.5, 0.5);
        glCallList(doubleStar);
    glPopMatrix();

    // bot left
    glPushMatrix();
        glTranslatef(-0.5, -0.5, 0);
        glRotatef(-15, 0, 0, 1);
        glScalef(0.5, 0.5, 0.5);
        glCallList(doubleStar);
    glPopMatrix();

    // bot right    
    glPushMatrix();
        glTranslatef(0.5, -0.5, 0);
        glRotatef(15, 0, 0, 1);
        glScalef(0.5, 0.5, 0.5);
        glCallList(doubleStar);
    glPopMatrix();

    glFlush();
    glutSwapBuffers();

}

void init(){

    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glClearDepth(1.0);

    glEnableClientState(GL_VERTEX_ARRAY);
    glVertexPointer(3, GL_FLOAT, 0, vertices);

    doubleStar = glGenLists(1);
    glNewList(doubleStar, GL_COMPILE);
        glPushAttrib(GL_CURRENT_BIT);
        glPushMatrix();

        glColor3f(0, 0, 0.7);

        // outside
        glPushMatrix();
            glDrawElements(GL_TRIANGLE_STRIP, 8, GL_UNSIGNED_INT, indices);
            glDrawElements(GL_TRIANGLE_STRIP, 8, GL_UNSIGNED_INT, &indices[8]);
        glPopMatrix();

        // inside
        glPushMatrix();
            glRotatef(30, 0, 0, 1);
            glScalef(0.4, 0.4, 0.4);            
            glDrawElements(GL_TRIANGLE_STRIP, 8, GL_UNSIGNED_INT, indices);
            glDrawElements(GL_TRIANGLE_STRIP, 8, GL_UNSIGNED_INT, &indices[8]);
        glPopMatrix();

        glPopMatrix();
        glPopAttrib();
    glEndList();

    glDisableClientState(GL_VERTEX_ARRAY);

    glutDisplayFunc(display);

}

最佳答案

So, the question is: would this work in any case?

没有。

Is it a good approach?

不!

Display Lists 只存储OpenGL 命令及其参数,不存储顶点数组的数据。事实上,如果您阅读过任何关于 OpenGL 显示列表的教程,它应该明确警告不要混合顶点数组和显示列表,因为这是不可能正确的。

事实上,您根本不应该使用显示列表。请忘记您对它们的了解并忽略它们。如果非要问为什么?因为:显示列表已被完全从现代 OpenGL 中删除。不要使用它们,它们已成为过去。他们最后一次有用的应用有时是在 15 年前左右。

关于c++ - OpenGL 使用 glNewList 和 glDrawElements,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26775268/

相关文章:

c++ - 使用智能指针变得聪明 : avoiding shared_ptr overuse

java - 使用 Lwjgl 的导出库

c++ - 相当于 DirectX 渲染状态的 OpenGL

c++ - 变量没有类类型,即使它已被定义

c++ - 获取 LPDIRECT3DVERTEXBUFFER9 上的顶点内容

c++ - 使用 C API 覆盖 Lua 中的赋值运算符

c++ - 从 C++ 到 OpenGL 的数据复制适用于自定义容器,但不适用于 std::tuple

c++ 什么内存压缩库?

c++ - Freeglut glew glutIdleFunc 导致滞后

c++ - 使用 OpenGL 3.3 和 Qt 5.6 创建相机