最近在重学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键可以隐藏文字.
软件下载地址:
http://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
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 }
代码中"// ......."的部分是由用户改写的.
源码下载地址:
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,请与我联系.
WhyGL:一套学习OpenGL的框架,及翻写Nehe的OpenGL教程,布布扣,bubuko.com
WhyGL:一套学习OpenGL的框架,及翻写Nehe的OpenGL教程
原文:http://www.cnblogs.com/WhyEngine/p/3632858.html