65.9K
CodeProject 正在变化。 阅读更多。
Home

探索 3D

starIconstarIconstarIconstarIconstarIcon

5.00/5 (4投票s)

2013年8月13日

CPOL

7分钟阅读

viewsIcon

27034

基于 OpenGL 的 3D 学习软件。

探索 3D 桌面软件

探索 3D 软件将针对教育类别,用于 Windows 8 平板电脑。其目的是让学生(和成人)从较低层次探索 3D,允许他们使用 3D 脚本语言,以及通过触摸或鼠标拖放来处理 3D。

其目的是帮助学生掌握三维建模的基本概念。这将通过软件中的两种不同方法来实现。

首先,将是一种低级别的 3D 基元定义脚本语言。这将允许学生通过组合多个 3D 基元来定义简单的 3D 模型。这将使学生更好地理解 3D 对象是如何在 3D 坐标系(X,Y,Z)中使用他们可以输入的 3D 坐标定义的。这些对象可以组合起来创建更复杂的模型。

例如,使用非常简单的 3D 基元可以创建更复杂的模型。

这是一个使用 3D 基元定义上述模型的简单脚本。

{P}1(-75, 40,-200)  2(-75, 40,200)  3(-75, 40,0)
   4(-75,-30,-200)  5(-75,-30,200)  6(-75,-30,0)
   7(100,-30,0)     8(-100,-30,0)   9(-180,-30,0)
  10(190,0,0)      11(-120, 5,150) 12(-120, 5,-150)
  13(-20, 5,150)   14(-20, 5,-150) 15(-120, 5,50)
  16(-120, 5,-50)  17(-20, 5,50)   18(-20, 5,-50)
  19(175,-30,-75)  20(175,-30,75)  21(175,-30,0)

WINGS:

{W}(1,.05,1)
{M}(1)
{C}(100,100,30,10,400,3)
{X}(1){D}(100,0,30,10,1)
{X}(0){D}(100,0,30,10,2)
{C}(100,100,30,10,400,6)
{X}(1){D}(100,0,30,10,4)
{X}(0){D}(100,0,30,10,5)

TAIL:

{W}(.5,.05,1)
{C}(100,100,30,10,150,21)
{X}(1){D}(100,0,30,10,19)
{X}(0){D}(100,0,30,10,20)

FUSELAGE:

{M}(2)
{W}(.5,.6,1)
{X}(2){C}(50,10,30,10,250,7)
{X}(2){C}(50,50,30,10,150,8)
{X}(0)
{W}(2,.6,.5)
{S}(50,12,12,9)

RUDDER:

{W}(.6,1,.1)
{S}(50,12,12,10)

WING STRUTS:


{W}(1,1,1)
{X}(4)
{M}(3)
{C}(3,3,6,6,78,11)
{C}(3,3,6,6,78,12)
{C}(3,3,6,6,78,13)
{C}(3,3,6,6,78,14)
{C}(3,3,6,6,78,15)
{C}(3,3,6,6,78,16)
{C}(3,3,6,6,78,17)
{C}(3,3,6,6,78,18)

首先通过定义点的坐标,然后使用这些点来定义三角形、四边形(矩形)、圆盘、球体和圆柱体,可以创建更复杂的模型。可以定义材质 ID,以及一些对象的缩放和旋转。

STL 3D 原型模型

为了更好地理解 3D 的强大功能,软件的第二个特点是能够显示 STL 文件格式的复杂 3D 模型。与游戏中使用的 3D 模型格式(通过低多边形模型和高质量纹理贴图来“伪造”真实感)不同,STL 文件格式旨在显示高多边形模型,即使只有单一颜色,也能仅仅通过高多边形数量获得真实感。STL 格式用于 3D 打印中的快速原型制作。虽然该软件的初始设计仅用于显示 STL 模型,但未来版本可以利用即将添加到 Windows 8.1 的 3D 打印功能。不过,对于本次比赛,只支持显示功能。

该软件将设计为支持快速加载和显示高多边形 STL 模型,即使在许多 Windows 8 平板电脑中使用的 Atom CPU 等最低硬件上也能实现。该软件将能够在几秒钟内加载并显示包含数十万个多边形(三角形)的 3D 模型。即使是包含数百万个多边形的模型,也能在非常合理的时间内加载并显示。例如,在配备 3.2 GHz Pentium D CPU(双核)和常见 50 美元左右现成 3D 显卡的旧 PC 上进行测试时,一个包含超过 200 万个多边形的 3D 模型可以在不到 5 秒的时间内加载并立即显示(每秒几帧)。

目标

