作者:太乙散数

摘要:用一个简单的例子,阐述了bcb中使用opengl的简单方法,包括初始化框架、旋转和平移图形、清除图像、初始化背景色以及在刷新时保持图像。

关键词:bcb6 opengl 旋转 清除 平移

到今天,终于把bcb6中应用Opengl的基本流程等弄清楚了,想想学之费时费力,特总结出来让后来者方便!

网上有很多Opengl应用的书和帖子,我也从中吸取了很多经验,但总感觉这些书和帖子没有把新手最想知道的最基础的东西讲明白。

为了浅显易懂,以一个例子来讲整个流程。首先创建一个新的Form(Form1 在后面的代码中我是这么定义的),然后在上面放置一个panel(Panel1)和 7个Button(具体见图1)。其中,Button1是绘图按钮,button2是清除按钮,button3是平移图像按钮,button4~7分别左旋、右旋、上旋、下旋按钮(担心图片不能上传,故唠叨几句)。这个例子的功能就是:在panel1上用opengl绘图,然后用7个button操作图形。下面是截图:

下面介绍具体的操作流程:

1)设置opengl的绘图环境。在bcb6中,只需在头文件中加入#include <GL/gl.h>、#include <GL/glu.h>两个命令即可。

2)设置hDC,即绘图区的句柄或指针,目的使程序知道你想在那

那个区域绘画。首先需要在头文件中声明HDC hDC,然后在TForm(Owner)函数下面初始化,本文的绘图区为Panel,所以hDC= hDC=GetDC(Form1->Panel1->Handle); 接着要对hDC的像素格式进行设置,SetDCPixelFormat(hDC),其实初学者大可不理会这个函数。

3) 设置RC(Rendering Context),老妖翻译为“图像操作描述表”,很晦涩。我认为就是与Opengl的绘图功能连接的一个通道,建议翻译为“背景通道”。首先要在头文件中声明HGLRC hRC;然后在TForm(Owner)函数下面初始化,要紧跟在hDC初始化之后:   hRC=wglCreateContext(hDC);wglMakeCurrent(hDC,hRC)。hRC只在此处有使用,后面就不会应用到。

4)在bcb中还有个比较特别的函数需要提前声明,那就是void __fastcall TForm1::IdleLoop(TObject*, bool& done),这个函数的功能就是控制屏幕刷新时绘图区的的情况。这个函数是个自定义函数在头文件中需要先声明。然后把Application->OnIdle = IdleLoop放入TForm(Owner),要放在第一句。这样就可以调用这个IdleLoop函数,为什么这样能调用,我不是很明白?可参考bcb中自带的opengl例子。

5)在绘图之前,还得对初始化的量hRC、hDC进行关闭设置,在FormDestroy(TObject *Sender)函数中设置。

6)opengl绘图。我把opengl的绘图语句放在button1的单击事件里。首先清除背景色,或者说叫重设背景色:glClearColor(0.5,0.7,0.9,1.0)、 glClear(GL_COLOR_BUFFER_BIT);  然后用glBegin和glEnd之间语句绘图;最后刷新缓存SwapBuffers(hDC)。后面的程序把绘图语句全放入RenderScence()函数里,所以在Button1Click(TObject *Sender)函数中只需调用RenderScence()。

注:要保证绘图后图形一直存在,除非自己清除,那么就必须在IdleLoop函数写入if(Sender==Button1) Button1Click(Sender);

7)很简单吧,图像能够绘制了!然后就需要对图像进行操作设置了。首先清除图像,只需在button2中重新刷新背景色;然后平移图像,只需在button3中写入glTranslatef(0.25,0,0)(这个命令的意思是将图形右移动0.25个单位。有时在0.25后加f,即0.25f,是指0.25是一个float类型的数),注意接着要重新画图形即调用RenderScence()。左右上下旋转与此雷同,就不一一介绍了。旋转的函数为glRotatef(-5, 1.0, 0.0, 0.0)(这个命令的意思是向上旋转5°,也就是说你点击一下,即向上旋转5°)。

8)文中还有一个功能,就是在一开始就把panel1的背景色绘上,但不绘图。要实现这功能,必须FormCreate(TObject *Sender) 、FormPaint(TObject *Sender)配合使用,为什么要这样未搞清楚!

