最近在重学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教程的更多相关文章

  1. [源码解析] 深度学习分布式训练框架 horovod (4) --- 网络基础 & Driver

    [源码解析] 深度学习分布式训练框架 horovod (4) --- 网络基础 & Driver 目录 [源码解析] 深度学习分布式训练框架 horovod (4) --- 网络基础 & ...

  2. [源码解析] 深度学习分布式训练框架 horovod (5) --- 融合框架

    [源码解析] 深度学习分布式训练框架 horovod (5) --- 融合框架 目录 [源码解析] 深度学习分布式训练框架 horovod (5) --- 融合框架 0x00 摘要 0x01 架构图 ...

  3. [源码解析] 深度学习分布式训练框架 horovod (7) --- DistributedOptimizer

    [源码解析] 深度学习分布式训练框架 horovod (7) --- DistributedOptimizer 目录 [源码解析] 深度学习分布式训练框架 horovod (7) --- Distri ...

  4. [源码解析] 深度学习分布式训练框架 horovod (8) --- on spark

    [源码解析] 深度学习分布式训练框架 horovod (8) --- on spark 目录 [源码解析] 深度学习分布式训练框架 horovod (8) --- on spark 0x00 摘要 0 ...

  5. [源码解析] 深度学习分布式训练框架 horovod (9) --- 启动 on spark

    [源码解析] 深度学习分布式训练框架 horovod (9) --- 启动 on spark 目录 [源码解析] 深度学习分布式训练框架 horovod (9) --- 启动 on spark 0x0 ...

  6. [源码解析] 深度学习分布式训练框架 horovod (18) --- kubeflow tf-operator

    [源码解析] 深度学习分布式训练框架 horovod (18) --- kubeflow tf-operator 目录 [源码解析] 深度学习分布式训练框架 horovod (18) --- kube ...

  7. OpenGL新手框架

    开始学习用OpenGL,也就想显示一些点,以为挺简单的,哎,看了两天才会画三维的点,做个总结. 使用OpenGL的基本流程 int main(int argv, char *argc[]) { //初 ...

  8. Java并发包源码学习之AQS框架(四)AbstractQueuedSynchronizer源码分析

    经过前面几篇文章的铺垫,今天我们终于要看看AQS的庐山真面目了,建议第一次看AbstractQueuedSynchronizer 类源码的朋友可以先看下我前面几篇文章: <Java并发包源码学习 ...

  9. Java并发包源码学习之AQS框架(三)LockSupport和interrupt

    接着上一篇文章今天我们来介绍下LockSupport和Java中线程的中断(interrupt). 其实除了LockSupport,Java之初就有Object对象的wait和notify方法可以实现 ...

随机推荐

  1. CSU - 2059 Water Problem

    Description ​ 一条'Z'形线可以将平面分为两个区域,那么由N条Z形线所定义的区域的最大个数是多少呢?每条Z形线由两条平行的无限半直线和一条直线段组成 Input 首先输入一个数字T(T& ...

  2. 移动端h5下ul实现横向滚动css代码

    html代码: <ul id="category"> <li>品牌团</li> <li>美体个护</li> <li ...

  3. 机器学习之路: python 朴素贝叶斯分类器 MultinomialNB 预测新闻类别

    使用python3 学习朴素贝叶斯分类api 设计到字符串提取特征向量 欢迎来到我的git下载源代码: https://github.com/linyi0604/MachineLearning fro ...

  4. Qt中文本编辑器实现语法高亮功能(Qscitinlla)

    Scintilla是一个免费.跨平台.支持语法高亮的编辑控件.它完整支持源代码的编辑和调试,包括语法高亮.错误指示.代码完成(code completion)和调用提示(call tips).能包含标 ...

  5. Django-url路由映射与views逻辑处理

    一.URL路由映射 路由映射模块,主要完成url与views视图函数的映射.当一个url请求到来时,会按照这个模块中的url地址从上到下进行匹配,如果匹配成功,将执行映射试图中的函数:反之将返回404 ...

  6. 王彪-20162321-Java程序设计与数据结构2nd-第十周学习总结

    学习目标 讨论有向图和无向图 定义带权图并讨论它们的应用 定义图的广度优先遍历和深度优先遍历 定义最小生成树 讨论图的实现策略 书中图的基本定义 图是由结点及结点间的连接组成的,结点称为顶点,结点间的 ...

  7. Curl 及 Curl的使用介绍

    Curl 简介 Curl是Linux下一个很强大的http命令行工具,其功能十分强大. 1) 二话不说,先从这里开始吧! $ curl http://www.linuxidc.com 回车之后,www ...

  8. 【8.14校内测试】【DP专题】

    nlogn做法,dp[i]表示当前长度为i的最长上升子序列末尾元素的值. 不会写lower_bound(qwq,贴一个以前的好看点的代码 #include<iostream>//使用low ...

  9. Codeforces Beta Round #37 A. Towers 水题

    A. Towers 题目连接: http://www.codeforces.com/contest/37/problem/A Description Little Vasya has received ...

  10. Caffe2(3)----下载现成的模型并使用

    Caffe2训练好的模型可在Model Zoo下载,下载的命令很简单,接下来以下载和使用squeezenet为例,进行简单说明. 1.浏览可下载的模型 已有模型都放在github上,地址:https: ...