该软件将从更实际的角度鼓励人们对 3D 建模产生兴趣并加深理解。它将鼓励 3D 建模在商业和教育中的应用(实际用途),而不是从游戏角度。低级 3D 基元脚本语言将促进对 3D 坐标系以及 3D 模型如何由许多简单多边形组成的更好理解。它还将提高对 3D 空间中 3D 对象(透视)的理解。

软件的 STL 3D 部分将增进对 3D 建模在实际应用(例如商业、3D 原型制作、3D 打印)中应用的理解和更好地欣赏。

软件开发

该软件分两个阶段开发。第一阶段基本完成(只计划进行一些小更新以添加 Windows 8 触摸功能)。软件的第一阶段是使用纯 WIN32 编程和 PowerBasic 本机代码编译器创建的。这会生成能够直接访问 Windows 中本机 WIN32 API 的 32 位软件。这允许构建动态软件,能够根据运行的 Windows 版本进行自我更改。这意味着该软件将运行在从 Windows XP 到 Windows 8 的所有 Windows 版本上(实际上甚至更早的版本也支持)。

第一阶段是构建一个完整的 GUI 引擎,它取代了直接访问 Windows API 的需要。该 GUI 引擎有以下目标:

  • 在从 XP 到 Windows 8 的多个 Windows 版本上运行
  • 只使用 WIN32 API,因此不需要 .NET 运行时
  • 专为最低配置硬件设计(内存小于 1 GB,CPU 频率 1 GHZ 或更高)
  • 无需 Direct-X,但基于 SOC(片上系统)常见的 OpenGL 2.0 标准(用于 3D)
  • 专为最小硬盘空间设计,尤其是固态硬盘 (SSD)
  • GUI 引擎的核心运行时将以 DLL 格式存在,大小约为 1 MB(无需 COM)
  • 支持所有基本本机窗口类(控件),包括最常见的控件和富文本框
  • 支持通用对话框

此 GUI 引擎旨在取代对 Windows API 的所有访问需求。软件的所有 GUI 功能都在 GUI 引擎中。

第二阶段将使用上述 GUI 引擎构建实际应用程序,实现所有 GUI 功能(包括 OpenGL 3D),并结合其自己的可视化设计器(拖放)进行代码生成,以及 PowerBasic 编译器。

所使用的 GUI 引擎并非第三方工具,而是由该开发人员(本文作者)在过去十年中从头完整设计的,是一个包含专有代码的商业产品。它是纯粹使用 PowerBasic 编译器和 Windows WIN32 API(以及 OpenGL 2.0 API)开发的。由于该工具拥有自己的可视化设计器/代码生成器(使用 GUI 引擎构建),因此本文讨论的应用程序可以在短时间内快速原型化。最终应用程序可执行文件将至少分发两个核心运行时 DLL,运行时总大小小于 1 兆字节。

该应用程序不需要任何组件安装(例如 COM 组件),也不需要任何 Microsoft 编译器运行时,也不需要任何 .NET 运行时。该应用程序也将是可移植的,这意味着它可以简单地复制并运行。例如,该应用程序可以很容易地从硬盘复制到 USB 驱动器并从 USB 驱动器运行。它甚至应该能够从 Microsoft SkyDrive 文件夹运行。

该软件将使用 PowerBasic 编译器EZGUI 5.0 Professional(由本文作者开发)进行开发。

代码

最初的 GUI 代码(表单和控件)将使用 EZGUI 5.0 可视化设计器(也由本文作者编写)进行原型设计。这将允许应用程序的快速原型设计。OpenGL 功能将由 EZGUI 运行时库中的 glCanvas 控件实现。该控件是一个混合控件,它将 2D 画布控件与顶部的 OpenGL 3D 层(用于 3D 对象)合并。glCanvas 控件的编码只需向其发送包含该控件支持的内置 3D 脚本语言的字符串命令即可。这是我创建的一个简单 3D 演示的一些示例代码

GLOBAL App_My3DModel$

