ArchieOpenGL基础教程第五课:搭建OpenGL基本框架③添加三维图元显示

来源:互联网 发布:wap淘宝流量和手淘流量 编辑:程序博客网 时间:2024/05/18 03:11

点击打开链接

补充:基本框架添加成员变量初始化代码

COpenglbaseView::COpenglbaseView(){// TODO: add construction code herem_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通过glViewport(0, 0, width, height)定义了视口和视口坐标。glViewport的第一、二个参数是视口左下角的像素坐标,第三、四个参数是视口的宽度和高度。

OnSize中的glMatrixMode是用来设置矩阵模式的,它有三个选项:GL_MODELVIEWGL_PROJECTIONGL_TEXTURE

GL_MODELVIEW表示从实体坐标系转到人眼坐标系。

GL_PROJECTION表示从人眼坐标系转到剪裁坐标系。

GL_TEXTURE表示从定义纹理的坐标系到粘贴纹理的坐标系的变换。

glLoadIdentity初始化工程矩阵(project matrix)

gluOrtho2D把工程矩阵设置成显示一个二维直角显示区域。

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

生成三维图形

三维和二维的坐标系统不同,三维的图形比二维的图形多一个z坐标。我们在生成简单的二维图形时,用的是gluOrtho2D;我们在生成三维图形时,需要两个远近裁剪平面,以生成透视效果。实际上,二维图形只是视线的近裁剪平面z= -1,远裁剪平面z=1;这样z坐标始终当作0,两者没有本质的差别。

在上述基础之上,我们只做简单的变化,就可以生成三维物体。

1、三维透视坐标设置

OnSize()中,把gluOrtho2D(0.0, 500.0*aspect,0.0, 500.0)换成

gluPerspective(45, aspect, 0.1f, 100.0f);

这样就实现了三维透视坐标系的设置。该语句说明了视点在原点,透视角是45度,近裁剪面在z=0.1处,远裁剪面在z=100.0f处。在离相机0.1-100单位距离内的物体是可以成像的。这里的近远裁剪面的距离都是相对相机的距离,所以都是正值。

透视投影为例, 


2、设置观察点(相机在世界坐标系中的位置)

使用gluLookAt设置相机在世界坐标系中的位置,在绘制函数前加观察点,在此之后的绘制(按世界坐标系绘制)将自动转化为相机坐标系。

 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 herestatic 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;}


 

3、添加三维绘制代码
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 herestatic 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;}




原创粉丝点击