WhyGL:一套学习OpenGL的框架,及翻写Nehe的OpenGL教程

      最近在重学OpenGL,之所以说重学是因为上次接触OpenGL还是在学校里,工作之后就一直在搞D3D,一转眼已经毕业6年了.OpenGL这门手艺早就完全荒废了,现在只能是重学.学习程序最有效的办法是动手写,光看书是不行了,因为看书的时候很容易陷入对人类两大难题的思考中,以至于进展缓慢.这两大难题是:这特妈是啥?那特妈又是啥?在重学的过程中,我翻写了Nehe所有的OpenGL教程DEMO.本来打算把"翻写"写成"重构"的,但想想"重构"这个词这么高端大气上档次,通常只有牛B的人和装B的人爱提,我要是用"重构",感觉后者的嫌疑更大.

      先贴出我的OpenGL作品:

软件说明:

"WhyGL演示程序平台.exe"和"WhyGL.exe"都可以运行程序,不同之处在于,一个是基本的Windows窗体程序,一个是MFC的单文档界面程序.

主UI界面上,鼠标点击可以选择要运行的DEMO
键盘的上下键也可以选择DEMO,PageUp和PageDown用于翻页,回车键用于启动选中的DEMO

F11键用于全屏切换,
ESC用于退出当前DEMO及退出全屏
每个DEMO都会将提示文字信息显示在界面上,H键可以隐藏文字.

 

软件下载地址:
https://files.cnblogs.com/WhyEngine/WhyGL.7z


      所有的DEMO都写在同一个程序中,采用面向对象的方法,每一个DEMO都对应一个对象.Nehe的DEMO中基本上是采用全局变量,全局函数来实现,而我翻写的程序尽量将其封装为对象的成员变量和成员函数.之所以称这套系统为一个框架,是因为我提供了一套学习OpenGL的平台,可以帮助3D程序的初学者更容易入门,用户可以方便的在上面添加自己的程序.

      3D程序一开始接触会觉得很难,不过究其根本可以分为以下几个过程:

(1)初始化渲染设备;
(2)创建渲染数据,设置渲染状态;
(3)执行数据的处理操作;
(4)响应消息事件;
(5)渲染处理;
(6)删除渲染数据,恢复渲染状态;
(7)销毁渲染设备.

      在WhyGL框架中,我尽量将一些系列通用的复杂的流程封装好,以便于用户写代码时,只关心具体的渲染逻辑.这有些类似GLUT,在GLUT中将windows窗体的创建,事件处理都封装好,用户只填写回调函数即可实现.在WhyGL,为用户提供一个DEMO基类,用户需要继承该类,并添加自己的成员变量,重载其方法就可以绘制自己的图形.这就如同考试时将问答题改成填空题,降低了难度.

先提供个具体的DEMO类如何写:

FlyingHelper.h

 1 #ifndef _FlyingHelper_H_
 2 #define _FlyingHelper_H_
 3 
 4 // INCLUDES -----------------------------------------------------------------------------
 5 
 6 #include "..\DemoGL.h"
 7 
 8 // --------------------------------------------------------------------------------------
 9 
10 class CFlyingHelper : public CDemoGL
11 {
12 public:
13     CFlyingHelper();
14 
15     ~CFlyingHelper();
16 
17     // 对该对象类型的判断
18     WHY_DEFINE_IS_KIND_OF(CFlyingHelper, CDemoGL);
19 
20     // 初始化处理
21     bool            Initialize();
22 
23     // 销毁处理(删除创建的对象,恢复GL设备状态)
24     void            Destroy();
25 
26     // 执行,用于对逻辑的处理
27     void            Execute(Yuint deltaTime);
28 
29     // 渲染
30     void            Render();
31 
32     // UI界面的渲染
33     void            RenderUI();
34 
35     // Windows系统消息响应
36     bool            ProcessSystemMessage(Yuint, Yuint, Yuint);
37 
38     // 返回功能说明
39     const char*     GetTip() const
40     {
41         return "Flying Helper: Tell you how to create a demo.";
42     }
43 
44     // 对GL设备状态的设置
45     void            InitGLStates();
46 
47     // 键盘事件响应
48     void            OnKeyDown(Yuint key);
49 
50     // 鼠标左键按下响应
51     void            OnMouseDown(short x, short y);
52 
53     // 鼠标左键弹起响应
54     void            OnMouseUp(short x, short y);
55 
56     // 鼠标移动事件响应
57     void            OnMouseMove(short x, short y);
58 
59     // 窗口大小变化响应
60     void            OnResize(Yuint width, Yuint height);
61 
62 private:
63     short m_mouseX;
64     short m_mouseY;
65     bool m_bMouseDown;
66 };
67 
68 // --------------------------------------------------------------------------------------
69 
70 #endif
View Code