9)很好,可以画图,可以简单操作了。后续还有很多工作要做,比如窗口的设置、光源的设置、图像的大小设置等等,但只要入了门,看相关的书籍就容易多了,祝大家学习轻松、学习快乐!希望本文能对你有一点点帮助。

附件:源程序

头文件程序*.h

 //---------------------------------------------------------------------------

 #ifndef openglexamH
 #define openglexamH
 //---------------------------------------------------------------------------
 #include <Classes.hpp>
 #include <Controls.hpp>
 #include <StdCtrls.hpp>
 #include <Forms.hpp>
 #include <ExtCtrls.hpp>
 #include <GL/gl.h>
 #include <GL/glu.h>

 //---------------------------------------------------------------------------
 class TForm1 : public TForm
 {
 __published:    // IDE-managed Components
         TButton *Button1;
         TPanel *Panel1;
         TButton *Button2;
         TButton *Button3;
         TButton *Button4;
         TButton *Button5;
         TButton *Button6;
         TButton *Button7;
         void __fastcall FormPaint(TObject *Sender);
         void __fastcall FormDestroy(TObject *Sender);
         void __fastcall FormResize(TObject *Sender);
         void __fastcall Button1Click(TObject *Sender);
         void __fastcall FormKeyDown(TObject *Sender, WORD &Key,
           TShiftState Shift);
         void __fastcall Button2Click(TObject *Sender);
         void __fastcall FormCreate(TObject *Sender);
         void __fastcall Button3Click(TObject *Sender);
 private:    // User declarations
 public:        // User declarations
         __fastcall TForm1(TComponent* Owner);
         HGLRC hRC;
         HDC hDC;
          void __fastcall IdleLoop(TObject*, bool&);
         void __fastcall SetDCPixelFormat(HDC hDC);
         void __fastcall RenderScence();
 };
 //---------------------------------------------------------------------------
 extern PACKAGE TForm1 *Form1;
 //---------------------------------------------------------------------------
 #endif

