++實(shí)例程序
以Microsoft Visual Studio為開發(fā)工具,基于Open GL圖形庫開發(fā)三維可視化的地學(xué)信息系統(tǒng)是比較快捷的方式。以下通過Microsoft Visual C++2010建立基于Open GL圖形庫的單文檔應(yīng)用程序框架為例,實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的三維可視化系統(tǒng)。
1.使用MFCApp Wizard建立單文檔的應(yīng)用程序框架,并加入Open GL圖形庫
用MFC App Wizard創(chuàng)建一個(gè)單文檔的MFC EXE項(xiàng)目,工程名稱假設(shè)為“Ex Open GL”, Application Type選擇“Single Document”,Project Style選擇“MFC Standard”。如圖7-4所示,在工程屬性設(shè)置中的“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
{
……
};
給工程添加一個(gè)位圖資源IDB_BITMAP_SHOW對(duì)應(yīng)某個(gè)圖片,用于本例中的紋理貼圖。
2.通過Class Wizard給視圖類添加成員變量及成員函數(shù),并增加WM_CREA-TE、WM_SIZE、WM_ERAZEBKGND、WM_KEYDOWN、WM_DESTROY等消息響應(yīng)函數(shù)
Ex Open GLView.h的主要程序代碼內(nèi)容如下:
class CEx Open GLView:public CView
{
……
圖7-4 應(yīng)用程序框架設(shè)置中添加Open GL圖形庫
public:
void initialize RC();//初始化Open GL Render Context
void destroy RC();//刪除Open GL Render Context
void display Scene();//渲染場(chǎng)景
//讀資源位圖
BYTE*glt Resource BMPBits(UINT n Resource,int*n Width,int*n Height);
void load Texture Image();//導(dǎo)入紋理圖片
public:
CClient DC*m_p DC;//DC
HGLRC m_RC;//Open GL RC
//相機(jī)參數(shù):眼睛位置,視點(diǎn),向上方向
double m_eye Position[3],m_eye Center[3],m_eye Updirection[3];
int m_viewport[4];//視口參數(shù)(xloc,yloc,width,height)
};
Ex Open GLView.cpp中的成員函數(shù)代碼主要如下:
#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;
}
//導(dǎo)入紋理圖片
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_M(jìn)ODE,GL_DECAL);
gl Tex Parameteri(GL_TEXTURE_2D,GL_TEXTURE_M(jìn)IN_FILTER,GL_LINEAR);
gl Tex Parameteri(GL_TEXTURE_2D,GL_TEXTURE_M(jìn)AG_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結(jié)構(gòu)的大小
1, //版本號(hào)
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_M(jìn)AIN_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);//創(chuàng)建RC
wgl Make Current(hdc,m_RC);//關(guān)聯(lián)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;
}
}
//繪制場(chǎng)景
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_M(jìn)ATERIAL);
gl Enable(GL_DITHER);
gl Shade Model(GL_SMOOTH);
gl Enable(GL_DEPTH_TEST);//深度測(cè)試
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_M(jìn)ODELVIEW);
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]);
//繪制一個(gè)紅色的平面
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();//彈出堆棧
//繪制一個(gè)綠色的半透明平面
gl Blend Func(GL_SRC_ALPHA,GL_ONE_M(jìn)INUS_SRC_ALPHA);
gl Enable(GL_BLEND);
gl Push Matrix();//壓入堆棧
gl Color4ub(0,255,0,125);//最后一個(gè)分量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);
//繪制一個(gè)帶紋理的平面
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);
//繪制一個(gè)茶壺
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();//執(zhí)行
Swap Buffers(m_p DC >Get Safe Hdc());//把后臺(tái)的繪制交換到前臺(tái)顯示
}
//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();//導(dǎo)入紋理圖片,以進(jìn)行紋理貼圖
//初始化其他參數(shù)
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();//繪制三維場(chǎng)景
}
void CEx Open GLView::On Key Down(UINT n Char,UINT n Rep Cnt,UINT n Flags)
{
switch(n Char)
{
case VK_LEFT://按下左箭頭,視圖向左旋轉(zhuǎn)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://按下右箭頭,視圖向右旋轉(zhuǎn)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基本的幾何圖形、文字等繪制以及紋理貼圖、視圖旋轉(zhuǎn)操作等。
圖7-5 基于Open GL的三維可視化圖形系統(tǒng)示例
免責(zé)聲明:以上內(nèi)容源自網(wǎng)絡(luò),版權(quán)歸原作者所有,如有侵犯您的原創(chuàng)版權(quán)請(qǐng)告知,我們將盡快刪除相關(guān)內(nèi)容。