以Microsoft Visual Studio为开发工具,基于Open GL图形库开发三维可视化的地学信息系统是比较快捷的方式。以下通过Microsoft Visual C++2010建立基于Open GL图形库的单文档应用程序框架为例,实现了一个简单的三维可视化系统。
1.使用MFCApp Wizard建立单文档的应用程序框架,并加入Open GL图形库
用MFC App Wizard创建一个单文档的MFC EXE项目,工程名称假设为“Ex Open GL”, Application Type选择“Single Document”,Project Style选择“MFC Standard”。如图7-4所示,在工程属性设置中的“Additional Dependencies”中添加“opengl32.lib;glaux.lib;glu32. lib”等Open GL图形库。
并在视图类的Ex Open GLView.h中增加Open GL图形库的文件包含:
#pragma once
#include<GL\GL.h>
#include<GL\GLU.h>
#include<GL\GLaux.h>
class CEx Open GLView:public CView
{
……
};
给工程添加一个位图资源IDB_BITMAP_SHOW对应某个图片,用于本例中的纹理贴图。
2.通过Class Wizard给视图类添加成员变量及成员函数,并增加WM_CREA-TE、WM_SIZE、WM_ERAZEBKGND、WM_KEYDOWN、WM_DESTROY等消息响应函数
Ex Open GLView.h的主要程序代码内容如下:
class CEx Open GLView:public CView
{
……
图7-4 应用程序框架设置中添加Open GL图形库
public:
void initialize RC();//初始化Open GL Render Context
void destroy RC();//删除Open GL Render Context
void display Scene();//渲染场景
//读资源位图
BYTE*glt Resource BMPBits(UINT n Resource,int*n Width,int*n Height);
void load Texture Image();//导入纹理图片
public:
CClient DC*m_p DC;//DC
HGLRC m_RC;//Open GL RC
//相机参数:眼睛位置,视点,向上方向
double m_eye Position[3],m_eye Center[3],m_eye Updirection[3];
int m_viewport[4];//视口参数(xloc,yloc,width,height)
};
Ex Open GLView.cpp中的成员函数代码主要如下:
#include"Resource.h"
#include<math.h>
#define PI 3.1415926
//读资源位图
BYTE*CEx Open GLView::glt Resource BMPBits(UINT n Resource,int*n Width,int*n Height)
{
HINSTANCE h Instance;//Instance Handle
HANDLE h Bitmap;//Handle to bitmap resource
BITMAPINFO bm Info;
BYTE*p Data;
//Find the bitmap resource
h Instance=Get Module Handle(NULL);
h Bitmap=Load Bitmap(h Instance,MAKEINTRESOURCE(n Resource));
if(h Bitmap==NULL)
return NULL;
Get Object(h Bitmap,sizeof(BITMAPINFO),&bm Info);
Delete Object(h Bitmap);
h Bitmap=Load Resource(h Instance,
Find Resource(h Instance,MAKEINTRESOURCE(n Resource),RT_BITMAP));
if(h Bitmap==NULL)
return NULL;
p Data=(BYTE*)Lock Resource(h Bitmap);
p Data+=sizeof(BITMAPINFO)1;
*n Width=bm Info.bmi Header.bi Width;//bm.bm Width;
*n Height=bm Info.bmi Header.bi Height;//bm.bm Height;
return p Data;
}
//导入纹理图片
void CEx Open GLView::load Texture Image()
{
BYTE*p Bytes;
int n Width,n Height;
p Bytes=glt Resource BMPBits(IDB_BITMAP_SHOW,&n Width,&n Height);
gl Tex Envi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_DECAL);
gl Tex Parameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
gl Tex Parameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
gl Tex Parameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
gl Tex Parameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
gl Tex Image2D(GL_TEXTURE_2D,0,GL_RGB8,n Width,n Height,0,
GL_BGR_EXT,GL_UNSIGNED_BYTE,p Bytes);
}
//初始化RC
void CEx Open GLView::initialize RC()
{
HDC hdc=m_p DC >Get Safe Hdc();
//初始化像素格式
PIXELFORMATDESCRIPTOR pfd={
sizeof(PIXELFORMATDESCRIPTOR), //pfd结构的大小
1, //版本号
PFD_DRAW_TO_WINDOW| //支持在窗口中绘图
PFD_SUPPORT_OPENGL| //支持Open GL
PFD_DOUBLEBUFFER, //双缓存模式
PFD_TYPE_RGBA, //RGBA颜色模式
24, //24位颜色深度
0,0,0,0,0,0, //忽略颜色位
0, //没有非透明度缓存
0, //忽略Alpha偏移位
0, //无累加缓存
0,0,0,0, //忽略累加位
32, //32位深度缓存
0, //无模板缓存
0, //无辅助缓存
PFD_MAIN_PLANE, //主层
0, //保留
0,0,0 //忽略层,可见性和损毁掩模
};
int pixelformat=::Choose Pixel Format(hdc,&pfd);//选择像素格式
BOOL rt=Set Pixel Format(hdc,pixelformat,&pfd);
m_RC=wgl Create Context(hdc);//创建RC
wgl Make Current(hdc,m_RC);//关联DC与RC
}
//删除RC
void CEx Open GLView::destroy RC()
{
wgl Make Current(NULL,NULL);
if(m_RC)
{
wgl Delete Context(m_RC);
m_RC=NULL;
}
}
//绘制场景
void CEx Open GLView::display Scene()
{
gl Clear Color(1.0f,1.0f,1.0f,1.0f);//背景为白色
gl Clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
gl Draw Buffer(GL_BACK);
gl Enable(GL_COLOR_MATERIAL);
gl Enable(GL_DITHER);
gl Shade Model(GL_SMOOTH);
gl Enable(GL_DEPTH_TEST);//深度测试
gl Front Face(GL_CW);
gl Polygon Mode(GL_FRONT_AND_BACK,GL_FILL);
gl Viewport(m_viewport[0],m_viewport[1],m_viewport[2],m_viewport[3]);
gl Matrix Mode(GL_PROJECTION);
gl Load Identity();
int w=m_viewport[2],h=m_viewport[3];
if(w==0) w=1;
if(h==0) h=1;
glu Perspective(45.0,(double)w/(double)h,0.01,1000.0);
gl Matrix Mode(GL_MODELVIEW);
gl Load Identity();
wgl Use Font Bitmaps(wgl Get Current DC(),0,256,1000);
gl List Base(1000);
gl Color3ub(255,0,0);
gl Raster Pos3f(20.0f,35.0f,100.0f);//文字的三维位置
char info[]="Three dimensional visualization by Open GL.";
gl Call Lists(strlen(info),GL_UNSIGNED_BYTE,info);
glu Look At(m_eye Position[0],m_eye Position[1],m_eye Position[2],
m_eye Center[0],m_eye Center[1],m_eye Center[2],
m_eye Updirection[0],m_eye Updirection[1],m_eye Updirection[2]);
//绘制一个红色的平面
gl Push Matrix();//压入堆栈
gl Begin(GL_POLYGON);
gl Color3ub(255,0,0);
gl Vertex3d(1.0,1.0,1.0);
gl Vertex3d(1.0, 1.0,1.0);
gl Vertex3d(1.0, 1.0, 1.0);
gl Vertex3d(1.0,1.0,1.0);
gl End();
gl Pop Matrix();//弹出堆栈
//绘制一个绿色的半透明平面
gl Blend Func(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
gl Enable(GL_BLEND);
gl Push Matrix();//压入堆栈
gl Color4ub(0,255,0,125);//最后一个分量alpha表示透明度
gl Begin(GL_POLYGON);
gl Vertex3d(1.0, 1.0,1.0);
gl Vertex3d(1.0,1.0,1.0);
gl Vertex3d(1.0,1.0, 1.0);
gl Vertex3d(1.0, 1.0, 1.0);
gl End();
gl Pop Matrix();//弹出堆栈
gl Disable(GL_BLEND);
//绘制一个带纹理的平面
gl Enable(GL_TEXTURE_2D);
gl Push Matrix();//压入堆栈
gl Begin(GL_POLYGON);
gl Tex Coord2f(0.0,0.0);
gl Vertex3d(2.0, 2.0,0.0);
gl Tex Coord2f(1.0,0.0);
gl Vertex3d(2.0,2.0,0.0);
gl Tex Coord2f(1.0,1.0);
gl Vertex3d(2.0,2.0, 0.0);
gl Tex Coord2f(0.0,1.0);
gl Vertex3d(2.0, 2.0, 0.0);
gl End();
gl Pop Matrix();//弹出堆栈
gl Disable(GL_TEXTURE_2D);
//绘制一个茶壶
gl Push Matrix();//压入堆栈
gl Translatef(0.0,0.0,2.0);
gl Rotatef(90.0,1.0,0.0,0.0);
gl Color3ub(0,0,255);
aux Solid Teapot(0.5);
gl Pop Matrix();//弹出堆栈
//绘制文字
wgl Use Font Bitmaps(wgl Get Current DC(),0,256,1000);
gl List Base(1000);
gl Raster Pos3f(1.0f,1.0f,1.0f);//文字的三维位置
gl Call Lists(34,GL_UNSIGNED_BYTE,"This is an example of Open GL text.");
gl Flush();//执行
Swap Buffers(m_p DC >Get Safe Hdc());//把后台的绘制交换到前台显示
}
//CEx Open GLView消息处理程序
int CEx Open GLView::On Create(LPCREATESTRUCT lp Create Struct)
{
if(CView::On Create(lp Create Struct)==1)
return 1;
m_p DC=new CClient DC(this);
if(!m_p DC)return 0;
initialize RC();//初始化RC
load Texture Image();//导入纹理图片,以进行纹理贴图
//初始化其他参数
m_eye Position[0]=8.0, m_eye Position[1]=0.0, m_eye Position[2]=4.0;
m_eye Center[0]=0.0, m_eye Center[1]=0.0, m_eye Center[2]=0.0;
m_eye Updirection[0]=0.0,m_eye Updirection[1]=0.0,m_eye Updirection[2]=1.0;
m_viewport[0]=0,m_viewport[1]=0,m_viewport[2]=100,m_viewport[3]=100;
return 0;
}
void CEx Open GLView::On Destroy()
{
CView::On Destroy();
destroy RC();//删除RC
if(m_p DC)delete m_p DC;
}
BOOL CEx Open GLView::On Erase Bkgnd(CDC*p DC)
{
return TRUE;
}
void CEx Open GLView::On Size(UINT n Type,int cx,int cy)
{
CView::On Size(n Type,cx,cy);
m_viewport[2]=cx,m_viewport[3]=cy;
}
//CEx Open GLView绘制
void CEx Open GLView::On Draw(CDC*/*p DC*/)
{
CEx Open GLDoc*p Doc=Get Document();
ASSERT_VALID(p Doc);
if(!p Doc)
return;
display Scene();//绘制三维场景
}
void CEx Open GLView::On Key Down(UINT n Char,UINT n Rep Cnt,UINT n Flags)
{
switch(n Char)
{
case VK_LEFT://按下左箭头,视图向左旋转10度
{
double d Sin=sin(10.0*PI/180.0),d Cos=cos(10.0*PI/180.0);
double d E[3]={(m_eye Position[0]m_eye Center[0]),
(m_eye Position[1]m_eye Center[1]),
(m_eye Position[2]m_eye Center[2])};
m_eye Position[0]=m_eye Center[0]+(d E[0]*d Cos+d E[1]*d Sin);
m_eye Position[1]=m_eye Center[1]+(d E[0]*d Sin+d E[1]*d Cos);
Invalidate(FALSE);
}
break;
case VK_RIGHT://按下右箭头,视图向右旋转10度
{
double d Sin=sin(10.0*PI/180.0),d Cos=cos(10.0*PI/180.0);
double d E[3]={(m_eye Position[0]m_eye Center[0]),
(m_eye Position[1]m_eye Center[1]),
(m_eye Position[2]m_eye Center[2])};
m_eye Position[0]=m_eye Center[0]+(d E[0]*d Cos+d E[1]*d Sin);
m_eye Position[1]=m_eye Center[1]+(d E[0]*d Sin+d E[1]*d Cos);
Invalidate(FALSE);
}
break;
default:;
}
CView::On Key Down(n Char,n Rep Cnt,n Flags);
}
其可视化效果如图7-5所示。该例子演示了Open GL基本的几何图形、文字等绘制以及纹理贴图、视图旋转操作等。
图7-5 基于Open GL的三维可视化图形系统示例
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。