VC++调用OpenGL实现3维图形的旋转,平移和缩放

在参考了洞庭散人关于OpenGL的系列文章之后,我自己实现了VC++调用OpenGL绘制3维图形,并实现旋转,平移和缩放,记录下来,以备以后查看,也可以帮助和我同等水平的人学习。

运行效果如下:

1. 开发环境,VC6

2.下载opengl的库文件,至少包括

将glut头文件复制到Microsoft Visual Studio\VC98\Include\GL

将glut和glut32库文件复制到Microsoft Visual Studio\VC98\Lib

将glut.dll和glut32.dll文件复制到System32下面,或者程序的运行目录下

3.新建VC工程,选择MFC应用程序,建立单文档视图程序,然后Finish

4.在Project/Settings下面,找到link页,在Object/library modules里面添加opengl32.lib glu32.lib glut32.lib glaux.lib

5.添加头文件

在stdafx.h文件中加入以下语句:

#include <gl/gl.h>


#include <gl/glu.h>


#include <gl/glut.h>


#include <gl/glaux.h>


6.添加消息响应函数

为以下的消息添加消息响应函数

7.添加成员变量和成员函数

在view类中添加:

	 HGLRC m_hRC;    //Rendering Context
	 CDC* m_pDC;        //Device Context
	 BOOL InitializeOpenGL();    //Initialize OpenGL
	 BOOL SetupPixelFormat();    //Set up the Pixel Format
     	 void RenderScene();            //Render the Scene
	 GLfloat m_xAngle;
         GLfloat m_yAngle;
         GLfloat m_xPos;
         GLfloat m_yPos;
         CPoint m_MouseDownPoint;
	 float m_Scale;


8.实现函数

     A.在view类的构造函数中初始化变量

    

CDrawCubeDemoView::CDrawCubeDemoView()
{
	// TODO: add construction code here
	m_xPos = 0.0f;
	m_yPos = 0.0f;
	m_xAngle = 0.0f;
        m_yAngle = 0.0f;
	m_Scale = 1.0f;
}

     B.在PreCreateWindow函数中加入

BOOL CDrawCubeDemoView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs
	//An OpenGL Window must be created with the following flags
	
    cs.style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
	return CView::PreCreateWindow(cs);
}


     C.在OnCreat函数中加入

int CDrawCubeDemoView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CView::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	// TODO: Add your specialized creation code here
	//Initialize OpenGL Here
	
    InitializeOpenGL();
	return 0;
}
BOOL CDrawCubeDemoView::InitializeOpenGL()
{
	//Get a DC for the Client Area
	
    m_pDC = new CClientDC(this);
	
    //Failure to Get DC
	
    if(m_pDC == NULL)
		
    {
		
        MessageBox("Error Obtaining DC");
		
        return FALSE;
		
    }
	
    //Failure to set the pixel format
	
    if(!SetupPixelFormat())
		
    {
		
        return FALSE;
		
    }
	
    //Create Rendering Context
	
    m_hRC = ::wglCreateContext (m_pDC->GetSafeHdc ());
	
    //Failure to Create Rendering Context
	
    if(m_hRC == 0)
		
    {
		
        MessageBox("Error Creating RC");
		
        return FALSE;
		
    }
	
    //Make the RC Current
	
    if(::wglMakeCurrent (m_pDC->GetSafeHdc (), m_hRC)==FALSE)
		
    {
		
        MessageBox("Error making RC Current");
		
        return FALSE;
		
    }
	
    //Specify Black as the clear color
	
    ::glClearColor(0.0f,0.0f,0.0f,0.0f);
	
    //Specify the back of the buffer as clear depth
	
    ::glClearDepth(1.0f);
	
    //Enable Depth Testing
	
    ::glEnable(GL_DEPTH_TEST);
	
    return TRUE;

}


 

