《基于MFC的OpenGL编程》Part3 Drawing Simple 3D objects

《基于MFC的OpenGL编程》Part3  Drawing Simple 3D objects

视见体

Viewing Volume is nothing but the region of 3D Cartesian space in that will occupy the window.It is nothing but the minimum and maximum x, y and z values that are inside the window. So if a vertex is outside this range of x, y and z values then they are clipped by OpenGL before rendering can occur.

Z Buffer

The new term we have to deal with in addition to width and height of an object in 3D graphics is depth.The depth of an object is its distance from the viewpoint. Theviewpoint is the location from which we are looking at that point.This depth value goes into the depth or Z-buffer. If we are drawing 2 objects that have some pixels that overlap, the first object will after it is rendered have its depth value in the depth buffer. When the next object is rendered, OpenGL will check to see whether the pixel it’s about to draw is in front of (with respect to the viewpoint) any pixel from the first object that’s already drawn. It does this by checking the Z value of the current pixel with the value that is already in the buffer. If the new pixel is closer to the viewpoint, OpenGL places its depth value in the depth buffer. This is how the Z-buffer works.

正交投影和透视投影

One term we need to understand very well to learn 3D Graphics well is projection. Well, computer graphics at its simplest is all about setting a color to a pixel on screen. And a pixel on a screen can have only two dimensions. So 3D graphics is merely an illusion.The 3D coordinates that we specify will have to be projected onto a 2D surface to create this illusion for us. And we have to specify how this projection works. By specifying a projection we specify the clipping or viewing volume.

基本3D图形绘制

1,CMy2OpenGLView.h中加入下列变量:

    BOOL m_bPoint;		//Status of Point
    BOOL m_bLine;        //Status of Line
    BOOL m_bPolygon;    //Status of Polygon
    BOOL m_bTriangle;    //Status of Triangle
	
    BOOL m_bCube;       
    BOOL m_bTorus;       
    BOOL m_bTeapot;       
    BOOL m_bIcosahedron;
    BOOL m_bSimpleCube;

 并且在构造函数中初始化:

CMy2OpenGLView::CMy2OpenGLView()
{
    // TODO: add construction code here
    m_bPoint    = FALSE;
    m_bLine        = FALSE;
    m_bPolygon    = FALSE;
    m_bTriangle = FALSE;

    m_bCube           = FALSE;        
    m_bTorus       = FALSE;        
    m_bTeapot       = FALSE;        
    m_bIcosahedron = FALSE;
    m_bSimpleCube  = FALSE;  
}

2、加入五个菜单项及其对应的事件处理程序

与上一篇一样,在资源文件视图中找到ToolBar,修改IDR_MAINFRAME中的工具图标,分别设置ID和提示,ID分别为:ID_OBJECTS_TEAPOT、ID_OBJECTS_CUBE、ID_OBJECTS_TORUS、ID_OBJECTS_ICOSAHEDRON、ID_OBJECTS_SIMPLECUBE,提示自己设置一下就可以了。分别是茶壶、立方体、环体、二十面体、简单立方体

void CMy2OpenGLView::OnObjectsTeapot() 
{
	// TODO: Add your command handler code here 
	//画茶壶
	m_bCube           = FALSE;        
	m_bTorus       = FALSE;        
	m_bTeapot       = TRUE;        
	m_bIcosahedron = FALSE;
	m_bSimpleCube  = FALSE;        
	InvalidateRect(NULL,FALSE);    
	
}

void CMy2OpenGLView::OnObjectsCube() 
{
	// TODO: Add your command handler code here
	//画立方体
    m_bCube           = TRUE;    
    m_bTorus       = FALSE;        
    m_bTeapot       = FALSE;        
    m_bIcosahedron = FALSE;
    m_bSimpleCube  = FALSE;        
    InvalidateRect(NULL,FALSE);
	
}

void CMy2OpenGLView::OnObjectsTorus() 
{
	// TODO: Add your command handler code here
	//画环形体
    m_bCube           = FALSE;    
    m_bTorus       = TRUE;        
    m_bTeapot       = FALSE;        
    m_bIcosahedron = FALSE;
    m_bSimpleCube  = FALSE;        
    InvalidateRect(NULL,FALSE);
}