Cpp文件源代码:

 //---------------------------------------------------------------------------

 #include <vcl.h>
 #pragma hdrstop

 #include "openglexam.h"
 //---------------------------------------------------------------------------
 #pragma package(smart_init)
 #pragma resource "*.dfm"
 TForm1 *Form1;
 //---------------------------------------------------------------------------
 __fastcall TForm1::TForm1(TComponent* Owner)
         : TForm(Owner)
 {
     Application->OnIdle = IdleLoop;
     hDC=GetDC(Form1->Panel1->Handle);//获取一个DC,
     SetDCPixelFormat(hDC); //调整该DC的象素格式
     hRC=wglCreateContext(hDC); //用这种DC去创建一个RC
     wglMakeCurrent(hDC,hRC); //指定当前DC、当前RC为hDC、hRC
 }
 //---------------------------------------------------------------------------
 void __fastcall TForm1::IdleLoop(TObject*, bool& done)
 {
     done = false;
     TObject *Sender;
     if(Sender==Button1)
         Button1Click(Sender);
 }
 //----------------------------------------------------
 void __fastcall TForm1::SetDCPixelFormat(HDC hDC)
 {
     //本函数用于调整DC的象素格式,如缓冲区、颜色数等
     //先不深究,只要知道它的作用就行
     int nPixelFormat;
     static PIXELFORMATDESCRIPTOR pfd = {
         sizeof(PIXELFORMATDESCRIPTOR),        // Size of this structure
         ,                                    // Version of this structure
         PFD_DRAW_TO_WINDOW |                  // Draw to Window (not to bitmap)
         PFD_SUPPORT_OPENGL |                  // Support OpenGL calls in window
         PFD_DOUBLEBUFFER,                     // Double buffered mode
         PFD_TYPE_RGBA,                        // RGBA Color mode
         ,                                   // Want 24bit color
         ,,,,,,                          // Not used to select mode
         ,,                                  // Not used to select mode
         ,,,,,                            // Not used to select mode
         ,                                   // Size of depth buffer
         ,                                    // Not used to select mode
         ,                                    // Not used to select mode
         PFD_MAIN_PLANE,                       // Draw in main plane
         ,                                    // Not used to select mode
         ,, };                              // Not used to select mode
     // Choose a pixel format that best matches that described in pfd
     nPixelFormat = ChoosePixelFormat(hDC, &pfd);
     // Set the pixel format for the device context
     SetPixelFormat(hDC, nPixelFormat, &pfd);
 }
 //-----------------------------------------------------------------
 void __fastcall TForm1::FormPaint(TObject *Sender)
 {
   glClearColor(0.5,0.7,0.9,1.0); //指定背景颜色(依次为RGBA)
   glClear(GL_COLOR_BUFFER_BIT);
   SwapBuffers(hDC);
 }
 //---------------------------------------------------------------------------
 void __fastcall TForm1::FormDestroy(TObject *Sender)
 {
     wglMakeCurrent(NULL,NULL);//取消当前RC和当前DC
     wglDeleteContext(hRC);//删除该RC
     DeleteObject(hDC);//删除Windows DC。
 }
 //---------------------------------------------------------------------------
 void __fastcall TForm1::RenderScence()
 {
 glClearColor(0.5,0.7,0.9,1.0); //指定背景颜色(依次为RGBA)
 glClear(GL_COLOR_BUFFER_BIT);
 glBegin(GL_TRIANGLES);

 glColor3f(1.0,0.0,0.0);
 glVertex3f(-1.0,0.0,0.0);
 glColor3f(0.0,1.0,0.0);
 glVertex3f(0.0,1.0,0.0);
 glColor3f(0.0,0.0,1.0);
 glVertex3f(1.0,0.0,0.0);
 glEnd();
 SwapBuffers(hDC);
 }
 //---------------------------------------------------------------------------
 void __fastcall TForm1::Button1Click(TObject *Sender)
 {
    RenderScence();

 }
 //---------------------------------------------------------------------------
 void __fastcall TForm1::Button2Click(TObject *Sender)
 {
   glClearColor(0.5,0.7,0.9,1.0); //指定背景颜色(依次为RGBA)
   glClear(GL_COLOR_BUFFER_BIT);  //用背景色清窗口

   SwapBuffers(hDC);
 }
 //---------------------------------------------------------------------------

 void __fastcall TForm1::FormCreate(TObject *Sender)
 {
   glClearColor(0.5,0.7,0.9,1.0); //指定背景颜色(依次为RGBA)
   glClear(GL_COLOR_BUFFER_BIT);  //用背景色清窗口
   //glFlush();
   SwapBuffers(hDC);
 }
 //---------------------------------------------------------------------------
 void __fastcall TForm1::Button3Click(TObject *Sender)
 {
   glTranslatef(,);
   RenderScence();
 }
 //---------------------------------------------------------------------------

 void __fastcall TForm1::Button6Click(TObject *Sender)
 {
    glRotatef(-, 1.0, 0.0, 0.0);
    RenderScence();
 }
 //---------------------------------------------------------------------------
 void __fastcall TForm1::Button7Click(TObject *Sender)
 {
     glRotatef(, 1.0, 0.0, 0.0);
     RenderScence();
 }
 //---------------------------------------------------------------------------
 void __fastcall TForm1::Button4Click(TObject *Sender)
 {
   glRotatef(-, 0.0, 1.0, 0.0);
   RenderScence();
 }
 //---------------------------------------------------------------------------
 void __fastcall TForm1::Button5Click(TObject *Sender)
 {
    glRotatef(, 0.0, 1.0, 0.0);
    RenderScence();
 }
 //---------------------------------------------------------------------------