SUB InitModel()
     LOCAL T$
     T$="{P}1(-75, 40,-200)  2(-75, 40,200)  3(-75, 40,0)"
     T$=T$+"4(-75,-30,-200)  5(-75,-30,200)  6(-75,-30,0)"
     T$=T$+"7(100,-30,0)     8(-100,-30,0)   9(-180,-30,0)"
     T$=T$+"10(190,0,0)      11(-120, 5,150) 12(-120, 5,-150)"
     T$=T$+"13(-20, 5,150)   14(-20, 5,-150) 15(-120, 5,50)"
     T$=T$+"16(-120, 5,-50)  17(-20, 5,50)   18(-20, 5,-50)"
     T$=T$+"19(175,-30,-75)  20(175,-30,75)  21(175,-30,0)"
     T$=T$+"{W}(1,.05,1){M}(1){C}(100,100,30,10,400,3)"
     T$=T$+"{X}(1){D}(100,0,30,10,1){X}(0){D}(100,0,30,10,2)"
     T$=T$+"{C}(100,100,30,10,400,6){X}(1){D}(100,0,30,10,4)"
     T$=T$+"{X}(0){D}(100,0,30,10,5){W}(.5,.05,1)"
     T$=T$+"{C}(100,100,30,10,150,21){X}(1){D}(100,0,30,10,19)"
     T$=T$+"{X}(0){D}(100,0,30,10,20){M}(2){W}(.5,.6,1)"
     T$=T$+"{X}(2){C}(50,10,30,10,250,7){X}(2){C}(50,50,30,10,150,8)"
     T$=T$+"{X}(0){W}(2,.6,.5){S}(50,12,12,9){W}(.6,1,.1){S}(50,12,12,10)"
     T$=T$+"{W}(1,1,1){X}(4){M}(3){C}(3,3,6,6,78,11){C}(3,3,6,6,78,12)"
     T$=T$+"{C}(3,3,6,6,78,13){C}(3,3,6,6,78,14){C}(3,3,6,6,78,15){C}(3,3,6,6,78,16)"
     T$=T$+"{C}(3,3,6,6,78,17){C}(3,3,6,6,78,18)"
     EZ_DoGL "DMain", %DMAIN_GLCANVAS1, "NEWMODEL <USER1>"+T$
END SUB

SUB Change3DStuff()
     LOCAL J&
     STATIC IFlag&
     STATIC Distance!, DPlus!
     IF IFlag&=0 THEN
          IFlag&=1
          EZ_DoGL "DMain", %DMAIN_GLCANVAS1,"LIGHTYX 45,45|
            LIGHTZ 1000|LIGHTAD 40,60|LIGHT2 1|LIGHT2YX 315,45|LIGHT2Z 1000|LIGHT2AD 20,30"
          EZ_DoGL "DMain", %DMAIN_GLCANVAS1,"QALL 1|BGCOLOR "+STR$(RGB(0,32,64))
     END IF
     IF Distance!=0 THEN
         Distance!=20
         DPlus!=.1
     END IF
     Distance!=Distance!+DPlus!
     IF Distance!<15 THEN
         Distance!=15
         DPlus!=.1
     END IF
     IF Distance!>50 THEN
         Distance!=50
         DPlus!=-.1
     END IF
     EZ_DoGL "DMain", %DMAIN_GLCANVAS1,"PERSPECTIVE "+STR$(Distance!)

    STATIC RD!, RD1!
    RD=RD+2
    IF RD>360 THEN RD=0

    RD1!=RD1!+1
    IF RD1!>360 THEN RD1!=0

    IF EZ_StartGL("DMain", %DMAIN_GLCANVAS1) THEN
         EZ_GL "ROTATE 1000,"+STR$(RD)+","+STR$(RD)+",0"
         EZ_GL "SROTATE 1000,0,"+STR$(RD1)+",0"
         EZ_GL "ROTATE 1001,"+STR$(RD)+","+STR$(RD)+",0"
         EZ_GL "SROTATE 1001,0,"+STR$(RD1)+",0"
         EZ_GL "ROTATE 1002,0,"+STR$(RD)+",0"
         EZ_GL "SROTATE 1002,0,"+STR$(RD1)+",0"
         EZ_GL "ROTATE 1003,0,"+STR$(RD)+",0"
         EZ_GL "SROTATE 1003,0,"+STR$(RD1)+",0"
         EZ_GL "ROTATE 1004,0,"+STR$(RD)+",0"
         EZ_GL "SROTATE 1004,0,"+STR$(RD1)+",0"
         EZ_GL "ROTATE 1005,0,"+STR$(360-RD)+",0"
         EZ_GL "SROTATE 1005,0,"+STR$(RD1)+",0"
         EZ_GL "ROTATE 1006,0,"+STR$(RD)+",0"
         EZ_GL "SROTATE 1006,0,"+STR$(RD1)+",0"
         EZ_EndGL
    END IF
END SUB

