如何在C++ Builder中使用OpenGL

作者:太乙散数

摘要:用一个简单的例子,阐述了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

 1 //---------------------------------------------------------------------------
 2 
 3 #ifndef openglexamH
 4 #define openglexamH
 5 //---------------------------------------------------------------------------
 6 #include <Classes.hpp>
 7 #include <Controls.hpp>
 8 #include <StdCtrls.hpp>
 9 #include <Forms.hpp>
10 #include <ExtCtrls.hpp>
11 #include <GL/gl.h>
12 #include <GL/glu.h>
13 
14 //---------------------------------------------------------------------------
15 class TForm1 : public TForm
16 {
17 __published:    // IDE-managed Components
18         TButton *Button1;
19         TPanel *Panel1;
20         TButton *Button2;
21         TButton *Button3;
22         TButton *Button4;
23         TButton *Button5;
24         TButton *Button6;
25         TButton *Button7;
26         void __fastcall FormPaint(TObject *Sender);
27         void __fastcall FormDestroy(TObject *Sender);
28         void __fastcall FormResize(TObject *Sender);
29         void __fastcall Button1Click(TObject *Sender);
30         void __fastcall FormKeyDown(TObject *Sender, WORD &Key,
31           TShiftState Shift);
32         void __fastcall Button2Click(TObject *Sender);
33         void __fastcall FormCreate(TObject *Sender);
34         void __fastcall Button3Click(TObject *Sender);
35 private:    // User declarations
36 public:        // User declarations
37         __fastcall TForm1(TComponent* Owner);
38         HGLRC hRC;
39         HDC hDC;
40          void __fastcall IdleLoop(TObject*, bool&);
41         void __fastcall SetDCPixelFormat(HDC hDC);
42         void __fastcall RenderScence();
43 };
44 //---------------------------------------------------------------------------
45 extern PACKAGE TForm1 *Form1;
46 //---------------------------------------------------------------------------
47 #endif

