OpenGL程序VC框架:Bezier 曲线

下面以画一条 Bezier 曲线为例,详细介绍VC++ 上 OpenGL编程的方法。文中给出了详细注释,以便给初学者明确的指引。一步一步地按所述去做,你将顺利地画出第一个 OpenGL 平台上的图形来。
  一、产生程序框架 Test.dsw
  New Project | MFC Application Wizard (EXE) | "Test" | OK
  *注* : 加“”者指要手工敲入的字串
  二、导入 Bezier 曲线类的文件
  用下面方法产生 BezierCurve.h BezierCurve.cpp 两个文件:
  WorkSpace | ClassView | Test Classes| <右击弹出> New Class | Generic Class(不用MFC类) | "CBezierCurve" | OK
  三、编辑好 Bezier 曲线类的定义与实现
  写好下面两个文件:
  BezierCurve.h BezierCurve.cpp
  四、设置编译环境:
  1. 在 BezierCurve.h 和 TestView.h 内各加上:
  #include <GL/gl.h>
  #include <GL/glu.h>
  #include <GL/glaux.h>
  2. 在集成环境中
  Project | Settings | Link | Object/library module | "opengl32.lib glu32.lib glaux.lib" | OK
  五、设置 OpenGL 工作环境:(下面各个操作,均针对 TestView.cpp )
  1. 处理 PreCreateWindow(): 设置 OpenGL 绘图窗口的风格
  cs.style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN | CS_OWNDC;
  2. 处理 OnCreate():创建 OpenGL 的绘图设备。
  OpenGL 绘图的机制是: 先用 OpenGL 的绘图上下文 Rendering Context (简称为 RC )把图画好,再把所绘结果通过 SwapBuffer() 函数传给 Window 的 绘图上下文 Device Context (简记为 DC).要注意的是,程序运行过程中,可以有多个 DC,但只能有一个 RC。因此当一个 DC 画完图后,要立即释放 RC,以便其它的 DC 也使用。在后面的代码中,将有详细注释。
  int CTestView::OnCreate(LPCREATESTRUCT lpCreateStruct)
  {
  if (CView::OnCreate(lpCreateStruct) == -1)
  return -1;
  myInitOpenGL();
  return 0;
  }
  void CTestView::myInitOpenGL()
  {
  m_pDC = new CClientDC(this); //创建 DC
  ASSERT(m_pDC != NULL);
  if (!mySetupPixelFormat()) //设定绘图的位图格式,函数下面列出
  return;
  m_hRC = wglCreateContext(m_pDC->m_hDC);//创建 RC
  wglMakeCurrent(m_pDC->m_hDC, m_hRC); //RC 与当前 DC 相关联
  } //CClient * m_pDC; HGLRC m_hRC; 是 CTestView 的成员变量
  BOOL CTestView::mySetupPixelFormat()
  {//我们暂时不管格式的具体内容是什么,以后熟悉了再改变格式
  static PIXELFORMATDESCRIPTOR pfd =
  {
  sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd
  1, // version number
  PFD_DRAW_TO_WINDOW | // support window
  PFD_SUPPORT_OPENGL | // support OpenGL
  PFD_DOUBLEBUFFER, // double buffered
  PFD_TYPE_RGBA, // RGBA type
  24, // 24-bit color depth
  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
  };
  int pixelformat;
  if ( (pixelformat = ChoosePixelFormat(m_pDC->m_hDC, &pfd)) == 0 )
  {
  MessageBox("ChoosePixelFormat failed");
  return FALSE;
  }
  if (SetPixelFormat(m_pDC->m_hDC, pixelformat, &pfd) == FALSE)
  {
  MessageBox("SetPixelFormat failed");
  return FALSE;
  }
  return TRUE;
  }
  3. 处理 OnDestroy()
  void CTestView::OnDestroy()
  {
  wglMakeCurrent(m_pDC->m_hDC,NULL); //释放与m_hDC 对应的 RC
  wglDeleteContext(m_hRC); //删除 RC
  if (m_pDC)
  delete m_pDC; //删除当前 View 拥有的 DC
  CView::OnDestroy();
  }
  4. 处理 OnEraseBkgnd()
  BOOL CTestView::OnEraseBkgnd(CDC* pDC)
  {
  // TODO: Add your message handler code here and/or call default
  // return CView::OnEraseBkgnd(pDC);
  //把这句话注释掉,若不然,Window
  //会用白色北景来刷新,导致画面闪烁
  return TRUE;//只要空返回即可。
  }
  5. 处理 OnDraw()
  void CTestView::OnDraw(CDC* pDC)
  {
  wglMakeCurrent(m_pDC->m_hDC,m_hRC);//使 RC 与当前 DC 相关联
  myDrawScene( ); //具体的绘图函数,在 RC 中绘制
  SwapBuffers(m_pDC->m_hDC);//把 RC 中所绘传到当前的 DC 上,从而
  //在屏幕上显示
  wglMakeCurrent(m_pDC->m_hDC,NULL);//释放 RC,以便其它 DC 进行绘图
  }
  void CTestView::myDrawScene( )
  {
  glClearColor(0.0f,0.0f,0.0f,1.0f);//设置背景颜色为黑色
  glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  glPushMatrix();
  glTranslated(0.0f,0.0f,-3.0f);//把物体沿(0,0,-1)方向平移
  //以便投影时可见。因为缺省的视点在(0,0,0),只有移开
  //物体才能可见。
  //本例是为了演示平面 Bezier 曲线的,只要作一个旋转
  //变换,可更清楚的看到其 3D 效果。
  //下面画一条 Bezier 曲线
  bezier_curve.myPolygon();//画Bezier曲线的控制多边形
  bezier_curve.myDraw(); //CBezierCurve bezier_curve
  //是 CTestView 的成员变量
  //具体的函数见附录
  glPopMatrix();
  glFlush(); //结束 RC 绘图
  return;
  }
  6. 处理 OnSize()
  void CTestView::OnSize(UINT nType, int cx, int cy)
  {
  CView::OnSize(nType, cx, cy);
  VERIFY(wglMakeCurrent(m_pDC->m_hDC,m_hRC));//确认RC与当前DC关联
  w=cx;
  h=cy;
  VERIFY(wglMakeCurrent(NULL,NULL));//确认DC释放RC
  }
  7 处理 OnLButtonDown()
  void CTestView::OnLButtonDown(UINT nFlags, CPoint point)
  {
  CView::OnLButtonDown(nFlags, point);
  if(bezier_curve.m_N>MAX-1)
  {
  MessageBox("顶点个数超过了最大数MAX=50");
  return;
  }
  //以下为坐标变换作准备
  GetClientRect(&m_ClientRect);//获取视口区域大小
  w=m_ClientRect.right-m_ClientRect.left;//视口宽度 w
  h=m_ClientRect.bottom-m_ClientRect.top;//视口高度 h
  //w,h 是CTestView的成员变量
  centerx=(m_ClientRect.left+m_ClientRect.right)/2;//中心位置,
  centery=(m_ClientRect.top+m_ClientRect.bottom)/2;//取之作原点
  //centerx,centery 是 CTestView 的成员变量
  GLdouble tmpx,tmpy;
  tmpx=scrx2glx(point.x);//屏幕上点坐标转化为OpenGL画图的规范坐标
  tmpy=scry2gly(point.y);
  bezier_curve.m_Vertex[bezier_curve.m_N].x=tmpx;//加一个顶点
  bezier_curve.m_Vertex[bezier_curve.m_N].y=tmpy;
  bezier_curve.m_N++;//顶点数加一
  InvalidateRect(NULL,TRUE);//发送刷新重绘消息
  }
  double CTestView::scrx2glx(int scrx)
  {
  return (double)(scrx-centerx)/double(h);
  }
  double CTestView::scry2gly(int scry)
  {
  }
  附录:
  1.CBezierCurve 的声明: (BezierCurve.h)
  class CBezierCurve
  {
  public:
  myPOINT2D m_Vertex[MAX];//控制顶点,以数组存储
  //myPOINT2D 是一个存二维点的结构
  //成员为Gldouble x,y
  int m_N; //控制顶点的个数
  public:
  CBezierCurve();
  virtual ~CBezierCurve();
  void bezier_generation(myPOINT2D P[MAX],int level);
  //算法的具体实现
  void myDraw();//画曲线函数
  void myPolygon(); //画控制多边形
  };
  2. CBezierCurve 的实现: (BezierCurve.cpp)
  CBezierCurve::CBezierCurve()
  {
  m_N=4;
  m_Vertex[0].x=-0.5f;
  m_Vertex[0].y=-0.5f;
  m_Vertex[1].x=-0.5f;
  m_Vertex[1].y=0.5f;
  m_Vertex[2].x=0.5f;
  m_Vertex[2].y=0.5f;
  m_Vertex[3].x=0.5f;
  m_Vertex[3].y=-0.5f;
  }
  CBezierCurve::~CBezierCurve()
  {
  }
  void CBezierCurve::myDraw()
  {
  bezier_generation(m_Vertex,LEVEL);
  }
  void CBezierCurve::bezier_generation(myPOINT2D P[MAX], int level)
  { //算法的具体描述,请参考相关书本
  int i,j;
  level--;
  if(level<0)return;
  if(level==0)
  {
  glColor3f(1.0f,1.0f,1.0f);
  glBegin(GL_LINES); //画出线段
  glVertex2d(P[0].x,P[0].y);
  glVertex2d(P[m_N-1].x,P[m_N-1].y);
  glEnd();//结束画线段
  return; //递归到了最底层,跳出递归
  }
  myPOINT2D Q[MAX],R[MAX];
  for(i=0;i {
  Q.x=P.x;
  Q.y=P.y;
  }
  for(i=1;i<m_N;i++)
  {
  R[m_N-i].x=Q[m_N-1].x;
  R[m_N-i].y=Q[m_N-1].y;
  for(j=m_N-1;j>=i;j--)
  {
  Q[j].x=(Q[j-1].x+Q[j].x)/double(2);
  Q[j].y=(Q[j-1].y+Q[j].y)/double(2);
  }
  }
  R[0].x=Q[m_N-1].x;
  R[0].y=Q[m_N-1].y;
  bezier_generation(Q,level);
  bezier_generation(R,level);
  }
  void CBezierCurve::myPolygon()
  {
  glBegin(GL_LINE_STRIP); //画出连线段
  glColor3f(0.2f,0.4f,0.4f);
  for(int i=0;i<m_N;i++)
  {
  glVertex2d(m_Vertex.x,m_Vertex.y);
  }
  glEnd();//结束画连线段
  }

相关文章:

非常夏日毕业设计  www.bysjdz.com  毕业设计毕业论文  论文定做免费论文  开题报告  文献综述  外文翻译  毕业设计定做  计算机毕业设计  计算机毕业论文 计算机外文翻译

找吧!毕业设计  www.zhaobysj.com毕业设计毕业论文论文定做免费论文 开题报告  文献综述 外文翻译  毕业设计定做  计算机毕业设计   计算机毕业论文 计算机外文翻译

转载于:https://www.cnblogs.com/hotsummer/archive/2010/12/24/1915818.html

OpenGL程序VC框架:Bezier 曲线相关推荐

  1. 第一个OpenGL程序

    OpenGL包含200多个函数,大致分为如下几类函数: 图元函数(primitive function)指定要生成屏幕图像的图元.包括两种类型:可在二维.三维或四维空间进行定义的几何图元,如多边形:离 ...

  2. 基于Win32框架的OpenGL程序

    本示例提供一个稳定的基于Win32的OpenGL程序框架结构,开发工具是Visual Studio 2010,编程之前应该确保OpenGL所使用的库函数都已被正确配置: 第一步,安装GLUT工具包: ...

  3. 计算机图形学(光栅显示系统、基于GLUT的OpenGL程序框架、基本图元光栅化)

    1.光栅显示系统 图形显示设备–CRT光栅扫描显示器(阴极射线管显示器) 电子束轰击屏幕表面的荧光物质,从而产生不同亮度的光点,这些光点是显示器可以控制的最小单位,称为像素.光点会逐渐变暗,需要不断刷 ...

  4. 3次Bezier曲线,曲面和3次B样条曲线和曲面

    问题: 昨天刚忙完图形学的编程作业,题目是自拟,听老师说他要重点考这个自由曲线,曲面,特地把作业定位了这个,好熟悉熟悉,据说成程老师的课考试非常的难呀.郁闷. 解答: 先自由曲线的含义和概念.基本上我 ...

  5. 实验10 Bezier曲线生成

    1.实验目的: 了解曲线的生成原理: 掌握几种常见的曲线生成算法,利用VC+OpenGL实现Bezier曲线生成算法. 2.实验内容: (1)结合示范代码了解曲线生成原理与算法实现,尤其是Bezier ...

  6. OpenGL---Windows下配置与第一个OpenGL程序

    下面记录一下Windows下配置OpenGL与我的第一个OpenGL程序. 第一步:选择一个编译环境    现在Windows系统的主流编译环境有Visual Studio,Broland C++ B ...

  7. 计算机图形学:Bezier曲线的绘制

    1.实验目的 掌握Bezier曲线的定义原理及绘制过程 定义: 贝塞尔曲线(Bezier curve),又称贝兹曲线或贝济埃曲线,是应用于二维图形应用程序的数学曲线.一般的矢量图形软件通过它来精确画出 ...

  8. java画bezier曲面_计算机图形学上机实验4-实现Bezier曲线和Bezier曲面的绘制

    <计算机图形学上机实验4-实现Bezier曲线和Bezier曲面的绘制>由会员分享,可在线阅读,更多相关<计算机图形学上机实验4-实现Bezier曲线和Bezier曲面的绘制(9页珍 ...

  9. 小程序二次贝塞尔曲线,购物车商品曲线飞入效果

    前段时间闲暇的时候看到一个贝塞尔曲线算法的文章,试着在小程序里去实现小程序的贝塞尔曲线算法,及其效果. 主要应用到的技术点: 1.小程序wxss布局,以及数据绑定 2.js二次bezier曲线算法 核 ...

最新文章

  1. DSP28335声音降噪(未完成)
  2. Wireshark初次使用
  3. 腾讯“死守”版权,网易云“再强”社区,各筑“孤峰”对战在线音乐下半场
  4. wxWidgets:创建一个 Frame
  5. 2008Beta 版AJAX的一个奇怪的问题
  6. c/c++整理--析构函数
  7. YoLo 实践(1)
  8. 项目管理---SVN,Subversion的安装,客户端和服务端
  9. 三维振镜原理_展商专访 | 先临三维与易加三维联合携多款精品及新品亮相2020年TCT亚洲展...
  10. 遇到事情不计较就是善待自己
  11. 将json转为map的两种方式及前后端开发json Api设计规范总结
  12. 几个常见的 Socket 连接错误及原因
  13. Visio 安装与操作小结
  14. SpringMVC入门简单静态资源处理
  15. 项目管理工具——Jira使用和配置
  16. base64和base32的区分方法
  17. 移动硬盘加密速度慢,取消;BitLocker加密不可逆;
  18. matlab求随机过程的数学期望,密度函数已知,怎么用matlab求其数学期望和方差?...
  19. 这个卷走175个国家和地区45亿英镑的“加密女王”忽然失踪,骗局崩盘
  20. Unity5.0 烘焙物体导入其他场景

热门文章

  1. 嵌入式开发五:未来之星机器人语音控制及视频开发(颜色追踪)(运动追踪)
  2. 这篇3万字的Java后端面试总结,面试官看了瑟瑟发抖(汇总)
  3. 计算机网络技术(五)——网络互联技术
  4. web.firewall.RequestRejectedException: The request was rejected because the URL contained a potentia
  5. 心脏出血漏洞(CVE-2014-0160)
  6. 喝不完的杯中酒,割不尽的名人头
  7. springmvc配置ssl_Spring Mvc和Spring Boot配置Tomcat支持Https
  8. PyQt 5.2 发布,此版本完全支持Qtv5.2.0
  9. Linux运维微信群,新闻|Linux 中国官方微信群开放加入
  10. 我所首席执行主任律师王杰接受《电脑报》记者采访就sp发展发表观点