BOOL CDrawCubeDemoView::SetupPixelFormat()
{
	static PIXELFORMATDESCRIPTOR pfd = 
		
    {
		
        sizeof(PIXELFORMATDESCRIPTOR),  // size of this pfd
			1,                              // version number
			
			PFD_DRAW_TO_WINDOW |            // support window
			
			PFD_SUPPORT_OPENGL |            // support OpenGL
			
			PFD_DOUBLEBUFFER,                // double buffered
			
			PFD_TYPE_RGBA,                  // RGBA type
			24,                             // 24-bit color depth
			0, 0, 0, 0, 0, 0,               // color bits ignored
			0,                              // no alpha buffer
			0,                              // shift bit ignored
			0,                              // no accumulation buffer
			0, 0, 0, 0,                     // accum bits ignored
			16,                             // 16-bit z-buffer
			0,                              // no stencil buffer
			0,                              // no auxiliary buffer
			
			PFD_MAIN_PLANE,                 // main layer
			0,                              // reserved
			0, 0, 0                         // layer masks ignored
			
    };
	
    int m_nPixelFormat = ::ChoosePixelFormat(m_pDC->GetSafeHdc(), &pfd);
	
    if ( m_nPixelFormat == 0 )
		
    {
		
		return FALSE;
		
    }
	
    if ( ::SetPixelFormat(m_pDC->GetSafeHdc(), m_nPixelFormat, &pfd) == FALSE)
		
    {
		
		return FALSE;
		
    }
	
    return TRUE;
}


D.在Onsize函数中加入

void CDrawCubeDemoView::OnSize(UINT nType, int cx, int cy) 
{
	CView::OnSize(nType, cx, cy);
	
	// TODO: Add your message handler code here
	GLdouble aspect_ratio; // width/height ratio
	
	if ( 0 >= cx || 0 >= cy )
	{
		return;
	}
	// select the full client area
	::glViewport(0, 0, cx, cy);
	// compute the aspect ratio
	// this will keep all dimension scales equal
	aspect_ratio = (GLdouble)cx/(GLdouble)cy;
	// select the projection matrix and clear it
	::glMatrixMode(GL_PROJECTION);
	::glLoadIdentity();
	// select the viewing volume
	::gluPerspective(45.0f, aspect_ratio, .01f, 200.0f);
	
	// switch back to the modelview matrix and clear it
	::glMatrixMode(GL_MODELVIEW);
     ::glLoadIdentity();
}

E.在OnDraw函数中加入

void CDrawCubeDemoView::OnDraw(CDC* pDC)
{
	CDrawCubeDemoDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here
	// Clear out the color & depth buffers
	::glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
	RenderScene();
	// Tell OpenGL to flush its pipeline
	::glFinish();
	// Now Swap the buffers
     ::SwapBuffers( m_pDC->GetSafeHdc() );
}


 

void CDrawCubeDemoView::RenderScene()
{		    

		glLoadIdentity();
		glTranslatef(m_xPos, m_yPos, -5.0f);
		glRotatef(m_xAngle, 1.0f,0.0f,0.0f);
		glRotatef(m_yAngle, 0.0f,1.0f,0.0f);
		glScalef(m_Scale,m_Scale,m_Scale);
		 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); 
         //Front Face
         glBegin(GL_POLYGON);
             glColor3f(1.0f,0.0f,0.0f);
             glVertex3f(-1.0f,-1.0f,0.0f);
             glColor3f(1.0f,1.0f,0.0f);
             glVertex3f( 1.0f,-1.0f,0.0f);
             glColor3f(1.0f,0.0f,1.0f);
             glVertex3f( 1.0f, 1.0f,0.0f);
             glColor3f(1.0f,1.0f,1.0f);
             glVertex3f(-1.0f, 1.0f,0.0f);
         glEnd();
         glColor3f(1.0f,1.0f,0.0f);
         //Back Face
         glBegin(GL_POLYGON);
             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);
         glEnd();
         glColor3f(1.0f,0.0f,1.0f);
         //Left Face
         glBegin(GL_POLYGON);
             glVertex3f(-1.0f,-1.0f, 0.0f);
             glVertex3f(-1.0f, 1.0f, 0.0f);
             glVertex3f(-1.0f, 1.0f,-1.0f);
             glVertex3f(-1.0f,-1.0f,-1.0f);
         glEnd();
         glColor3f(0.0f,1.0f,0.0f);
         //Right Face
         glBegin(GL_POLYGON);
             glVertex3f(1.0f,-1.0f, 0.0f);
             glVertex3f(1.0f,-1.0f,-1.0f);
             glVertex3f(1.0f, 1.0f,-1.0f);
             glVertex3f(1.0f, 1.0f, 0.0f);
         glEnd();
         glColor3f(0.0f,1.0f,1.0f);
         //Top Face
         glBegin(GL_POLYGON);
             glVertex3f(-1.0f, 1.0f,  0.0f);
             glVertex3f( 1.0f, 1.0f,  0.0f);
             glVertex3f( 1.0f, 1.0f, -1.0f);
             glVertex3f(-1.0f, 1.0f, -1.0f);
         glEnd();
         glColor3f(0.0f,0.0f,1.0f);
         //Botton Face
         glBegin(GL_POLYGON);
		 glVertex3f(-1.0f, -1.0f,  0.0f);
		 glVertex3f(-1.0f, -1.0f, -1.0f);
		 glVertex3f( 1.0f, -1.0f, -1.0f);
		 glVertex3f( 1.0f, -1.0f,  0.0f);
         glEnd();
 
}