如何在C++ Builder中使用OpenGL的更多相关文章

  1. 如何在Report Builder中使用fnd_profile.value

    在EBS的Report开发中,需要根据客户化的一个Profile来控制用户可以访问的数据,可是在开发的过程中发现一直取不到该Profile的值,后来百度才找到了原因. 解决方法: 1.添加用户参数p_ ...

  2. 在MFC框架中使用OpenGL的简单实例

    引言 我们知道,在MFC框架中,用于绘图的接口是GDI.但GDI只能绘制简单的2D图形,要想制作精美的3D图形,一个可行的办法是使用OpenGL或者Direct3D等第三方库. 由于最近在给导师的一个 ...

  3. VS2010中配置OpenGL

    下面将对VS2010中配置OpenGL进行简单介绍. 学习OpenGL前的准备工作第一步,选择一个编译环境现在Windows系统的主流编译环境有Visual Studio,Broland C++ Bu ...

  4. vs2010中配置OpenGL以及针对64位系统所遇问题的解决办法

    一.下面将对VS2010中配置OpenGL进行简单介绍. 学习OpenGL前的准备工作 第一步,选择一个编译环境 现在Windows系统的主流编译环境有Visual Studio,Broland C+ ...

  5. 《MFC dialog中加入OpenGL窗体》

    <MFC dialog中加入OpenGL窗体> 最近学习了如何在MFC对话框程序中加入OpenGL窗体的方法,在这里将自己的实现过程归纳一下. 步骤零: 加入PictureControl控 ...

  6. 如何在 Visual Studio 中使用 Git 同步代码到 CodePlex

    开源社区不管在国内还是国外都很火热,微软也曾因为没有开源而倍受指责,但是随着 .Net framework.ASP.Net MVC等框架的逐渐开源,也让大家看到了微软开源的步伐.CodePlex 则是 ...

  7. VC 6中配置OpenGL开发环境

    2010,2012中配置类似 http://hi.baidu.com/yanzi52351/item/f9a600dffa4caa4ddcf9be1d VC 6中配置OpenGL开发环境 这里,我习惯 ...

  8. 如何在Linux服务器中隐藏PHP版本

    通常,大多数默认设置安装的web服务器存在信息泄露,这其中之一就是PHP.PHP 是如今流行的服务端html嵌入式语言(之一?).在如今这个充满挑战的时代,有许多攻击者会尝试发现你服务端的漏洞.因此, ...

  9. [Laravel-Swagger]如何在 Laravel 项目中使用 Swagger

    如何在 Laravel 项目中使用 Swagger http://swagger.io/getting-started/ 安装依赖 swagger-php composer require zirco ...

随机推荐

  1. 集成 Entity Framework

    ABP 基础设施层——集成 Entity Framework 本文翻译自ABP的官方教程<EntityFramework Integration>,地址为:http://aspnetboi ...

  2. 使用requirejs实现模块化编程

    > 序言 - -# 公司大了,业务多了,前端代码量也逐渐增大,我们渐渐的依赖js实现的交互越来越多,长期以来会导致我们的代码维护越来越困难,所以依赖的插件也越来越多..比如这样页面中有大量的js ...

  3. Elasticsearch教程

    Elasticsearch教程 摘要: 参考资料Elasticsearch中文参考文档思维导图阅读全文 posted @ 2015-08-05 11:49 xingoo 阅读(18) | 评论 (0) ...

  4. web开发性能优化---UI接口章

    1.尽可能的远div+css设计 DIV+CSS与表相比格优势布局: a.精简代码 采用DIV+CSS设计,页面代码精简.这是为了XHTML了解都知道. 代码精简所带来的直接优点有两点:一是提高蜘蛛爬 ...

  5. java.lang.reflect操作对象属性(域)的值

    package reflect; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.l ...

  6. HTML文档中应用css样式的方法总结

    在HTML文档中应用css样式大致有三种方法:1.link标签链接外部样式表:2.使用style元素包含样式表:3.使用style属性,即内联样式 一.link标签链接外部样式表 先看一条较为标准的l ...

  7. android_Activity生命周期功能

    说明:初步activity 生命周期7功能. 样本:于MainActivity我加了button,搬家button.跳到OtherActivity.控制台输出的观察. 让我们来看看这些功能: 他们的流 ...

  8. 【转】monkey工具简介

    原文地址:http://www.testwo.com/blog/6188   一.Monkey 简介 Android的SDK 里面,Monkey的tools是一个命令行工具,当连接Android设备时 ...

  9. [VirtualBox] - Install Oracle Linux 7 on Oracle VirtualBox

    I'll start coding with JEE soon. Product environment adopts Oracle + WebLogic in Linux, technology a ...

  10. C++内存泄露的有效预防方法:谁使用,谁删除 (1.2)

    内存泄露就是new出来的东西没有delete,我们能够这样:创建动态对象的人虽然使用new来创建对象:使用此对象的人负责释放此内存块. 比如:我和他人共享一个消息队列,他人将消息(new出来的对象)放 ...