FlyingHelper.cpp

  1 // --------------------------------------------------------------------------------------
  2 
  3 #include "..\..\..\WhyEngine\YInterface\WhyModuleAPI.h"
  4 #include "..\..\..\Interface\YicGLDevice.h"
  5 #include "..\..\..\Interface\YicGLFont.h"
  6 #include "..\..\..\Interface\YicGLPrimitive2DRender.h"
  7 #include <gl\gl.h>            // Header File For The OpenGL32 Library
  8 #include <gl\glu.h>            // Header File For The GLu32 Library
  9 #include "FlyingHelper.h"
 10 
 11 // --------------------------------------------------------------------------------------
 12 
 13 #ifndef WM_MOUSEWHEEL
 14   #define WM_MOUSEWHEEL                 0x020A
 15 #endif
 16 
 17 // --------------------------------------------------------------------------------------
 18 
 19 // 将实体对象注册到引擎(非常重要)
 20 WHY_REGISTER_ENTITY(CFlyingHelper)
 21 
 22 // --------------------------------------------------------------------------------------
 23 
 24 CFlyingHelper::CFlyingHelper()
 25 {
 26     m_mouseX = 0;
 27     m_mouseY = 0;
 28     m_bMouseDown = false;
 29 }
 30 
 31 CFlyingHelper::~CFlyingHelper()
 32 {
 33 }
 34 
 35 // 初始化处理
 36 bool            CFlyingHelper::Initialize()
 37 {
 38     if (!CDemoGL::Initialize())
 39     {
 40         return false;
 41     }
 42     
 43     // .......
 44 
 45     // 注册引擎的系统消息层
 46     _WHY_CORE->RegisterEntityLayer(this, YE_ELAYER_WINDOWS_MESSAGE, 0x80000000);
 47 
 48     return true;
 49 }
 50 
 51 // 销毁处理(删除创建的对象,恢复GL设备状态)
 52 void            CFlyingHelper::Destroy()
 53 {
 54     // .......
 55 
 56     CDemoGL::Destroy();
 57 }
 58 
 59 // 执行,用于对逻辑的处理(每帧都会被执行一次)
 60 void            CFlyingHelper::Execute(Yuint deltaTime)
 61 {
 62     // .......
 63 }
 64 
 65 // 渲染(每帧都会被执行一次)
 66 void            CFlyingHelper::Render()
 67 {
 68     // .......
 69 }
 70 
 71 // UI界面的渲染(每帧都会被执行一次)
 72 void            CFlyingHelper::RenderUI()
 73 {
 74     CDemoGL::RenderUI();
 75     
 76     char szPos[64];
 77     sprintf(szPos, "(%d, %d)", m_mouseX, m_mouseY);
 78     unsigned int color = (m_bMouseDown) ? 0xffff0000 : 0xff00ff00;
 79     m_pGLFont->DrawText2D(m_mouseX, m_mouseY, color, szPos);
 80 }
 81 
 82 // Windows系统消息响应
 83 bool            CFlyingHelper::ProcessSystemMessage(Yuint iMsg, Yuint wParam, Yuint lParam)
 84 {
 85     switch (iMsg)
 86     {
 87     case WM_SIZE:
 88         break;
 89     case WM_KEYDOWN:
 90         break;
 91     case WM_LBUTTONDOWN:
 92         break;
 93     case WM_LBUTTONUP:
 94         break;
 95     case WM_RBUTTONDOWN:
 96         break;
 97     case WM_RBUTTONUP:
 98         break;
 99     case WM_MOUSEMOVE:
100         break;
101     case WM_MOUSEWHEEL:
102         break;
103     }
104 
105     return false;
106 }
107 
108 // 对GL设备状态的设置
109 void            CFlyingHelper::InitGLStates()
110 {
111     // .......
112 }
113 
114 // 键盘事件响应
115 void            CFlyingHelper::OnKeyDown(Yuint key)
116 {
117     char c[4];
118     c[0] = (char)key;
119     c[1] = '\r';
120     c[2] = '\n';
121     c[3] = 0;
122     ::OutputDebugStringA(c);
123 }
124 
125 // 鼠标左键按下响应
126 void            CFlyingHelper::OnMouseDown(short x, short y)
127 {
128     m_bMouseDown = true;
129 }
130 
131 // 鼠标左键弹起响应
132 void            CFlyingHelper::OnMouseUp(short x, short y)
133 {
134     m_bMouseDown = false;
135 }
136 
137 // 鼠标移动事件响应
138 void            CFlyingHelper::OnMouseMove(short x, short y)
139 {
140     m_mouseX = x;
141     m_mouseY = y;
142 }
143 
144 // 窗口大小变化响应
145 void            CFlyingHelper::OnResize(Yuint width, Yuint height)
146 {
147     CDemoGL::OnResize(width, height);
148 
149     // .......
150 }
View Code

