设为首页 加入收藏

TOP

Visual C++下OpenGL开发框架与应用(二)
2012-11-04 15:23:03 来源: 作者: 【 】 浏览:418
Tags:Visual OpenGL 开发 框架 应用
  三、例程分析

  3D游戏里面经常会出现地形这一三维实体,下面的例程就是在一个单文档应用程序下实现3D地形的显示。大概思路是建立OpenGL的程序框架,然后初始化地形数据,在此框架上绘制3D地形,由于为了介绍框架,所以程序中涉及到地形数据的初始化和绘制部分都比较简单,详见本文的源代码部分。另外这里也没有涉及到纹理映射、材质等高级内容,但是实际编程(www.cppentry.com)中,为了使3D图形更生动,往往要应用这些技术。

  此例程的核心代码及分析如下:

BOOL CTerraintestView::PreCreateWindow(CREATESTRUCT& cs)
{
//设置窗口类型
cs.style |=WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
return CView::PreCreateWindow(cs);
}
void CTerraintestView::OnDraw(CDC* pDC)
{
//渲染场景
RenderScene();
}
BOOL CTerraintestView::InitializeOpenGL(CDC *pDC)
{
//进行opengl的初始化工作
m_pDC=pDC;
//首先把DC的象素格式调整为指定的格式,以便后面对DC的使用
SetupPixelFormat();
//根据DC来创建RC
m_hRC=::wglCreateContext(m_pDC->GetSafeHdc());
//设置当前的RC,以后的画图操作都画在m_pDC指向的DC上
::wglMakeCurrent(m_pDC->GetSafeHdc(),m_hRC);
//下面可以进行画图操作了
return TRUE;
}
int CTerraintestView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
//获取客户区的设备描述表
m_pDC=new CClientDC(this);
//初始化OpenGL
InitializeOpenGL(m_pDC);
//初始化OpenGL的一些状态参数并对地形数据进行初始化
InitGL();
return 0;
}
BOOL CTerraintestView::SetupPixelFormat()
{
//初始化象素格式以及选取合适的格式来创建RC
PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR), // pfd结构的大小
1, // 版本号
PFD_DRAW_TO_WINDOW | // 支持在窗口中绘图
PFD_SUPPORT_OPENGL | // 支持 OpenGL
PFD_DOUBLEBUFFER, // 双缓存模式
PFD_TYPE_RGBA, // RGBA 颜色模式
24, // 24 位颜色深度 ,color depth
0, 0, 0, 0, 0, 0, // 忽略颜色位
0, // 没有非透明度缓存
0, // 忽略移位位
0, // 无累加缓存
0, 0, 0, 0, // 忽略累加位
32, // 32 位深度缓存
0, // 无模板缓存
0, // 无辅助缓存
PFD_MAIN_PLANE, // 主层
0, // 保留
0, 0, 0 // 忽略层,可见性和损毁掩模
};
//在DC中选择合适的象素格式并返回索引号
int pixelformat;
pixelformat=::ChoosePixelFormat(m_pDC->GetSafeHdc(),&pfd);
if (pixelformat==0)
{
AfxMessageBox("no matched pixelformat!");
return FALSE;
}
//设置指定象素格式
if (::SetPixelFormat(m_pDC->GetSafeHdc(),pixelformat,&pfd)==FALSE)
{
AfxMessageBox("can't set specified pixelformat!");
return FALSE;
}
return TRUE;
}
BOOL CTerraintestView::InitGL()
{
//初始化整个场景和OpenGL的状态变量
//初始化地形数据以便于绘制
InitTerrainData();
// OpenGL场景初始化(光照、雾化等〕
glShadeModel(GL_SMOOTH); // Enable Smooth Shading
glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background
glClearDepth(1.0f); // Depth Buffer Setup
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do
return TRUE; // Initialization Went OK
}
void CTerraintestView::InitTerrainData()
{
//随机初始化地形数据,此处与程序框架无关,故省略,可以参加本文对应的源代码
}
BOOL CTerraintestView::RenderScene()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(0,7,0,4,4,4,0,1,0); //视图变换
DrawTerrain(); //绘制地形
::SwapBuffers(m_pDC->GetSafeHdc()); //交互缓冲区
return TRUE;
}
BOOL CTerraintestView::DrawTerrain()
{
//根据地形数据绘制出地形
float h1,h2,h3,h4;
float color1,color2,color3,color4;
int x,z;
for(x=1;x<29;x++)
{
for(z=1;z<29;z++)
{
//获取相邻的四个顶点的高程数据
h1=m_land[x][z];
h2=m_land[x][z+1];
h3=m_land[x+1][z];
h4=m_land[x+1][z+1];
//计算各个顶点的颜色数据
color1=h1*256/(m_Max-m_Min);
color2=h2*256/(m_Max-m_Min);
color3=h3*256/(m_Max-m_Min);
color4=h4*256/(m_Max-m_Min);
//地形由四边形构成
glBegin(GL_QUADS);
glColor3f(color1,0,color1);
glVertex3d((float)x,h1,(float)z);
glColor3f(color2,color2,color2);
glVertex3d((float)x,h2,(float)(z+1));
glColor3f(color3,color3,color3);
glVertex3d((float)(x+1),h3,(float)z);
glColor3f(color4,color4,color4);
glVertex3d((float)(x+1),h4,(float)(z+1));
glEnd();
}
}
return TRUE;
}
void CTerraintestView::OnDestroy()
{
CView::OnDestroy();
//删除当前的RC
::wglMakeCurrent(NULL,NULL);
//删除RC
::wglDeleteContext(m_hRC);
//删除DC
if (m_pDC)
delete m_pDC;
}
void CTerraintestView::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);
//添加窗口缩放时的图形变换函数,即视口变换
glViewport(0,0,cx,cy);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f,(GLfloat)cx/(GLfloat)cy,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}

  四、小结

  前面介绍了VC下的OpenGL应用程序的开发框架,借助此框架,使得开发人员象使用Win32函数一样来使用OpenGL提供的图形库函数,减轻了开发的难度,增强了程序代码的鲁棒性,因此对使用OpenGL进行图形应用开发具有较高的借鉴意义。

首页 上一页 1 2 下一页 尾页 2/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇水晶报表在VC6中的简单使用方法 下一篇用VC开发基于ORACLE数据库方法

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: