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键可以隐藏文字.
软件下载地址:
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
#ifndef _FlyingHelper_H_
#define _FlyingHelper_H_ // INCLUDES ----------------------------------------------------------------------------- #include "..\DemoGL.h" // -------------------------------------------------------------------------------------- class CFlyingHelper : public CDemoGL
{
public:
CFlyingHelper(); ~CFlyingHelper(); // 对该对象类型的判断
WHY_DEFINE_IS_KIND_OF(CFlyingHelper, CDemoGL); // 初始化处理
bool Initialize(); // 销毁处理(删除创建的对象,恢复GL设备状态)
void Destroy(); // 执行,用于对逻辑的处理
void Execute(Yuint deltaTime); // 渲染
void Render(); // UI界面的渲染
void RenderUI(); // Windows系统消息响应
bool ProcessSystemMessage(Yuint, Yuint, Yuint); // 返回功能说明
const char* GetTip() const
{
return "Flying Helper: Tell you how to create a demo.";
} // 对GL设备状态的设置
void InitGLStates(); // 键盘事件响应
void OnKeyDown(Yuint key); // 鼠标左键按下响应
void OnMouseDown(short x, short y); // 鼠标左键弹起响应
void OnMouseUp(short x, short y); // 鼠标移动事件响应
void OnMouseMove(short x, short y); // 窗口大小变化响应
void OnResize(Yuint width, Yuint height); private:
short m_mouseX;
short m_mouseY;
bool m_bMouseDown;
}; // -------------------------------------------------------------------------------------- #endif
FlyingHelper.cpp
// -------------------------------------------------------------------------------------- #include "..\..\..\WhyEngine\YInterface\WhyModuleAPI.h"
#include "..\..\..\Interface\YicGLDevice.h"
#include "..\..\..\Interface\YicGLFont.h"
#include "..\..\..\Interface\YicGLPrimitive2DRender.h"
#include <gl\gl.h> // Header File For The OpenGL32 Library
#include <gl\glu.h> // Header File For The GLu32 Library
#include "FlyingHelper.h" // -------------------------------------------------------------------------------------- #ifndef WM_MOUSEWHEEL
#define WM_MOUSEWHEEL 0x020A
#endif // -------------------------------------------------------------------------------------- // 将实体对象注册到引擎(非常重要)
WHY_REGISTER_ENTITY(CFlyingHelper) // -------------------------------------------------------------------------------------- CFlyingHelper::CFlyingHelper()
{
m_mouseX = ;
m_mouseY = ;
m_bMouseDown = false;
} CFlyingHelper::~CFlyingHelper()
{
} // 初始化处理
bool CFlyingHelper::Initialize()
{
if (!CDemoGL::Initialize())
{
return false;
} // ....... // 注册引擎的系统消息层
_WHY_CORE->RegisterEntityLayer(this, YE_ELAYER_WINDOWS_MESSAGE, 0x80000000); return true;
} // 销毁处理(删除创建的对象,恢复GL设备状态)
void CFlyingHelper::Destroy()
{
// ....... CDemoGL::Destroy();
} // 执行,用于对逻辑的处理(每帧都会被执行一次)
void CFlyingHelper::Execute(Yuint deltaTime)
{
// .......
} // 渲染(每帧都会被执行一次)
void CFlyingHelper::Render()
{
// .......
} // UI界面的渲染(每帧都会被执行一次)
void CFlyingHelper::RenderUI()
{
CDemoGL::RenderUI(); char szPos[];
sprintf(szPos, "(%d, %d)", m_mouseX, m_mouseY);
unsigned int color = (m_bMouseDown) ? 0xffff0000 : 0xff00ff00;
m_pGLFont->DrawText2D(m_mouseX, m_mouseY, color, szPos);
} // Windows系统消息响应
bool CFlyingHelper::ProcessSystemMessage(Yuint iMsg, Yuint wParam, Yuint lParam)
{
switch (iMsg)
{
case WM_SIZE:
break;
case WM_KEYDOWN:
break;
case WM_LBUTTONDOWN:
break;
case WM_LBUTTONUP:
break;
case WM_RBUTTONDOWN:
break;
case WM_RBUTTONUP:
break;
case WM_MOUSEMOVE:
break;
case WM_MOUSEWHEEL:
break;
} return false;
} // 对GL设备状态的设置
void CFlyingHelper::InitGLStates()
{
// .......
} // 键盘事件响应
void CFlyingHelper::OnKeyDown(Yuint key)
{
char c[];
c[] = (char)key;
c[] = '\r';
c[] = '\n';
c[] = ;
::OutputDebugStringA(c);
} // 鼠标左键按下响应
void CFlyingHelper::OnMouseDown(short x, short y)
{
m_bMouseDown = true;
} // 鼠标左键弹起响应
void CFlyingHelper::OnMouseUp(short x, short y)
{
m_bMouseDown = false;
} // 鼠标移动事件响应
void CFlyingHelper::OnMouseMove(short x, short y)
{
m_mouseX = x;
m_mouseY = y;
} // 窗口大小变化响应
void CFlyingHelper::OnResize(Yuint width, Yuint height)
{
CDemoGL::OnResize(width, height); // .......
}
代码中"// ......."的部分是由用户改写的.
源码下载地址:
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 = 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
WhyGL:一套学习OpenGL的框架,及翻写Nehe的OpenGL教程的更多相关文章
- [源码解析] 深度学习分布式训练框架 horovod (4) --- 网络基础 & Driver
[源码解析] 深度学习分布式训练框架 horovod (4) --- 网络基础 & Driver 目录 [源码解析] 深度学习分布式训练框架 horovod (4) --- 网络基础 & ...
- [源码解析] 深度学习分布式训练框架 horovod (5) --- 融合框架
[源码解析] 深度学习分布式训练框架 horovod (5) --- 融合框架 目录 [源码解析] 深度学习分布式训练框架 horovod (5) --- 融合框架 0x00 摘要 0x01 架构图 ...
- [源码解析] 深度学习分布式训练框架 horovod (7) --- DistributedOptimizer
[源码解析] 深度学习分布式训练框架 horovod (7) --- DistributedOptimizer 目录 [源码解析] 深度学习分布式训练框架 horovod (7) --- Distri ...
- [源码解析] 深度学习分布式训练框架 horovod (8) --- on spark
[源码解析] 深度学习分布式训练框架 horovod (8) --- on spark 目录 [源码解析] 深度学习分布式训练框架 horovod (8) --- on spark 0x00 摘要 0 ...
- [源码解析] 深度学习分布式训练框架 horovod (9) --- 启动 on spark
[源码解析] 深度学习分布式训练框架 horovod (9) --- 启动 on spark 目录 [源码解析] 深度学习分布式训练框架 horovod (9) --- 启动 on spark 0x0 ...
- [源码解析] 深度学习分布式训练框架 horovod (18) --- kubeflow tf-operator
[源码解析] 深度学习分布式训练框架 horovod (18) --- kubeflow tf-operator 目录 [源码解析] 深度学习分布式训练框架 horovod (18) --- kube ...
- OpenGL新手框架
开始学习用OpenGL,也就想显示一些点,以为挺简单的,哎,看了两天才会画三维的点,做个总结. 使用OpenGL的基本流程 int main(int argv, char *argc[]) { //初 ...
- Java并发包源码学习之AQS框架(四)AbstractQueuedSynchronizer源码分析
经过前面几篇文章的铺垫,今天我们终于要看看AQS的庐山真面目了,建议第一次看AbstractQueuedSynchronizer 类源码的朋友可以先看下我前面几篇文章: <Java并发包源码学习 ...
- Java并发包源码学习之AQS框架(三)LockSupport和interrupt
接着上一篇文章今天我们来介绍下LockSupport和Java中线程的中断(interrupt). 其实除了LockSupport,Java之初就有Object对象的wait和notify方法可以实现 ...
随机推荐
- 关于table边框,设置了border-collapse:collapse之后,设置border-radius没效果
做项目遇到边框需要设置圆角,然后发现在设置了border-collapse:collapse之后,border-radius:10px不起作用了,发现这个是css本身的问题,两者不能混在一起使用. 代 ...
- Codeforces Round #441 (Div. 2, by Moscow Team Olympiad) E. National Property(2-sat)
E. National Property time limit per test 1 second memory limit per test 512 megabytes input standard ...
- [SQL]196. Delete Duplicate Emails
Write a SQL query to delete all duplicate email entries in a table named Person, keeping only unique ...
- 【CF 453A】 A. Little Pony and Expected Maximum(期望、快速幂)
A. Little Pony and Expected Maximum time limit per test 1 second memory limit per test 256 megabytes ...
- Struts2的概念
Struts2的概念 Struts2是一个基于MVC设计模式的Web应用框架,它本质上相当于一个servlet,在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与视图的数 ...
- 排序算法之直接插入排序Java实现
排序算法之直接插入排序 舞蹈演示排序: 冒泡排序: http://t.cn/hrf58M 希尔排序:http://t.cn/hrosvb 选择排序:http://t.cn/hros6e 插入排序: ...
- 1 Scala基本概念 +IDE
Scala基本概念 +IDE 推荐:<Scala编程> 1 基本概念 在Spark开发中,Scala被认为是目前和Spark兼容最好的语言. Scala运行在标准的java平台,可以与ja ...
- hdu 4745 区间dp
题意:求一个环的最长回文序列,是序列不是串 链接:点我 起点是可以任意的, 所以只要求出每个区间的最长回文序列之后取max(dp[1][i]+dp[i+1][n]),即可得最终答案 本来是想扩展两倍的 ...
- 【10.7校内测试】【队列滑窗】【2-sat】【贪心+栈二分+线段树(noip模拟好题)】【生日祭!】
比较好想的一道题,直接用队列滑窗,因为扫一遍往队列里加东西时,改变的只有一个值,开桶储存好就行了! #include<bits/stdc++.h> using namespace std; ...
- cdoj 841 休生伤杜景死惊开 逆序数/树状数组
休生伤杜景死惊开 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) 陆伯言军陷八卦 ...