代码中"// ......."的部分是由用户改写的.

 

源码下载地址:
http://pan.baidu.com/s/1bniWD0z

源码中有4个模块,

"SampleWin"和"WhyDemoViewer"为Windows应用程序.

"WhyGLDevice"为OpenGL的设备创建模块,里面还实现了字体的显示功能和简单二维图形显示的功能.

"WhyTestGL"为具体的DEMO逻辑,用户可以在这里添加自己的代码.

程序中还需要一个模块WhyCore这是我引擎的核心,用于对其他模块的加载管理,不过我尚没有将其开源的打算.

 

接下来要说下程序需要的两个配置文件

WhyCore.ini是引擎的启动文件

ModulesPath = .\dll\

DumpProcess = true
CreateDumpFile = true
WriteDumpLog = true
MaxNumStackFrame = 10

Game = CWhyTestGL

[WhyTestGL]
;DemoGL = CFlying01
[WhyTestGL]
DemoGL = CFlying01 这个表示初始时将启动哪一个DEMO,CFlying01为一个DEMO对象的类名.用该方法在调试程序时比较方便.
前面加分号;表示该行无效.

WhyTestGL.ini是DEMO的配置文件
[WhyTestGL]
Nehe = OpenGL-Nehe OpenGL tutorials most of the source data sets to help you from entry to proficient in OpenGL
Flying = WhyEngine Demo

[Nehe]
CNeheLesson01 = Press any key to change background color
CNeheLesson02 = My First Polygon, Draw Triangle and Quad
.........
CNeheLesson47 = CG Vertex Shader
CNeheLesson48 = ArcBall Rotation

[Flying]
CFlyingHelper = Flying Helper: Tell you how to create a demo
CFlying01 = Test YicGLPrimitive2DRender and draw some 2D graph

这里的]表示DEMO分为几组.

然后每个字段下是DEMO对象的类名以及对应的相关信息.

用户如果写了自己的DEMO,请务必在WhyTestGL.INI配置文件中添加上相关信息.

-------------------------------------------------------------------------------------
最后要说的是,这个东西写得很仓促,如果有什么BUG,请与我联系.

 

[Nehe]
CNeheLesson01 OpenGL窗口 Press any key to change background color

 

