用于绘制的 MFC 和 OpenGL 事件

MFC and OpenGL events for drawing

本文关键字:OpenGL 事件 MFC 绘制 用于      更新时间:2023-10-16

我构建了一个SDI MFC应用程序,其中CView子级正在用OpenGL绘制一个立方体。此立方体由以下函数绘制:

void CglSDI3View::setupScene()
{
wglMakeCurrent(m_hDC, m_hRC);
// Clear color and depth buffer bits
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Wireframe Mode
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glBegin(GL_QUADS);
// Front Side
glVertex3f(1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
// Back Side
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f(1.0f, 1.0f, -1.0f);
glVertex3f(1.0f, -1.0f, -1.0f);
// Top Side
(...)
glEnd();
SwapBuffers(m_hDC);

}

我没有定义计时器。现在,我的OnDraw函数如下:

void CglSDI3View::OnDraw(CDC* /*pDC*/)
{
CglSDI3Doc* pDoc = GetDocument();
wglMakeCurrent(m_hDC, m_hRC);
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -m_fZoom);
glTranslatef(m_fPosX, m_fPosY, 0.0f);
glRotatef(m_fRotX, 1.0f, 0.0f, 0.0f);
glRotatef(m_fRotY, 0.0f, 1.0f, 0.0f);
setupScene();
wglMakeCurrent(NULL, NULL);
ValidateRect(NULL);
}

其中m_fRotXm_fRotYm_fPosX等是缩放和平移因子。我的问题是:我是否需要在每次OnDraw()呼叫时都拨打setupScene()?或者这可以优化吗?换句话说,是否必须在每次OnDraw()调用时重绘立方体,或者有没有办法只执行此操作一次,然后仅应用转换?

请注意,未来setupScene()函数会绘制出带有数百万个彩色点的巨大点云,因此需要尽可能进行优化。

"setupScene"这个名字具有误导性。OpenGL没有场景。OpenGL没有模型。OpenGL不是一个场景图。

OpenGL是一个"愚蠢"的绘图API。它一次绘制一个点、线和三角形。画了一些东西之后,它已经忘记了它。

所以,是的,如果你想在图纸中进行一些更改,你必须重新绘制,因为,嗯,这只是一个绘图,仅此而已。OpenGL没有可以操纵的保留场景。

因此,将"setupScene"重命名为"drawScene",并按照其恰当的名称使用它。