• 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

     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 "......WhyEngineYInterfaceWhyModuleAPI.h"
      4 #include "......InterfaceYicGLDevice.h"
      5 #include "......InterfaceYicGLFont.h"
      6 #include "......InterfaceYicGLPrimitive2DRender.h"
      7 #include <glgl.h>            // Header File For The OpenGL32 Library
      8 #include <glglu.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] = '
    ';
    120     c[2] = '
    ';
    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

     

  • 相关阅读:
    【leetcode】1365. How Many Numbers Are Smaller Than the Current Number
    【leetcode】1363. Largest Multiple of Three
    【leetcode】1362. Closest Divisors
    【leetcode】1361. Validate Binary Tree Nodes
    【leetcode】1360. Number of Days Between Two Dates
    【leetcode】1359. Count All Valid Pickup and Delivery Options
    【leetcode】1357. Apply Discount Every n Orders
    【leetcode】1356. Sort Integers by The Number of 1 Bits
    ISE应用入门的一些问题
    DDR的型号问题
  • 原文地址:https://www.cnblogs.com/WhyEngine/p/3632858.html
Copyright © 2020-2023  润新知