void CMy2OpenGLView::OnObjectsIcosahedron() 
{
	// TODO: Add your command handler code here
	//画二十面体
    m_bCube        = FALSE;    
    m_bTorus       = FALSE;        
    m_bTeapot      = FALSE;        
    m_bIcosahedron = TRUE;
    m_bSimpleCube  = FALSE;        
    InvalidateRect(NULL,FALSE);
}

void CMy2OpenGLView::OnObjectsSimplecube() 
{
	// TODO: Add your command handler code here
	//画简单立方体
    m_bCube        = FALSE;    
    m_bTorus       = FALSE;        
    m_bTeapot      = FALSE;        
    m_bIcosahedron = FALSE;
    m_bSimpleCube  = TRUE;        
    InvalidateRect(NULL,FALSE);
	
}

3,由于开始绘制3维图形,因此使用第二篇文章(Part2)的OnSize()函数:主要就是将gluOrtho2D(-10.0, aspect_ratio,-10.0,10.0);替换为glPerspective(40.0f,aspect_ratio, 4.0f, -10.0f);。

4RenderScene中加入具体的绘制代码:

注:添加的代码从//Replace the current matrix with Identity Matrix这句注释开始

void CMy2OpenGLView::RenderScene ()
{//第一个玩具嘛,先空着,后面慢慢填
/*    //Clear the color buffer 
	
    glClear(GL_COLOR_BUFFER_BIT |GL_DEPTH_BUFFER_BIT);
    	glLoadIdentity();
    	
    	glTranslatef(200.0,200.0,0.0);
    	glBegin(GL_TRIANGLES);
    	glColor4f(0.0f,1.0f,0.0f,0.0f);
		glVertex3f(0.0f,100.0f,0.0f);
    	glColor4f(1.0f,1.0f,0.0f,0.0f);
    	glVertex3f(-100.0f,0.0f,0.0f);
    	glColor4f(255.0f,0.0f,0.0f,0.0f);
    	glVertex3f(100.0f,0.0f,0.0f);
    	glEnd();
    	
        //Flush the rendering pipeline
    	
       

	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
	glLoadIdentity();

	glTranslatef(100.0,200.0,0.0);

	glBegin(GL_POLYGON);
		glColor3f(0.0f,255.0f,255.0f);
		glVertex3f(-1.0,-2.0,0.0);

		glColor3f(0.0f,0.0f,255.0f);
		glVertex3f(1.0,2.0,0.0);

		glColor3f(0.0f,255.0f,0.0f);
		glVertex3f(3.0,4.0,0.0);

		glColor3f(255.0f,255.0f,0.0f);
		glVertex3f(2.0,2.0,0.0);

		glColor3f(0.0f,0.0f,255.0f);
		glVertex3f(0.0,1.0,0.0);		
		
		glColor3f(155.0f,255.0f,255.0f);
 		glVertex3f(-1.0,-2.0,-0.0);
	glEnd();
	glFlush();


 glLoadIdentity();
  glClear(GL_COLOR_BUFFER_BIT); 
		glTranslatef(-50.0,-350.0,0.0);
    glBegin(GL_POLYGON);
        glColor4f(1.0f,0.0f,0.0f,1.0f);
        glVertex2f(200.0f,250.0f);
        glColor4f(0.0f,1.0f,0.0f,1.0f);
        glVertex2f(650.0f,600.0f);
        glColor4f(0.0f,0.0f,1.0f,1.0f);
        glVertex2f(650.0f,250.0f);
    glEnd();
    glFlush();*/


	//绘制函数
	
    if(m_bPoint==TRUE)
		
    {
		
        glPointSize(3.0f);
		
        glBegin(GL_POINTS);//坐标原点在窗口视图的中间位置
		
		glVertex2f(0.0f,0.0f);
		
		glVertex2f(1.0f,0.0f);
		
		glVertex2f(0.5f,1.0f);
		
        glEnd();
		
    }
	
    else if(m_bLine==TRUE)
		
    {
		
        glBegin(GL_LINES);
		
		glVertex2f(-1.0f,-1.0f);
		
		glVertex2f(1.0f,1.0f);
		
        glEnd();
		
    }
	
    else if(m_bTriangle==TRUE)
		
    {
		
        glBegin(GL_TRIANGLES);
		
		glVertex2f(-2.0f,0.0f);
		
		glVertex2f(2.0f,0.0f);
		
		glVertex2f(0.0f,4.0f);
		
        glEnd();
		
    }
	
    else if(m_bPolygon==TRUE)
		
    {
		
        glBegin(GL_POLYGON);
		
		glVertex2f(0.0f,0.0f);
		
		glVertex2f(3.0f,0.0f);
		
		glVertex2f(4.0f,3.0f);
		
		glVertex2f(1.5f,6.0f);
		
		glVertex2f(-1.0f,3.0f);
		
        glEnd();
	}
	 <strong>//Replace the current matrix with Identity Matrix</strong>
	glLoadIdentity();
    glTranslatef(0.0f,0.0f,-5.0f);
    glRotatef(-30.0f,1.0f,1.0f,0.0f);
	//Draw a Teapot
    if(m_bTeapot)
    {
        glutWireTeapot(1.0f);
    }
	//Draw a Cube
	if (m_bCube)
	{
		glutWireCube(1.0f);
	}
	if (m_bTorus)
	{
		glutWireTorus(0.5f,1.0f,50,50);
	}
	if (m_bIcosahedron)
	{
		glutWireIcosahedron();
	}
	if (m_bSimpleCube)
	{
		glPolygonMode(GL_FRONT_AND_BACK,GL_LINES);
		
		//front face
		glBegin(GL_POLYGON);
			glColor3f(1.0f,0.0f,1.0f);
			glVertex3f(-1.0,-1.0,0.0);
			glColor3f(1.0f,1.0f,1.0f);
			glVertex3f(-1.0,1.0,0.0);
			glColor3f(1.0f,1.0f,0.0f);
			glVertex3f(1.0,1.0,0.0);
			glColor3f(0.0f,0.8f,1.0f);
			glVertex3f(1.0,-1.0,0.0);
		glEnd();

		//back face
		glBegin(GL_POLYGON);
			glColor3f(0.0f,0.5f,0.0f);
			glVertex3f(-1.0,-1.0,-1.0);
			glColor3f(1.0f,0.8f,10.0f);
			glVertex3f(-1.0,1.0,-1.0);
			glColor3f(0.0f,0.0f,1.0f);
			glVertex3f(1.0,1.0,-1.0);
			glColor3f(1.0f,1.0f,0.0f);
			glVertex3f(1.0,-1.0,-1.0);
		glEnd();

		//left face
		glBegin(GL_POLYGON);
			glColor3f(1.0f,0.5f,0.0f);
			glVertex3f(-1.0,-1.0,0.0);
			glColor3f(0.8f,0.0f,0.0f);
			glVertex3f(-1.0,1.0,0.0);
			glColor3f(0.0f,0.0f,1.0f);
			glVertex3f(-1.0,1.0,-1.0);
			glColor3f(0.0f,0.6f,1.0f);
			glVertex3f(-1.0,-1.0,-1.0);
		glEnd();

		//right face
		glBegin(GL_POLYGON);
			glColor3f(1.0f,0.0f,0.0f);
			glVertex3f(1.0,-1.0,0.0);
			glColor3f(0.0f,1.0f,1.0f);
			glVertex3f(1.0,1.0,0.0);
			glColor3f(0.0f,0.0f,1.0f);
			glVertex3f(1.0,1.0,-1.0);
			glColor3f(1.0f,0.0f,1.0f);
			glVertex3f(1.0,-1.0,-1.0);
		glEnd();

		//top face
		glBegin(GL_POLYGON);
			glColor3f(0.0f,1.0f,0.0f);
			glVertex3f(-1.0,1.0,0.0);
			glColor3f(0.0f,0.0f,1.0f);
			glVertex3f(-1.0,1.0,-1.0);
			glColor3f(1.0f,0.0f,0.0f);
			glVertex3f(1.0,1.0,-1.0);
			glColor3f(0.0f,0.5f,0.8f);
			glVertex3f(1.0,1.0,0.0);
		glEnd();

		//bottom face
		glBegin(GL_POLYGON);
			glColor3f(0.0f,1.0f,0.0f);
			glVertex3f(-1.0,-1.0,0.0);
			glColor3f(0.0f,0.0f,1.0f);
			glVertex3f(-1.0,-1.0,-1.0);
			glColor3f(1.0f,0.0f,0.0f);
			glVertex3f(1.0,-1.0,-1.0);
			glColor3f(0.0f,0.5f,0.8f);
			glVertex3f(1.0,-1.0,0.0);
		glEnd();

	}
}

5、期待已久的界面:





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值