F.改写OnEraseBkgnd函数,并在OnDestroy函数中加入

BOOL CDrawCubeDemoView::OnEraseBkgnd(CDC* pDC) 
{
	// TODO: Add your message handler code here and/or call default
	
	return TRUE;
}


 

void CDrawCubeDemoView::OnDestroy() 
{
	CView::OnDestroy();
	
	// TODO: Add your message handler code here
	//Make the RC non-current
	if(::wglMakeCurrent (0,0) == FALSE)
	{
		MessageBox("Could not make RC non-current");
	}
	
	//Delete the rendering context
	if(::wglDeleteContext (m_hRC)==FALSE)
	{
		MessageBox("Could not delete RC");
	}
	//Delete the DC
	if(m_pDC)
	{
		delete m_pDC;
	}
	//Set it to NULL
     m_pDC = NULL;
}


G.实现鼠标响应函数

void CDrawCubeDemoView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	// TODO: Add your message handler code here and/or call default
	switch (nChar)
	{
	case VK_UP:        m_yPos = m_yPos + 0.1f;
		break;
	case VK_DOWN:    m_yPos = m_yPos - 0.1f;
		break;
	case VK_LEFT:    m_xPos = m_xPos - 0.1f;
		break;
	case VK_RIGHT:  m_xPos = m_xPos + 0.1f;
		break;
	default:        MessageBox("Press the arrow keys only");
		break;
	}        
	
    InvalidateRect(NULL,FALSE);
	CView::OnKeyDown(nChar, nRepCnt, nFlags);
}

void CDrawCubeDemoView::OnLButtonDown(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	m_MouseDownPoint=point;
     SetCapture();
	CView::OnLButtonDown(nFlags, point);
}

void CDrawCubeDemoView::OnLButtonUp(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	m_MouseDownPoint=CPoint(0,0);
     ReleaseCapture();
	CView::OnLButtonUp(nFlags, point);
}

void CDrawCubeDemoView::OnMouseMove(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	if (GetCapture()==this)
	{
		//Increment the object rotation angles
		m_xAngle+=(point.y-m_MouseDownPoint.y)/3.6;
		m_yAngle+=(point.x-m_MouseDownPoint.x)/3.6;
		//Redraw the view
		InvalidateRect(NULL,FALSE);
		//Set the mouse point
		m_MouseDownPoint=point;
     };
	CView::OnMouseMove(nFlags, point);
}

BOOL CDrawCubeDemoView::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt) 
{
	// TODO: Add your message handler code here and/or call default
	m_Scale += 0.01 *zDelta /120;
	InvalidateRect(NULL,FALSE);
	return CView::OnMouseWheel(nFlags, zDelta, pt);
}


 


 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值