SUB InitObjects()
     LOCAL J&, T$, P$
     IF EZ_StartGL("DMain", %DMAIN_GLCANVAS1) THEN
          ' last paramater of LOADNEW command is as follows:
          ' 1 - AutoScale to Resize Object to aproximately window size
          ' 2 - AutoScale and swap X,Y axis
          ' 3 - AutoScale and swap X,Y axis and autogen Normals
          ' 4 - AutoScale and autogen Normals
          EZ_GL "BGMODE 0"
          EZ_GL "MATPAT 990,&H0088FF,100,100,6,0,8"
          EZ_GL "DEFPAL 2,81,82,83,84,85,111"
          EZ_GL "ADD CUBE, 1000, -100,50,0, 1,1,1,38,0"
          EZ_GL "MAT 1000,2,2"
          EZ_GL "SCALE 1000,.33,.33,.33"
          EZ_GL "ALIAS 1000,1"
          EZ_GL "ADD USER1,1001, 125,50,0, 1,1,1,35,1"     ' 81
          EZ_GL "SCALE 1001,.5,.5,.5"
          EZ_GL "ADD CUBE,1002,-100,-50,0, .5,1,.25,81,0"
          EZ_GL "SCALE 1002,3.0,.25,.25"
          EZ_GL "WIRE 1002, 1"
          EZ_GL "LWIDTH 1002, 3.0"
          EZ_GL "ALIAS 1002,1"
          EZ_GL "ADD SPHERE_Q,1003,125,-50,0, 1,1,1,89,0"     ' 74
          EZ_GL "SCALE 1003,.25,.25,.25"
          EZ_GL "ADD CONE_C,1004,0,-50,-95,1,1,1,74,0"
          EZ_GL "SCALE 1004,.25,.25,.25"
          EZ_GL "ALIAS 1004,1"
          EZ_GL "ADD SPHERE_F,1005,-140,-50,50, 1,1,1,75,0"
          EZ_GL "SCALE 1005,.33,.33,.33"
          EZ_GL "WIRE 1005,1"
          EZ_GL "ALIAS 1005,1"
          EZ_GL "ADD MOON,1006,125,-50,0, 1,1,1,77,0"
          EZ_GL "SCALE 1006,.25,.25,.25"
          EZ_EndGL
     END IF
END SUB
'<<END>>

GLOBAL App_Show3DObjects&
GLOBAL App_3DSpeed&

SUB DMAIN_GLCANVAS1_Events( MyID&, CMsg&, CVal&, Cancel&)
 SELECT CASE CMsg&
  CASE %EZ_Click
  CASE %EZ_Loaded
       InitModel
       Change3DStuff
       InitObjects
       App_Show3DObjects&=0
       EZ_StartPrivateTimer "{ME}", MyID&,1
  CASE %EZ_PTimer
       IF App_Show3DObjects& THEN
            LOCAL N&
            IF App_3DSpeed&<=0 THEN App_3DSpeed&=1
            FOR N&=1 TO App_3DSpeed&
                 Change3DStuff
                 EZ_RedrawControl "{ME}",MyID&
            NEXT N&
       END IF
 END SELECT
END SUB

由于 OpenGL 是通过真实的自定义窗口类(控件)实现的,这意味着应用程序不必仅仅是一个 OpenGL 窗口。该应用程序将是一个真正的多窗口应用程序(类似于使用 Microsoft 语言中的 WinForms 可能实现的效果),可以根据需要拥有任意数量的 OpenGL 控件实例。例如,可以使用一个 OpenGL 控件定义材质库,而另一个 OpenGL 控件将显示当前的 3D 世界,另一个则可用于显示正在使用的单个模型。挑战在于使平板电脑用户和触摸屏的用户界面舒适。此外,该应用程序将设计为可扩展,利用 GUI 引擎中内置的自动调整大小引擎。

开发者

该软件的开发者是 Chris Boss,一家小型独立编程工具公司的所有者,该公司主要面向 PowerBasic 程序员。他于 1975 年首次接触编程,并在 1990 年代创办了自己的定制编程业务。他从事 WIN32 程序员已有十多年,一直使用 PowerBasic,他的主要产品是 EZGUI 开发系统。EZGUI 由两部分组成。首先是一个 GUI 引擎,它取代了直接访问 WIN32 API 的需要。该引擎不仅支持所有基本的 GUI 功能(表单、控件、通用对话框等),还支持内置的拖放引擎(用于构建可视化设计器)、低级功能(例如子类化、所有者绘制、超类化、线程)、许多自定义控件,包括带有低级 DIB 引擎和专有 2D 精灵引擎的 Canvas 控件,带有内置专有 3D 脚本语言的基于 OpenGL 的 Canvas 控件,一个 MCI 控件,Properties Listbox 控件等等。EZGUI 被许多商业公司用于开发商业软件。

© . All rights reserved.