如何在OpenGL中将多个显示列表ID分配给GLU建模?

oyt4ldly  于 2022-11-04  发布在  其他
关注(0)|答案(1)|浏览(119)

我很好奇OpenGL如何分配多个显示列表ID。
目前我有:

void MyCreateList() {
    MyListID = glGenLists(1);  
    glNewList(MyListID, GL_COMPILE);  
        //gluSphere(qobj, 1.0, 20, 20);                  //Sphere
        //gluCylinder(qobj, 1.0, 0.0, 2.0, 20, 8);         //Cylinder
        gluDisk(qobj, 0.25, 1.0, 20, 3);                  //Disk
        //gluPartialDisk(qobj, 0.5, 1.0, 26, 13, 0, 180);  //PartialDisk
    glEndList();
}

=〉一个显示列表的ID。

void MyCreateList() {
    GLuint listOne, listTwo, listThree, listFour;
    listOne = glGenLists(4);
    listTwo = listOne + 1;
    listThree = listTwo + 1;
    listFour = listThree + 1;
    glNewList(listThree, GL_COMPILE);  
        gluSphere(qobj, 1.0, 20, 20);                   //Sphere 
        gluCylinder(qobj, 1.0, 0.0, 2.0, 20, 8);          //Cylinder
        gluDisk(qobj, 0.25, 1.0, 20, 3);                 //Disk
        gluPartialDisk(qobj, 0.5, 1.0, 26, 13, 0, 180);  //PartialDisk
    glEndList();
}

=〉多个显示列表的ID。
以下是所需的结果:

如果您使用“显示列表”仅分配一个ID,则不会出现问题,但如果您分配多个ID,则无法正常工作。
有什么想法吗?

gopyfrb3

gopyfrb31#

显示列表将一系列OpenGL命令和数据分组,以便在初始创建后可以重复执行,从而提高程序的性能(有关显示列表的详细信息以及各种代码示例,请参阅here)。
请注意,显示列表在OpenGL 3.0中已被弃用,在OpenGL 3.1中已被删除,此处已对此进行了讨论:Why were display lists deprecated in opengl 3.1?
第二个代码片段中的四个glu*()调用创建了图元,这些图元仅存储在生成的四个显示列表中的一个列表中,即listThree中。在该显示列表中,球体、圆柱体、圆盘和部分圆盘被放置在相同的位置,因此将重叠。此外,四个显示列表ID变量listOne, listTwo, listThree, listFour对于函数MyCreateList()的作用域是局部的,因此在函数调用之后它们将不可访问。
如果程序应该从发布的screenshot生成结果,那么只需要一个shape(用gluDisk()生成)和一个显示列表。(为什么要为该任务使用多个显示列表?)
如果这是一个教育性的练习,我认为它是关于将转换放入一个显示列表中,以生成显示的倾斜的scape,例如下面这样(磁盘用glScalef()拉伸,用glRotatef()旋转):

/* $ gcc -Wall -pedantic skewed.c -o skewed -lGL -lGLU -lglut && ./skewed */

# include <GL/glut.h>

static GLuint _displayList = 0;

static void _create_display_list(void)
{
    GLUquadricObj *qobj = NULL;
    _displayList = glGenLists(1);

    qobj = gluNewQuadric();
    glNewList(_displayList, GL_COMPILE);
        glPushMatrix();

        glRotatef(30.0f, 0.0f, 0.0f, 1.0f);
        glScalef(0.8f, 1.0f, 0.8f);
        glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
        gluDisk(qobj, 0.25, 1.0, 20, 3);

        glPopMatrix();
    glEndList();
    gluDeleteQuadric(qobj);
    qobj = NULL;
}

static void _reshape(GLint w, GLint h)
{
    glViewport(0, 0, w, h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(-1.0f, 1.0f, -1.0f, 1.0f);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

static void _display(void)
{
    glClear(GL_COLOR_BUFFER_BIT);
    glCallList(_displayList);
    glFlush();
}

int main(int argc, char**argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutCreateWindow("test");
    glutDisplayFunc(_display);
    glutReshapeFunc(_reshape);

    _create_display_list();
    glutMainLoop();
    return 0;
}

这里是一个修改后的示例,它说明了多个显示列表的使用:

/* $ gcc -Wall -pedantic test_gl.c -o test_gl -lGL -lGLU -lglut && ./test_gl */

# include <GL/glut.h>

static GLuint _displayList = 0;

static void _create_display_lists(void)
{
    GLUquadricObj *qobj = NULL;
    _displayList = glGenLists(4);

    /* shapes (white) */
    qobj = gluNewQuadric();
    glNewList(_displayList + 2, GL_COMPILE);
        glPushMatrix();

        glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
        glTranslatef(-2.0f, -2.0f, 0.0f);

        gluSphere(qobj, 1.0, 20, 20);

        glTranslatef(4.0f, 0.0f, 0.0f);
        gluCylinder(qobj, 1.0, 0.0, 2.0, 20, 8);

        glTranslatef(0.0f, 4.0f, 0.0f);
        gluDisk(qobj, 0.25, 1.0, 20, 3);

        glTranslatef(-4.0f, 0.0f, 0.0f);
        gluPartialDisk(qobj, 0.5, 1.0, 26, 13, 0, 180);

        glPopMatrix();
    glEndList();
    gluDeleteQuadric(qobj);
    qobj = NULL;

    /* diagonal line (cyan) */
    glNewList(_displayList, GL_COMPILE);
        glBegin(GL_LINES);
        glColor4f(1.0f, 1.0f, 0.0f, 1.0f);
        glVertex4f(-3.0f, 3.0f, 0.0f, 1.0f);
        glVertex4f(3.0f, 3.0f, 0.0f, 1.0f);
        glEnd();
    glEndList();

    /* horizontal line (yellow) */
    glNewList(_displayList + 1, GL_COMPILE);
        glBegin(GL_LINES);
        glColor4f(0.0f, 1.0f, 1.0f, 1.0f);
        glVertex4f(-3.0f, -3.0f, 0.0f, 1.0f);
        glVertex4f(3.0f, 3.0f, 0.0f, 1.0f);
        glEnd();
    glEndList();

    /* diagonal line (magenta) */
    glNewList(_displayList + 3, GL_COMPILE);
        glBegin(GL_LINES);
        glColor4f(1.0f, 0.0f, 1.0f, 1.0f);
        glVertex4f(-3.0f, 3.0f, 0.0f, 1.0f);
        glVertex4f(3.0f, -3.0f, 0.0f, 1.0f);
        glEnd();
    glEndList();
}

static void _reshape(GLint w, GLint h)
{
    glViewport(0, 0, w, h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(-4.0f, 4.0f, -4.0f, 4.0f);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

static void _display(void)
{
    glClear(GL_COLOR_BUFFER_BIT);
    glCallList(_displayList);
    glCallList(_displayList + 1);
    glCallList(_displayList + 2);
    glCallList(_displayList + 3);
    glFlush();
}

int main(int argc, char**argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutCreateWindow("test");
    glutDisplayFunc(_display);
    glutReshapeFunc(_reshape);

    glLineWidth(5.0f);
    glDisable(GL_DEPTH_TEST);
    _create_display_lists();

    glutMainLoop();
    return 0;
}

所有使用的GL/GLU函数的文档可在以下位置找到:
https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/
所有使用的GLUT函数的文档都可以在以下位置找到:
https://www.opengl.org/resources/libraries/glut/spec3/spec3.html
有关“传统OpenGL”主题的更多信息,请访问here

相关问题