CNeheLesson02 多边形 My First Polygon, Draw Triangle and Quad

 

CNeheLesson03 添加颜色 Adding Color

 

CNeheLesson04 旋转 Rotation

 

CNeheLesson05 3D空间 3D Shapes: Pyramid and Box

 

CNeheLesson06 纹理映射 Texture Mapping

 

CNeheLesson07 光照和键盘 Texture Filters, Lighting & Keyboard Control

 

CNeheLesson08 混合 Blending

 

CNeheLesson09 移动图像 Moving Bitmaps In 3D Space

 

CNeheLesson10 3D世界 Loading And Moving Through A 3D World

 

CNeheLesson11 飘动的旗帜 Flag Effect (Waving Texture)

 

CNeheLesson12 显示列表 Display List

 

CNeheLesson13 2D字体 Draw Text

 

CNeheLesson14 3D字体 Draw 3D Text

 

CNeheLesson15 纹理图形字 Texture Mapped Outline Fonts

 

CNeheLesson16 雾 Cool Looking Fog

 

CNeheLesson17 2D图像文字 2D Texture Font

 

CNeheLesson18 二次几何体 Quadric Geometry

 

CNeheLesson19 粒子系统 Particle Engine Using Triangle Strips

 

CNeheLesson20 蒙板 Masking

 

CNeheLesson21 线的游戏 Game Crazy Grid. Lines, Antialiasing, Timing, Ortho View And Simple Sounds

 

CNeheLesson22 凹凸映射 Bump-Mapping, Multi-Texturing & Extensions

 

CNeheLesson23 球面映射 Sphere Mapping Quadrics In OpenGL

 

CNeheLesson24 扩展TGA纹理 Tokens, Extensions, Scissor Testing And TGA Loading

 

CNeheLesson25 变形 Morphing & Loading Objects From A File

 

CNeheLesson26 反射 Clipping & Reflections Using The Stencil Buffer

 

CNeheLesson27 影子 Shadows

 

CNeheLesson28 贝塞尔曲面 Bezier Patches / Fullscreen Fix

 

CNeheLesson29 Blt函数 Blitter Function, RAW Texture Loading

 

CNeheLesson30 碰撞检测 Collision Detection

 

CNeheLesson31 模型加载 Model Loading

 

CNeheLesson32 拾取游戏 Shoot Game. Picking, Alpha Blending, Alpha Testing, Sorting

 

CNeheLesson33 TGA文件 Loading Compressed And Uncompressed TGA's

 

CNeheLesson34 地形 Beautiful Landscapes By Means Of Height Mapping

 

CNeheLesson35 播放AVI Playing AVI Files In OpenGL

 

CNeheLesson36 渲染到纹理 Radial Blur & Rendering To A Texture

 

CNeheLesson37 卡通映射 Cel-Shading

 

CNeheLesson38 资源文件 Butterfly Texturing Triangles

 

CNeheLesson39 物理模拟 Introduction to Physical Simulations

 

CNeheLesson40 绳子的模拟 Rope Physics

 

CNeheLesson41 体积雾气 Volumetric Fog & IPicture Image Loading

 

CNeheLesson42 多重视口 Multiple Viewports

 

CNeheLesson43 FreeType库 FreeType Fonts in OpenGL

 

CNeheLesson44 3D 光晕 3D Lens Flare With Occlusion Testing

 

CNeheLesson45 顶点缓存 Vertex Buffer Objects

 

CNeheLesson46 全屏反走样 Fullscreen AntiAliasing

 

CNeheLesson47 CG顶点脚本 CG Vertex Shader

 

CNeheLesson48 轨迹球 ArcBall Rotation

 


[Flying]
CFlyingHelper = Flying Helper: Tell you how to create a demo

 

CFlying01 = Test YicGLPrimitive2DRender and draw some 2D graph

 

 

posted on 2014-03-29 18:37  叶飞影  阅读(9161)  评论(3编辑  收藏  举报