点击打开链接
补充:基本框架添加成员变量初始化代码
COpenglbaseView::COpenglbaseView() { // TODO: add construction code here m_hRC=NULL; m_pDC=NULL; }
否则不能显示三维图元。因为这里我们没有用到纹理,所以把初始化中的启用纹理映射函数注释掉
BOOL COpenglbaseView::InitializeOpenGL(CDC *pDC) { m_pDC=pDC; if(!SetupPixelFormat()) return FALSE; m_hRC=::wglCreateContext(m_pDC->GetSafeHdc());//产生一个新的opengl绘图描述表使之适合在参数hdc给出的设备上画图 ::wglMakeCurrent(m_pDC->GetSafeHdc(),m_hRC); // SetLight();//设置光照环境 // LoadGLTextures();//设置绘图环境 // glEnable(GL_TEXTURE_2D);//启用纹理映射 return TRUE; }
----------------------------------------------------------------------------------
在②中只是讲了怎样制作二维图形,其默认为正视投影
将OnSize函数
void COpenglbaseView::OnSize(UINT nType, int cx, int cy) { CView::OnSize(nType, cx, cy); // TODO: Add your message handler code here //添加窗口缩放时的图形变换函数 glViewport(0,0,cx,cy); }
void COpenglbaseView::OnSize(UINT nType, int cx, int cy) { CView::OnSize(nType, cx, cy); // TODO: Add your message handler code here //添加窗口缩放时的图形变换函数 //添加窗口缩放时的变换函数 GLsizei width, height; GLdouble aspect; width = cx; height = cy; if (cy==0) aspect = (GLdouble)width; else aspect = (GLdouble)width/(GLdouble)height; glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0.0, 500.0*aspect, 0.0, 500.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); }
OnSize中的glMatrixMode是用来设置矩阵模式的,它有三个选项:GL_MODELVIEW、GL_PROJECTION、GL_TEXTURE。
GL_MODELVIEW表示从实体坐标系转到人眼坐标系。
GL_PROJECTION表示从人眼坐标系转到剪裁坐标系。
GL_TEXTURE表示从定义纹理的坐标系到粘贴纹理的坐标系的变换。
glLoadIdentity初始化工程矩阵(project matrix);
gluOrtho2D把工程矩阵设置成显示一个二维直角显示区域。
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
生成三维图形
三维和二维的坐标系统不同,三维的图形比二维的图形多一个z坐标。我们在生成简单的二维图形时,用的是gluOrtho2D;我们在生成三维图形时,需要两个远近裁剪平面,以生成透视效果。实际上,二维图形只是视线的近裁剪平面z= -1,远裁剪平面z=1;这样z坐标始终当作0,两者没有本质的差别。
在上述基础之上,我们只做简单的变化,就可以生成三维物体。
gluPerspective(45, aspect, 0.1f, 100.0f);
这样就实现了三维透视坐标系的设置。该语句说明了视点在原点,透视角是45度,近裁剪面在z=0.1处,远裁剪面在z=100.0f处。在离相机0.1-100单位距离内的物体是可以成像的。这里的近远裁剪面的距离都是相对相机的距离,所以都是正值。
透视投影为例,
gluLookAt(0,0,-1,0,0,0,0,1,0); RenderScene();//渲染场景
void COpenglbaseView::OnDraw(CDC* pDC) { COpenglbaseDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here static BOOL bBusy = FALSE; if (bBusy) { return; } bBusy=TRUE; //双缓存应用 ////////////////////////////////////////////////////////////////////////// gluLookAt(0,0,-1,0,0,0,0,1,0); RenderScene();//渲染场景 ////////////////////////////////////////////////////////////////////////// glFlush(); glFinish();//完成绘制 SwapBuffers(m_pDC->GetSafeHdc());//双缓存应用 bBusy=FALSE; }
BOOL COpenglbaseView::RenderScene() { glClearColor(0.0f,0.0f,0.0f,0.0f); glClearDepth(1.0f); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); ////////////////////////////////////////////////////////////////////////// //三维测试 glBegin(GL_POLYGON); glColor3f(0.0f,1.0f,0.0f); glVertex3f(-2.0f, -2.0f, 5.0f); glVertex3f( 2.0f, -2.0f, 5.0f); glVertex3f( 2.0f, 2.0f,5.0f); glVertex3f(-2.0f, 2.0f,5.0f); glEnd();
////////////////////////////////////////////////////////////////////////// return TRUE; }
显示结果如下,在正中央有一正方形
但是有一个问题是正方形不停地闪烁,这是因为我们框架里有一个Timer定时器定时刷新,为了消除闪烁
Delete删除OnTimer函数
在View的OnCreate函数中注释掉
// SetTimer(1,20,NULL);
在OnDestroy中注释掉
// KillTimer(1);
----------------------------------------------------------------------------------------------------------------------------------
验证gluLookAt函数
将人眼位置向x轴正方向即右移动100个单位,视线方向不变,此时屏幕内显示为黑屏,将图元的x坐标加100,又如上图所示。
可见,gluLookAt只是改变人眼(摄像机)的位置,绘制图元时还是以世界坐标系为参考系。
void COpenglbaseView::OnDraw(CDC* pDC) { COpenglbaseDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here static BOOL bBusy = FALSE; if (bBusy) { return; } bBusy=TRUE; //双缓存应用 ////////////////////////////////////////////////////////////////////////// gluLookAt(100,0,-1,100,0,0,0,1,0); RenderScene();//渲染场景 ////////////////////////////////////////////////////////////////////////// glFlush(); glFinish();//完成绘制 SwapBuffers(wglGetCurrentDC());//双缓存应用 bBusy=FALSE; }
BOOL COpenglbaseView::RenderScene() { glClearColor(0.0f,0.0f,0.0f,0.0f);//背景为红色 glClearDepth(GL_DEPTH_TEST); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); //三维测试 glBegin(GL_POLYGON); glColor3f(0.0f,1.0f,0.0f); glVertex3f(-2.0f+100.f, -2.0f, 5.0f); glVertex3f( 2.0f+100.f, -2.0f, 5.0f); glVertex3f( 2.0f+100.f, 2.0f,5.0f); glVertex3f(-2.0f+100.f, 2.0f,5.0f); glEnd(); return TRUE; }