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

点击打开链接

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

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通过 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 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;
}


 

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




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值