如何将多个显示列表 ID 分配给 OpenGL 中的 GLU 建模?
How do I assign Multiple Display List IDs to GLU Modeling in OpenGL?
我很好奇 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,将无法正常工作。
有什么想法吗?
显示列表将一系列 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 生成结果,则只需要一个形状(用 gluDisk()
生成)和一个显示列表。 (为什么要为该任务使用多个显示列表?)
如果这是一个教育练习,我认为它是关于将变换放入显示列表,以生成显示的倾斜景观,例如像这样(磁盘用 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。
我很好奇 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,将无法正常工作。
有什么想法吗?
显示列表将一系列 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 生成结果,则只需要一个形状(用 gluDisk()
生成)和一个显示列表。 (为什么要为该任务使用多个显示列表?)
如果这是一个教育练习,我认为它是关于将变换放入显示列表,以生成显示的倾斜景观,例如像这样(磁盘用 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。