软件频道>程序开发>JavaVBVCDelphiC/C++Web开发微软专栏移动数据库程序人生软件工程|开发客
您现在的位置: 天极网 > 开发频道 > opengl非全屏绘图的简单使用总结
全文

opengl非全屏绘图的简单使用总结

2008-04-09 15:17作者:MEFULEU的专栏出处:天极网责任编辑:孙蓬阳

  OpenGL是个专业的3D程序接口,是一个功能强大,调用方便的底层3D图形库。OpenGL的前身是SGI公司为其图形工作站开发的IRIS GL。

     初始化;

 

以下是引用片段:
 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
  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
  {
  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位整数

  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);表示划线宽度的函数。

原文连接:http://blog.csdn.net/mefuleu/archive/2008/04/08/2260275.aspx

相关搜索:
关注此文读者还看过
文章排行
本周
本月
最近更新
关于我们|About us|网站律师|天极服务|电子杂志|RSS订阅|加入我们|网站地图
TMG
Copyright (C) 1999-2009 Chinabyte.com, All Rights Reserved 版权所有 天极网络
商务联系、网站内容、合作建议:010-82657868
版权声明 在线提交意见反馈 渝ICP证B2-20030003号
经营性网站备案信息 网警备案 中国网站排名
天极传媒:天极网|比特网|IT专家网|IT商网|52PK游戏网|IT分众