Cpp文件源代码:

  1 //---------------------------------------------------------------------------
  2 
  3 #include <vcl.h>
  4 #pragma hdrstop
  5 
  6 #include "openglexam.h"
  7 //---------------------------------------------------------------------------
  8 #pragma package(smart_init)
  9 #pragma resource "*.dfm"
 10 TForm1 *Form1;
 11 //---------------------------------------------------------------------------
 12 __fastcall TForm1::TForm1(TComponent* Owner)
 13         : TForm(Owner)
 14 {   
 15     Application->OnIdle = IdleLoop;
 16     hDC=GetDC(Form1->Panel1->Handle);//获取一个DC,
 17     SetDCPixelFormat(hDC); //调整该DC的象素格式
 18     hRC=wglCreateContext(hDC); //用这种DC去创建一个RC
 19     wglMakeCurrent(hDC,hRC); //指定当前DC、当前RC为hDC、hRC
 20 }
 21 //---------------------------------------------------------------------------
 22 void __fastcall TForm1::IdleLoop(TObject*, bool& done)
 23 {
 24     done = false;
 25     TObject *Sender;
 26     if(Sender==Button1)
 27         Button1Click(Sender);
 28 }
 29 //----------------------------------------------------
 30 void __fastcall TForm1::SetDCPixelFormat(HDC hDC)
 31 {
 32     //本函数用于调整DC的象素格式,如缓冲区、颜色数等
 33     //先不深究,只要知道它的作用就行
 34     int nPixelFormat;
 35     static PIXELFORMATDESCRIPTOR pfd = {
 36         sizeof(PIXELFORMATDESCRIPTOR),        // Size of this structure
 37         1,                                    // Version of this structure
 38         PFD_DRAW_TO_WINDOW |                  // Draw to Window (not to bitmap)
 39         PFD_SUPPORT_OPENGL |                  // Support OpenGL calls in window
 40         PFD_DOUBLEBUFFER,                     // Double buffered mode
 41         PFD_TYPE_RGBA,                        // RGBA Color mode
 42         24,                                   // Want 24bit color
 43         0,0,0,0,0,0,                          // Not used to select mode
 44         0,0,                                  // Not used to select mode
 45         0,0,0,0,0,                            // Not used to select mode
 46         32,                                   // Size of depth buffer
 47         0,                                    // Not used to select mode
 48         0,                                    // Not used to select mode
 49         PFD_MAIN_PLANE,                       // Draw in main plane
 50         0,                                    // Not used to select mode
 51         0,0,0 };                              // Not used to select mode
 52     // Choose a pixel format that best matches that described in pfd
 53     nPixelFormat = ChoosePixelFormat(hDC, &pfd);
 54     // Set the pixel format for the device context
 55     SetPixelFormat(hDC, nPixelFormat, &pfd);
 56 }
 57 //-----------------------------------------------------------------
 58 void __fastcall TForm1::FormPaint(TObject *Sender)
 59 {
 60   glClearColor(0.5,0.7,0.9,1.0); //指定背景颜色(依次为RGBA)
 61   glClear(GL_COLOR_BUFFER_BIT);
 62   SwapBuffers(hDC);
 63 }
 64 //---------------------------------------------------------------------------
 65 void __fastcall TForm1::FormDestroy(TObject *Sender)
 66 {
 67     wglMakeCurrent(NULL,NULL);//取消当前RC和当前DC
 68     wglDeleteContext(hRC);//删除该RC
 69     DeleteObject(hDC);//删除Windows DC。
 70 }
 71 //---------------------------------------------------------------------------
 72 void __fastcall TForm1::RenderScence()
 73 {
 74 glClearColor(0.5,0.7,0.9,1.0); //指定背景颜色(依次为RGBA)
 75 glClear(GL_COLOR_BUFFER_BIT);
 76 glBegin(GL_TRIANGLES);
 77 
 78 glColor3f(1.0,0.0,0.0);
 79 glVertex3f(-1.0,0.0,0.0);
 80 glColor3f(0.0,1.0,0.0);
 81 glVertex3f(0.0,1.0,0.0);
 82 glColor3f(0.0,0.0,1.0);
 83 glVertex3f(1.0,0.0,0.0);
 84 glEnd();
 85 SwapBuffers(hDC);
 86 }
 87 //---------------------------------------------------------------------------
 88 void __fastcall TForm1::Button1Click(TObject *Sender)
 89 {
 90    RenderScence();
 91 
 92 }
 93 //---------------------------------------------------------------------------
 94 void __fastcall TForm1::Button2Click(TObject *Sender)
 95 {
 96   glClearColor(0.5,0.7,0.9,1.0); //指定背景颜色(依次为RGBA)
 97   glClear(GL_COLOR_BUFFER_BIT);  //用背景色清窗口
 98 
 99   SwapBuffers(hDC);
100 }
101 //---------------------------------------------------------------------------
102 
103 void __fastcall TForm1::FormCreate(TObject *Sender)
104 {
105   glClearColor(0.5,0.7,0.9,1.0); //指定背景颜色(依次为RGBA)
106   glClear(GL_COLOR_BUFFER_BIT);  //用背景色清窗口
107   //glFlush();
108   SwapBuffers(hDC);
109 }
110 //---------------------------------------------------------------------------
111 void __fastcall TForm1::Button3Click(TObject *Sender)
112 {
113   glTranslatef(0.25,0,0);
114   RenderScence();
115 }
116 //---------------------------------------------------------------------------
117 
118 void __fastcall TForm1::Button6Click(TObject *Sender)
119 {
120    glRotatef(-5, 1.0, 0.0, 0.0);
121    RenderScence();
122 }
123 //---------------------------------------------------------------------------
124 void __fastcall TForm1::Button7Click(TObject *Sender)
125 {
126     glRotatef(5, 1.0, 0.0, 0.0);
127     RenderScence();
128 }
129 //---------------------------------------------------------------------------
130 void __fastcall TForm1::Button4Click(TObject *Sender)
131 {
132   glRotatef(-5, 0.0, 1.0, 0.0);
133   RenderScence();
134 }
135 //---------------------------------------------------------------------------
136 void __fastcall TForm1::Button5Click(TObject *Sender)
137 {
138    glRotatef(5, 0.0, 1.0, 0.0);
139    RenderScence();
140 }
141 //---------------------------------------------------------------------------

 

 

如何在C++ Builder中使用OpenGL,古老的榕树,5-wow.com

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。