初始化;
BOOL bSetupPixelFormat(HDC hdc)
{
PIXELFORMATDESCRIPTOR *ppfd; // pfd,
int pixelformat;
static PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR), //固定值
1, //固定值
PFD_DRAW_TO_WINDOW | // support window
PFD_SUPPORT_OPENGL | // support OpenGL
PFD_DOUBLEBUFFER,
16, //程序在16位色彩下运行
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
32, // 32-bit z-buffer
0, // no stencil buffer
0, // no auxiliary buffer
PFD_MAIN_PLANE, // main layer
0, // reserved
0, 0, 0 // layer masks ignored
};
ppfd = &pfd;
if ( (pixelformat = ChoosePixelFormat(hdc, ppfd)) == 0 ) //选择象素格式
{
MessageBox(NULL, "ChoosePixelFormat failed", "Error", MB_OK);
return FALSE;
}
if (SetPixelFormat(hdc, pixelformat, ppfd) == FALSE) //设置格式
{
MessageBox(NULL, "SetPixelFormat failed", "Error", MB_OK);
return FALSE;
}
return TRUE;
}
GLvoid TOpenGL_Form::initializeGL(GLsizei width, GLsizei height)
{
glClearIndex( (GLfloat)BLACK_INDEX); //
glClearColor(1.0,1.0,1.0,0);
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); //清空Buffer
glClearDepth( 1.0 ); //清空Buffer
/*OpenGL清除缓存操作过程是:先给出要写入每个缓存的清除值,然后用单个//函数命令执行操作,传入所有要清除的缓存表,若硬件能同时清除,则这些清除操作可以同时进行;否则,//各个操作依次进行。
//void glClearColor(GLclampf red,GLclampf green,GLclampf blue,GLclampf alpha);RGBA方式下的颜色//缓存
//void glClearIndex(GLfloat index);颜色表方式下的颜色缓存
//void glClearDepth(GLclampd depth); 颜色表方式下的深度缓存
//void glClearStencil(GLint s); 颜色表方式下的模板缓存
//void glClearAccum(GLflaot red,GLfloat green,GLfloat blue,GLfloat alpha); 颜色表方式下的累积缓//存
//void glClaear(Glbitfield mask);清除指定的缓存。参数mask可以是下面这些位逻辑的或
// GL_COLOR_BUFFER_BIT
// GL_DEPTH_BUFFER_BIT
// GL_STENCIL_BUFFER_BIT
// GL_ACCUM_BUFFER_BIT
*/
glEnable(GL_DEPTH_TEST); //使用 depth buffer
glMatrixMode( GL_PROJECTION ); //设置物体对象
/*-------------------------------------------------------------------------------------------------------------------------------
两个基本OpenGL矩阵操作函数:void glLoadMatrix{fd}(const TYPE *m)
设置当前矩阵中的元素值。函数参数*m是一个指向16个元素(m0,m1,...,m15)的指针,
这16个元素就是当前矩阵 M 中的元素,其排 列方式如下:
* *
* m0 m4 m8 m12 *
M =* m1 m5 m9 m13 *
* m2 m6 m10 m14 *
* m3 m7 m11 M15 *
* *
void glMultMatrix{fd}(const TYPE *m) 用当前矩阵去乘*m所指定的矩阵,并将结果存放于*m中。当前矩阵可以是用glLoadMatrix()指定的矩阵,也可以是其它矩阵变换函数的综合结果。
*************************几何变换**************************************************************
平移变换函数如下:void glTranslate{fd}(TYPE x,TYPE y,TYPE z)
旋转变换函数如下:void glRotate{fd}(TYPE angle,TYPE x,TYPE y,TYPE z)
缩放和反射变换函数如下:void glScale{fd}(TYPE x,TYPE y,TYPE z)
*************************投影变换**************************************************************
在进行投影变化前,必须加上下面两个函数glMAtrixMode(GL_PROJECTION);glLoadIdentity();
正射投影函数共有两个,一个函数是:void glOrtho(GLdouble left,GLdouble right,GLdouble bottom,GLdouble top,GLdouble near,GLdouble far);另一个函数是:void gluOrtho2D(GLdouble left,GLdouble right,GLdouble bottom,GLdouble top)
透视投影函数共有两个,一个函数是:void glFrustum(GLdouble left,GLdouble Right,GLdouble bottom,GLdouble top,GLdouble near,GLdouble far);另一个函数是:void gluPerspective(GLdouble fovy,GLdouble aspect,GLdouble zNear,GLdouble zFar);
*************************裁切变换**************************************************************
在OpenGL中,空间物体的三维裁剪变换包括两个部分:视景体裁剪和附加平面裁剪。视景体裁剪已经包含在投影变换里;附加平面裁剪函数为:void glClipPlane(GLenum plane,Const GLdouble *equation);在调用附加裁剪函数之前,必须先启动glEnable(GL_CLIP_PLANEi),使得当前所定义的裁剪平面有效;当不再调用某个附加裁剪平面时,可用glDisable(GL_CLIP_PLANEi)关闭相应的附加裁剪功能。
*************************视角变换**************************************************************
OpenGL中相关函数是:glViewport(GLint x,GLint y,GLsizei width, GLsizei height);
*************************矩阵堆栈的操作********************************************************
堆栈操作函数有以下两个:void glPushMatrix(void);void glPopMatrix(void);
-------------------------------------------------------------------------------------------------------------------------------------------*/
}
void __fastcall TOpenGL_Form::FormCreate(TObject *Sender)
{
ghDC = GetDC(Panel1->Handle); //获取一个DC
if (!bSetupPixelFormat(ghDC)) //设置DC的象素格式
Close();
ghRC = wglCreateContext(ghDC); //建立一个着色环境RC
wglMakeCurrent(ghDC, ghRC); //将建立的RC激活
initializeGL(Panel1->Width, Panel1->Height); //初始化OpenGL
}
//自适应缩放及设定曲线类型
GLvoid TOpenGL_Form::resize( GLsizei width, GLsizei height )
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, width, 0.0,height); //正射投影 设定图形为二维的图形
glMatrixMode(GL_MODELVIEW);
}
void __fastcall TOpenGL_Form::FormResize(TObject *Sender)
{
resize(Panel1->Width, Panel1->Height);
}
//openGL的释放
void __fastcall TOpenGL_Form::FormClose(TObject *Sender, TCloseAction &Action)
{
Timer1->Enabled = false;
if (ghRC)
wglDeleteContext(ghRC);
if (ghDC)
ReleaseDC(Panel1->Handle, ghDC);
}
其它画图过程;
void line2i(GLint x1,GLint y1,GLint x2,GLint y2)
{
glBegin(GL_LINES);
glVertex2f(x1,y1);
glVertex2f(x2,y2);
glEnd();
}
//画直线
void TOpenGL_Form::DrawPoint(TPoint pointsA,TPoint pointsB)
{
glLoadIdentity();
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); //清空Buffer
glPushMatrix();
glColor3f(0.059f,0.035f,0.97f);
line2i (pointsA.x , pointsA.y , pointsB.x ,pointsB.y);
glPopMatrix();
glFlush();
SwapBuffers(ghDC); //输出到当前DC上
}
//其他一下简单操作
//---------------------------------------------------------------------------
void __fastcall TOpenGL_Form::btdarwframClick(TObject *Sender)
{
int w=Panel1->Width,h=Panel1->Height;
glLoadIdentity();
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); //清空Buffer
glPushMatrix();
glColor3f(0.059f,0.035f,0.97f); //设定当前的颜色,rgb[值为:色素/255]
glLineWidth(5); //设定当前曲线的大小
glBegin(GL_LINE_LOOP);
glVertex2f(10,10);
glVertex2f(10,h-10);
glVertex2f(w-10,h-10);
glVertex2f(w-10,10);
glEnd();
glLineWidth(1);
//画一根红的中线
glColor3f(1,0,0); //设定当前的颜色,rgb[值为:色素/255]
glBegin(GL_LINES);
glVertex2f(10,h/2);
glVertex2f(w-10,h/2);
glEnd();
SwapBuffers(ghDC); //输出到当前DC上
//画一根虚线
glColor3f(1,0,0); //设定当前的颜色,rgb[值为:色素/255]
glEnable(GL_LINE_STIPPLE); //启动虚线模式
glLineStipple (5, 0xAAAA); //void glLineStipple(GLint factor, GLushort pattern);该函数设置当前点的划线方式。factor表示连续画线的次数,范围为1~255,pattern是由0和1组成的16进制数,当位值为1时绘制直线,为0时不绘制直线,例如:0000111100001111的16进制为0x0F0F,表示绘制的是一条短线段,即我们说的破折线。
glLineWidth(2);
glBegin(GL_LINES);
glVertex2f(w/2,10);
glVertex2f(w/2,h-10);
glEnd();
glLineWidth(1);
SwapBuffers(ghDC); //输出到当前DC上
glDisable(GL_LINE_STIPPLE); //关闭虚线模式
glPopMatrix();
glFlush();
Yield();
}
//画大量的数据集
void TOpenGL_Form::SetPicToCanVas(HDC ghDC,int gDCw,int gDCh,TCanvas *DescCanvas)
{
//把当前的图形抓下来进行对画图对象重绘这样子就不用担心图像丢失
#ifdef _DEBUG
Graphics::TBitmap*bmp=new Graphics::TBitmap;
bmp->Width= gDCw;
bmp->Height=gDCh;
TCanvas *DeskCanvas = new TCanvas();
DeskCanvas->Handle =ghDC;
BitBlt(bmp->Canvas->Handle,0,0,gDCw,gDCh,ghDC, 0,0,SRCCOPY);
bmp->SaveToFile("d://ghDC.bmp");
DescCanvas->Draw(0,0,bmp);
delete bmp;
delete DeskCanvas;
#else
BitBlt(DescCanvas->Handle,0,0,gDCw,gDCh,ghDC, 0,0,SRCCOPY);
#endif
}
void __fastcall TOpenGL_Form::bttestClick(TObject *Sender)
{
AnsiString str;
int w,h,h2;
TPoint ptA,ptB;
double tmp=0;
w=Panel1->Width;
h=Panel1->Height;
if (opendlg->Execute())
{
WORD dt=GetTickCount(),dt2;
int fhwnd,iFileLength;
AnsiString filename=opendlg->FileName;
fhwnd=FileOpen(filename,fmOpenRead);
double *tmprc=NULL;
int N;
try
{
iFileLength = FileSeek(fhwnd,0,2);
FileSeek(fhwnd,0,0);
N=(iFileLength+1)/sizeof(double);
tmprc =new double[N+1];
FileRead(fhwnd,tmprc,sizeof(double)*N);
}
__finally
{
FileClose(fhwnd);
fhwnd=0;
}
//读取一个均值
for (int i=0;i<N;i++)
tmp+=tmprc[i];
tmp/=N;
ptA.x=0;
ptA.y=h/2;
glLoadIdentity();
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); //清空Buffer
glPushMatrix();
glColor3f(0.059f,0.035f,0.97f);
//开始绘图
for (int i=0;i<N/4000;i++) //每4000个数重新的更换画布
{
for (int j=0;j<4000;j++)
{
ptB.x=(i*4000+j)*w/N;
ptB.y=h*tmprc[i*4000+j]/tmp/2.0;
line2i (ptA.x , ptA.y , ptB.x ,ptB.y);
ptA=ptB;
}
SwapBuffers(ghDC); //输出到当前DC上
}
glPopMatrix();
glFlush();
Yield();
dt2=GetTickCount();
str="run Time="+IntToStr(dt2-dt)+"ms";
TextOut(ghDC, 0, 0, str.c_str(), str.Length()); //绘图花费时间输出
//把当前的图形抓下来进行对画图对象重绘这样子就不用担心图像丢失
SetPicToCanVas(ghDC,Panel1->Width,Panel1->Height,Image1->Canvas);
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
附部分gl库
opengl函数
gl 库:
1.glClear(GLbitfield mask);
功能;用预先设置的值清除缓冲区。
参数说明;mask指定 被刷新的缓冲区,可以是GL_COLOR_BUFFER_BIT. GL_DEPTH_BUFFER_BIT ,GL_ACCUM_BUFFER_BIT, GL_STENCIL_BUFFER_BIT
GL_COLOR_BUFFER_BIT.表示颜色缓冲区
GL_DEPTH_BUFFER_BIT ,表示深度缓冲区
GL_ACCUM_BUFFER_BIT,表示累积缓冲区
GL_STENCIL_BUFFER_BIT表示模板缓冲区
2.glClearColor(GLelamof red,GLelamof green,Glelamof blue, Glelampf alpha);
功能;指定颜色缓冲区的清除值
参数说明; 初始值0,取值范围[0,1]
3.glClearDepth();
功能;指定深度缓冲区的清除值
参数说明; 初始值0,取值范围[0,1]
4.glClearIndex();
功能;指定颜色索引缓冲区的清除值
参数说明; 初始值0,取值范围[功能;指定颜色缓冲区的清除值
参数说明; 初始值0,取值范围[0,1]0,1]
5.glClearAccum();
功能;用于设置累积缓冲区的清除值
参数说明; 初始值0,取值范围[0,1]
6.glClearStencil();
功能;设置模板缓冲区的清除值
参数说明; 初始值0,取值范围[0,1]
7.glColor3{b,d,f,s,i,ub,ui,us}();
功能;设置当前的绘图颜色
参数说明; 取值范围[0.0,1.1]
8.glColor4();
功能;设置当前的绘图颜色
参数说明; 取值范围[0.0,1.1]
9.glFinish(void);
功能;在有限时间内强制执行opengl命令
消隐
在三维空间中,一些物体遮挡另一个物体是很自然的事,而且这种遮挡关系随视点的不同而不同,清除一个物体被其他物体挡住的部分 的操作称为消隐;
10.3.glClearDepth(GLelampd depth);
功能;指定深度缓冲区的清除值
参数说明;depth指定清除缓冲区时用的深度值。初始值1,也就是刷新深度buffer后,深度buffer为窗口中每一个像素点设置的深度值。
进行消隐时启用深度测试,11.glEnable(GL.GL_DEPTH_TEST);
12.glDepthFunc(GLenum func);
功能;指定用于深度缓冲比较值。
参数说明;func指定深度比较函数,GL_NEVER,GL_LESS,GL_EQUAL,GL_LEQUAL,GL_GREATER,GL_NOTE_QUAL,GL_GEQUAL,GL_ALWAYS,缺省值GL_LESS,
GL_NEVER,不通过(输入的深度值不取代参考值)
GL_LESS,如果输入的深度值小于参考值,则通过
GL_EQUAL,如果输入的深度值等于参考值,则通过
GL_LEQUAL,如果输入的深度值小于或等于参考值,则通过
GL_GREATER,如果输入的深度值大于参考值,则通过
GL_NOTE_QUAL,如果输入的深度值不等于参考值,则通过
GL_GEQUAL,如果输入的深度值大于或等于参考值,则通过
GL_ALWAYS,总是通过(输入的深度值取代参考值)
构造图形
13.glBegin(GLenum mode)
参数说明;mode
GL_POINT 单个点
GL_LINES线
GL_LINE_STRIP 折线
GL_LINE_LOOP 闭合线
GL_TRIANGLES 多个三角形
GL_TRIANGLES 相连的三角形
GL_TRIANGLE_FAN 三角形扇
GL_QUADS 多个四边形
GL_QUADS_STRIP 相连的四边形
GL_POLYGON 凸多边形
glVertex 设置定点坐标
glColor 设置当前颜色
glIndex 设置当前调色板索引
glNormal 设置当前法线向量
glEvalCoord 生成一维或二维坐标
glCallList,glCallLists 执行显示列表
glTexCoord 设置纹理坐标
glEdgeFlag 标志边缘是否为边界
glMaterial 设置材质属性
14.glEnd();
15. glPointSize(GLfloat size)
功能;指定光栅化的点的直径
初始值;1;
启用反走样glEnable(GL_POINT_SMOOTH);
关闭glEnable(GL_POINT_SMOOTH);
16.glLineWidth(GLfloat width)
功能;指定光栅化线的宽度
初始值为1;
启用反走样glEnable(GL_LINE_SMOOTH);/
关闭glDisable(GL_LINE_SMOOTH);
20.glLineStipple(GLint factor,GLshort pattern);
功能;指定线的点画绘制模板
参数说明;factor 指定点画绘制模板中每个二进制位的重复次数 范围[1,256] 默认1;pattern 一个16位整数
21. glRect()
功能;绘制一个矩形
22. glPolygonMode(GLenum face,GLenum mode);
功能;指定多边形正面或反面的绘图模式
参数说明;face GL_FRONT正面,GL_BACK反面,GL_FRONT_AND_BACK正反面
mode 绘图模式 GL_POINT点 ,GL_LINE线段, GL_FILL填充
23.glFrontFace(GLenum mode)
功能;
指定多边形的正面;
参数说明;GL_CCW相当于投影到窗口坐标系的多边形的有序顶点,按逆时针方向出现的为多边型的正面。
,GL_CW,指定所绘制的多边形的顶点按顺时针方向的面是多边型的正面
缺省值GL_CCW
24.glCullFace(Glenum mode);
功能;指定被拣选的多边形的面。
参数说明;mode GL_FRONT GL_BACK GL_FRONT_AND_BACK ,却省值是GL_BACK.
开启拣选操作glEnable(GL_CULL_FACE);/
关闭glDisable(GL_CULL_FACE);
25.glPolygonStipple();
功能;设置多边型的点画绘制方法
开启多边型的点画绘图模式启glEnable(GL_POLYGON_STIPPLE)
关闭glDisable(GL_POLYGON_STIP_PLE)
26.glEdgeFlag(boolean);
功能;指定某边是被当作边界还是当作非边界
1、void glEnable(GL_LINE_STIPPLE); 是启动虚线模式,使用glDisable(GL_LINE_STIPPLE) 该模式,在以后它的应用是经常性的,至于可以用哪些模式,通过http://www.google.cn可以搜索到很多的。
2、void glLineStipple(GLint factor, GLushort pattern);该函数设置当前点的划线方式。factor表示连续画线的次数,范围为1~255,pattern是由0和1组成的16进制数,当位值为1时绘制直线,为0时不绘制直线,例如:0000111100001111的16进制为0x0F0F,表示绘制的是一条短线段,即我们说的破折线。
3、void glLineWidth(GLfloat width);表示划线宽度的函数。