MFC下OpenGL入门计算机图形学作业.docx
《MFC下OpenGL入门计算机图形学作业.docx》由会员分享,可在线阅读,更多相关《MFC下OpenGL入门计算机图形学作业.docx(16页珍藏版)》请在冰点文库上搜索。
![MFC下OpenGL入门计算机图形学作业.docx](https://file1.bingdoc.com/fileroot1/2023-5/4/ed70ecba-9a08-465f-8c0b-799550d4d2ca/ed70ecba-9a08-465f-8c0b-799550d4d2ca1.gif)
MFC下OpenGL入门计算机图形学作业
MFC下OpenGL入门
源文件
1,建一工程文件,我这里命名为first,现在first工程里面我们没有添加任何东西,所有的东西都是MFC自动帮我们创建的。
2,添加链接库。
这一步很关键。
打开菜单栏下的项目->属性->配置属性->链接器->输入->附加依赖项里加入OpenGL32.libGLu32.libGLaux.lib,如图
3,加头文件,在stdafx里面添加opengl的头文件。
如下代码所示:
代码
//-----------------------Tramp---添加OpenGL库头文件----------------------------->
#include"stdio.h"
#include"math.h"
#include"gl\gl.h"
#include"gl\glu.h"
#include"gl\glaux.h"
//---------------------------------------------------------------------------<
4,CCY457OpenGLView类的属性栏,为下述消息加入消息处理函数:
WM_CREATE(forOnCreate),WM_DESTROY(forOnDestroy),WM_SIZE(forOnSize),WM_ERASEBACKGROUND(forOnEraseBkground).如下图:
5,设置窗口显示风格。
窗口创建之前我们必须设置窗口风格包含WS_CLIPCHILDREN和WS_CLIPSIBLINGS,从而避免OpenGL绘制到其他窗口中去。
这些应该放在PreCreateWindow()中。
代码
BOOLCfirstView:
:
PreCreateWindow(CREATESTRUCT&cs)
{
//TODO:
在此处通过修改
//CREATESTRUCTcs来修改窗口类或样式
cs.style|=WS_CLIPSIBLINGS|WS_CLIPCHILDREN;//Tramp
returnCView:
:
PreCreateWindow(cs);
}
6,在CfirstView.h中加入如下语句:
/************************************************************************/
/*设置的变量是RenderingContext(着色描述表)。
每一个OpenGL都被连接到一个着
色描述表上。
着色描述表将所有的OpenGL调用命令连接到DeviceContext(设备描述表)上。
我将OpenGL的着色描述表定义为hRC。
要让您的程序能够绘制窗口的话,还需要创建一个
设备描述表,也就是第二行的内容。
Windows的设备描述表被定义为hDC。
DC将窗口连接到
GDI(GraphicsDeviceInterface图形设备接口)。
而RC将OpenGL连接到DC*/
/************************************************************************/
HGLRCm_hRC;//RenderingContext着色描述表
CDC*m_pDC;//DeviceContext设备描述表
BOOLInitializeOpenGL();//InitializeOpenGL
BOOLSetupPixelFormat();//SetupthePixelFormat
voidRenderScene();//RendertheScene
7,在OnCreate中我们将通过建立像素格式和绘制上下文来初始化OpenGL.在InitializeOpenGL()中会创建一个设备上下文(DC),为这个DC选择一个像素格式,创建和这个DC相关的绘制上下文(RC),然后选择这个RC.这个函数会调用SetupPixelFormat()来建立像素格式。
intClesson1View:
:
OnCreate(LPCREATESTRUCTlpCreateStruct)
{
if(CView:
:
OnCreate(lpCreateStruct)==-1)
return-1;
//TODO:
在此添加您专用的创建代码
InitializeOpenGL();//初始化openGL绘图
return0;
}
//初始化opengl绘制
BOOLCfirstView:
:
InitializeOpenGL()
{
//GetaDCfortheClientArea
m_pDC=newCClientDC(this);
//FailuretoGetDC
if(m_pDC==NULL)
{
//:
:
MessageBox("ErrorObtainingDC");
returnFALSE;
}
//Failuretosetthepixelformat
if(!
SetupPixelFormat())
{
returnFALSE;
}
//CreateRenderingContext
m_hRC=:
:
wglCreateContext(m_pDC->GetSafeHdc());
//FailuretoCreateRenderingContext
if(m_hRC==0)
{
//MessageBox("ErrorCreatingRC");
returnFALSE;
}
//MaketheRCCurrent
if(:
:
wglMakeCurrent(m_pDC->GetSafeHdc(),m_hRC)==FALSE)
{
//MessageBox("ErrormakingRCCurrent");
returnFALSE;
}
//SpecifyBlackastheclearcolor
:
:
glClearColor(0.0f,0.0f,0.0f,0.0f);
//Specifythebackofthebufferascleardepth
:
:
glClearDepth(1.0f);
//EnableDepthTesting
:
:
glEnable(GL_DEPTH_TEST);
returnTRUE;
}
//设置像素格式
BOOLCfirstView:
:
SetupPixelFormat()
{
staticPIXELFORMATDESCRIPTORpfd=
{
sizeof(PIXELFORMATDESCRIPTOR),//sizeofthispfd
1,//versionnumber
PFD_DRAW_TO_WINDOW|//supportwindow
PFD_SUPPORT_OPENGL|//supportOpenGL
PFD_DOUBLEBUFFER,//doublebuffered
PFD_TYPE_RGBA,//RGBAtype
24,//24-bitcolordepth
0,0,0,0,0,0,//colorbitsignored
0,//noalphabuffer
0,//shiftbitignored
0,//noaccumulationbuffer
0,0,0,0,//accumbitsignored
16,//16-bitz-buffer
0,//nostencilbuffer
0,//noauxiliarybuffer
PFD_MAIN_PLANE,//mainlayer
0,//reserved
0,0,0//layermasksignored
};
intm_nPixelFormat=:
:
ChoosePixelFormat(m_pDC->GetSafeHdc(),&pfd);
if(m_nPixelFormat==0)
{
returnFALSE;
}
if(:
:
SetPixelFormat(m_pDC->GetSafeHdc(),m_nPixelFormat,&pfd)==FALSE)
{
returnFALSE;
}
returnTRUE;
}
8,在OnSize()中一般用来设置视口和视锥,因为这些是和窗口大小相关的。
基本操作包括设置视口,选择投影矩阵,设置模型视图矩阵。
voidCfirstView:
:
OnSize(UINTnType,intcx,intcy)
{
CView:
:
OnSize(nType,cx,cy);
//TODO:
在此处添加消息处理程序代码
GLdoubleaspect_ratio;//width/heightratio
if(0>=cx||0>=cy)
{
return;
}
//selectthefullclientarea
:
:
glViewport(0,0,cx,cy);
//computetheaspectratio
//thiswillkeepalldimensionscalesequal
aspect_ratio=(GLdouble)cx/(GLdouble)cy;
//selecttheprojectionmatrixandclearit
:
:
glMatrixMode(GL_PROJECTION);
:
:
glLoadIdentity();
//selecttheviewingvolume
:
:
gluPerspective(45.0f,aspect_ratio,.01f,200.0f);//画三维
//:
:
gluOrtho2D(-10.0f,10.0f,-10.0f,10.0f);//二维
//switchbacktothemodelviewmatrixandclearit
:
:
glMatrixMode(GL_MODELVIEW);
:
:
glLoadIdentity();
}
9,在绘制场景时,一般包括如下步骤:
1)清空缓存。
2)绘制场景。
3)Flush掉渲染流水线。
4)若设置了双缓冲,则交换前后台缓冲区。
voidCfirstView:
:
OnDraw(CDC*/*pDC*/)
{
CfirstDoc*pDoc=GetDocument();
ASSERT_VALID(pDoc);
if(!
pDoc)
return;
//TODO:
在此处为本机数据添加绘制代码
//Clearoutthecolor&depthbuffers
:
:
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
RenderScene();//绘图都放在这
//TellOpenGLtoflushitspipeline
:
:
glFinish();
//NowSwapthebuffers
:
:
SwapBuffers(m_pDC->GetSafeHdc());
}
10,为了使改变窗口大小时严重的闪烁,在OnEraseBkgnd里做一些操作,避免windows自己的窗口刷新闪烁。
BOOLCfirstView:
:
OnEraseBkgnd(CDC*pDC)
{
//TODO:
在此添加消息处理程序代码和/或调用默认值
returnTRUE;
}
11,为了避免内存泄露,我们要将在SetupPixelFormat()中使用了new运算符来为CClientDC对象分配的内存在程序关闭时delete掉。
voidCfirstView:
:
OnDestroy()
{
CView:
:
OnDestroy();
//TODO:
在此处添加消息处理程序代码
//MaketheRCnon-current
if(:
:
wglMakeCurrent(0,0)==FALSE)
{
MessageBox(_T("CouldnotmakeRCnon-current"));
}
//Deletetherenderingcontext
if(:
:
wglDeleteContext(m_hRC)==FALSE)
{
MessageBox(_T("CouldnotdeleteRC"));
}
//DeletetheDC
if(m_pDC)
{
deletem_pDC;
}
//SetittoNULL
m_pDC=NULL;
}
12,下面写主绘图函数,RenderScene(),在窗口画了一个正方体、一个四面体。
voidCfirstView:
:
RenderScene()
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);//ClearScreenAndDepthBuffer
glLoadIdentity();//ResetTheCurrentModelviewMatrix
glTranslatef(-1.5f,0.0f,-6.0f);//MoveLeft1.5UnitsAndIntoTheScreen6.0
glRotatef(30,0.0f,1.0f,0.0f);//RotateTheTriangleOnTheYaxis(NEW)
glBegin(GL_TRIANGLES);//StartDrawingATriangle
glColor3f(1.0f,0.0f,0.0f);//Red
glVertex3f(0.0f,1.0f,0.0f);//TopOfTriangle(Front)
glColor3f(0.0f,1.0f,0.0f);//Green
glVertex3f(-1.0f,-1.0f,1.0f);//LeftOfTriangle(Front)
glColor3f(0.0f,0.0f,1.0f);//Blue
glVertex3f(1.0f,-1.0f,1.0f);//RightOfTriangle(Front)
glColor3f(1.0f,0.0f,0.0f);//Red
glVertex3f(0.0f,1.0f,0.0f);//TopOfTriangle(Right)
glColor3f(0.0f,0.0f,1.0f);//Blue
glVertex3f(1.0f,-1.0f,1.0f);//LeftOfTriangle(Right)
glColor3f(0.0f,1.0f,0.0f);//Green
glVertex3f(1.0f,-1.0f,-1.0f);//RightOfTriangle(Right)
glColor3f(1.0f,0.0f,0.0f);//Red
glVertex3f(0.0f,1.0f,0.0f);//TopOfTriangle(Back)
glColor3f(0.0f,1.0f,0.0f);//Green
glVertex3f(1.0f,-1.0f,-1.0f);//LeftOfTriangle(Back)
glColor3f(0.0f,0.0f,1.0f);//Blue
glVertex3f(-1.0f,-1.0f,-1.0f);//RightOfTriangle(Back)
glColor3f(1.0f,0.0f,0.0f);//Red
glVertex3f(0.0f,1.0f,0.0f);//TopOfTriangle(Left)
glColor3f(0.0f,0.0f,1.0f);//Blue
glVertex3f(-1.0f,-1.0f,-1.0f);//LeftOfTriangle(Left)
glColor3f(0.0f,1.0f,0.0f);//Green
glVertex3f(-1.0f,-1.0f,1.0f);//RightOfTriangle(Left)
glEnd();//DoneDrawingThePyramid
glLoadIdentity();//ResetTheCurrentModelviewMatrix
glTranslatef(1.5f,0.0f,-7.0f);//MoveRight1.5UnitsAndIntoTheScreen7.0
glRotatef(25,1.0f,1.0f,1.0f);//RotateTheQuadOnTheXaxis(NEW)
glBegin(GL_QUADS);//DrawAQuad
glColor3f(0.0f,1.0f,0.0f);//SetTheColorToGreen
glVertex3f(1.0f,1.0f,-1.0f);//TopRightOfTheQuad(Top)
glVertex3f(-1.0f,1.0f,-1.0f);//TopLeftOfTheQuad(Top)
glVertex3f(-1.0f,1.0f,1.0f);//BottomLeftOfTheQuad(Top)
glVertex3f(1.0f,1.0f,1.0f);//BottomRightOfTheQuad(Top)
glColor3f(1.0f,0.5f,0.0f);//SetTheColorToOrange
glVertex3f(1.0f,-1.0f,1.0f);//TopRightOfTheQuad(Bottom)
glVertex3f(-1.0f,-1.0f,1.0f);//TopLeftOfTheQuad(Bottom)
glVertex3f(-1.0f,-1.0f,-1.0f);//BottomLeftOfTheQuad(Bottom)
glVertex3f(1.0f,-1.0f,-1.0f);//BottomRightOfTheQuad(Bottom)
glColor3f(1.0f,0.0f,0.0f);//SetTheColorToRed
glVertex3f(1.0f,1.0f,1.0f);//TopRightOfTheQuad(Front)
glVertex3f(-1.0f,1.0f,1.0f);//TopLeftOfTheQuad(Front)
glVertex3f(-1.0f,-1.0f,1.0f);//BottomLeftOfTheQuad(Front)
glVertex3f(1.0f,-1.0f,1.0f);//BottomRightOfTheQuad(Front)
glColor3f(1.0f,1.0f,0.0f);//SetTheColorToYellow
glVertex3f(1.0f,-1.0f,-1.0f);//TopRightOfTheQuad(Back)
glVertex3f(-1.0f,-1.0f,-1.0f);//TopLeftOfTheQuad(Back)
glVertex3f(-1.0f,1.0f,-1.0f);//BottomLeftOfTheQuad(Back)
glVertex3f(1.0f,1.0f,-1.0f);//BottomRightOfTheQuad(Back)
glColor3f(0.0f,0.0f,1.0f);//SetTheColorToBlue
glVertex3f(-1.0f,1.0f,1.0f);//TopRightOfTheQuad(Left)
glVertex3f(-1.0f,1.0f,-1.0f);//TopLeftOfTheQuad(Left)
glVertex3f(-1.0f,-1.0f,-1.0f);//BottomLeftOfTheQuad(Left)
glVertex3f(-1.0f,-1.0f,1.0f);//BottomRightOfTheQuad(Left)
glColor3f(1.0f,0.0f,1.0f);//SetTheColorToViolet
glVertex3f(1.0f,1.0f,-1.0f);//TopRightOfTheQuad(Right)
glVertex3f(1.0f,1.0f,1.0f);//TopLeftOfTheQuad(Right)
glVertex3f(1.0f,-1.0f,1.0f);//BottomLeftOfTheQuad(Right)
glVertex3f(1.0f,-1.0f,-1.0f);//BottomRightOfTheQuad(Right)
glEnd();//DoneDrawingTheQuad
}
附,坐标交互操作的实现:
//控制旋转和位置的变量
GLfloatm_xAngle;//
GLfloatm_yAngle;
GLfloatm_xPos;
GLfloatm_yPos;
CPointm_MouseDownPoint;
旋转的关键操作:
m_xAngle+=(point.y-m_MouseDownPoint.y)/3.6;
m_yAngle+=(point.x-m_MouseDownPoint.x)/3.6;
//Setthemousepoint
m_Mous