问题:
很多应用要在MFC下使用OpenGL,碰到较大的显示工作就需要使用OpenGL的显示列表,最近在使用中发现了一个问题:
GLuint InitDispalyList() { GLUquadricObj * l_poQObj; unsigned int l_uiNumOfOject = 30; GLuint l_gluiListIndex = glGenLists(l_uiNumOfOject); GLenum l_glenError = glGetError(); if (GL_NO_ERROR != l_glenError) { TRACE("An OpenGL error has occured: %s\n",gluErrorString(l_glenError)); return 0; } l_poQObj = gluNewQuadric(); gluQuadricDrawStyle(l_poQObj, (GLenum) GLU_FILL); gluQuadricNormals(l_poQObj, (GLenum) GLU_SMOOTH); for(unsigned int i=0;i<l_uiNumOfOject;i++) { glNewList(l_gluiListIndex + i, GL_COMPILE); gluSphere(l_poQObj, 20, 20, 20); glEndList(); } return l_gluiListIndex; }
这段代码用来申请30个显示列表,但是当直接调用时,总是会出现glGenLists返回0的问题,错误输出为GL_INVALID_OPERATION,官方资料的解释为glGenLists was called between a call to glBegin and the corresponding call to glEnd.。所以就开始各种查找glBegin,但是发现都成对匹配。
解决:
经过各种问题的查找与尝试,发现当上式函数放到OnDraw里调用时则可以成功申请,所以联想到是否是渲染环境的问题,所以修改如下:
void GLView::OnInitDisplayList() { CClientDC l_oDC(this); wglMakeCurrent(l_oDC.m_hDC, m_hRC); InitDispalyList(); wglMakeCurrent(NULL, NULL); }
其中GLView为使用的OpenGL视图,通过调用wglMakeCurrent函数设定当前设备描述符的渲染环境,m_hRC为建立OpenGL渲染环境时的句柄。
虽然问题已经解决,但是由于对MFC设备描述符及其与OpenGL管线的联系并不是很了解,所以只是大概的理解其中的道理,此外也希望官方资料能够进一步完善,满屏幕都是glBegin的代码伤不起呀。。。