Rapid-Q Documentation by William Yu (c)1999 Глава 13


13. Direct3D в Rapid-Q

Это только введение в использование Direct3D совместно с Rapid-Q. Поскольку большинство 3-D компонентов для Rapid-Q не закончено в данной главе описывается только то, что уже работает.

13.1 Требования (Requirement specifications)
Основное требовагие, чтобы был установлен DirectX 6.0. или выше. Используйте DXDIAG чтобы проверить, какая весия установлена.

13.2 Использование Anim8or для создания 3D моделей
Если вы хорошо понимаете процесс создания 3D моделей вы можете пропустить этот раздел. Ниже я расскажу о создании простых 3D моделей для использования в Rapid-Q с помощью Anim8or.

If you don't like doing your own 3D models you can always download pre-made 3D models from www.3dcafe.com and other websites like it. However, it's always nice to customize your objects, so learning to use a 3D modeling program wouldn't hurt. The optional parameter -m is used to create a single mesh for use with MeshBuilder. Without -m, your .X file is saved as a frame so you would have to use QD3DFrame to load your .X file.

13.3 Загрузка и использование .X файлов (Loading/Using .X Files)
Simply loading an .X file is easy enough, to make sure you have this much working, copy and paste this code:
' Simply places an object on the scene

$TYPECHECK ON

CONST alClient = 5

'-- Light Types
CONST D3DRMLIGHT_AMBIENT = 0
CONST D3DRMLIGHT_POINT = 1
CONST D3DRMLIGHT_SPOT = 2
CONST D3DRMLIGHT_DIRECTIONAL = 3
CONST D3DRMLIGHT_PARALLELPOINT = 4

DECLARE SUB DXInitialize(Sender AS QDXScreen)
DECLARE SUB DXTimerExpired

DIM DXTimer AS QDXTimer
    DXTimer.Enabled = 1
    DXTimer.Interval = 0
    DXTimer.Activeonly = 0
    DXTimer.OnTimer = DXTimerExpired

CREATE Form AS QForm
    Caption = "Direct 3D Пример"
    Center
    CREATE DXScreen AS QDXScreen
        Init(320,240)
        Align = alClient
        Use3D = 1
        UseHardware = 0        '' This is for non-3D accelerated video cards.
                               '' 3D will be emulated using software, which
                               '' is much slower.
        OnInitialize = DXInitialize
    END CREATE
    ShowModal
END CREATE


SUB DXInitialize(Sender AS QDXScreen)
   DIM Light AS QD3DLight
   DIM LightFrame AS QD3DFrame, MeshFrame AS QD3DFrame
   DIM MeshBuilder AS QD3DMeshBuilder

   DXScreen.CreateFrame(LightFrame)
   DXScreen.CreateFrame(MeshFrame)

   '-- Need light, else object would be completely hidden
   DXScreen.CreateLightRGB(D3DRMLIGHT_DIRECTIONAL, 0.9, 0.9, 0.9, Light)
   LightFrame.AddLight(Light)

   DXScreen.SetCameraPosition(-5, 10, 0)
   DXScreen.SetCameraOrientation(0.35, -0.65, 1.0, -0.15, 1.0, 0.5)

   MeshFrame.SetPosition(0, 0, 15)
   MeshFrame.SetOrientation(0, 0, 1, 0, 1, 0)
   MeshFrame.SetRotation(0, 0, 0, 0.05)     '-- Angle of rotation = 0.05

   DXScreen.CreateMeshBuilder(MeshBuilder)  '-- Create object

   MeshBuilder.Load("poly.x")               '-- Load your object
   MeshFrame.AddVisual(MeshBuilder)         '-- Add object to frame
END SUB

SUB DXTimerExpired
   DXScreen.ForceUpdate(0,0,50,50)   '-- Updates FPS Text
   DXScreen.Render
   DXScreen.TextOut(10,10,"FPS: "+STR$(DXTimer.FrameRate), &HFFFFFF, -1)
   DXScreen.Flip
END SUB
If everything worked, you should obtain some output that looks like this:
If you understood the example, it's quite easy to add more objects to the scene, just create another MeshFrame and load another object file. Play around with the code until you're satisfied.

13.4 Использованеи текстур (Wrapping textures around an object)
Now that we have the basics, time to wrap textures around our object. To do this, all we need is a .BMP file for our texture. There's a few important points to note, First, width and height of bitmap must be equal, and secondly, they must be powers of 2 (ie. 32x32, 256x256, etc.). This is obviously for optimization reasons, but don't ask me, I didn't create Direct3D. Anyway, to wrap this texture around our object, we just need to modify the above code a bit (changes are noted in Blue):
' Wrap textures around 3D object

$TYPECHECK ON

CONST alClient = 5

'-- Light Types
CONST D3DRMLIGHT_AMBIENT = 0
CONST D3DRMLIGHT_POINT = 1
CONST D3DRMLIGHT_SPOT = 2
CONST D3DRMLIGHT_DIRECTIONAL = 3
CONST D3DRMLIGHT_PARALLELPOINT = 4

'-- Wrap Types
CONST D3DRMWRAP_FLAT = 0
CONST D3DRMWRAP_CYLINDER = 1
CONST D3DRMWRAP_SPHERE = 2
CONST D3DRMWRAP_CHROME = 3
CONST D3DRMWRAP_SHEET = 4
CONST D3DRMWRAP_BOX = 5

CONST WrapType = D3DRMWRAP_SPHERE     '-- You can modify this

DECLARE SUB DXInitialize(Sender AS QDXScreen)
DECLARE SUB DXTimerExpired

DIM DXTimer AS QDXTimer
    DXTimer.Enabled = 1
    DXTimer.Interval = 0
    DXTimer.Activeonly = 0
    DXTimer.OnTimer = DXTimerExpired

CREATE Form AS QForm
    Caption = "Direct 3D Пример"
    Center
    CREATE DXScreen AS QDXScreen
        Init(320,240)
        Align = alClient
        Use3D = 1
        UseHardware = 0        '' This is for non-3D accelerated video cards.
                               '' 3D will be emulated using software, which
                               '' is much slower.
        OnInitialize = DXInitialize
    END CREATE
    ShowModal
END CREATE


SUB DXInitialize(Sender AS QDXScreen)
   DIM Light AS QD3DLight
   DIM LightFrame AS QD3DFrame, MeshFrame AS QD3DFrame
   DIM MeshBuilder AS QD3DMeshBuilder
   DIM Texture AS QD3DTexture
   DIM Wrap AS QD3DWrap
   DIM Mesh AS QD3DMesh


   DXScreen.CreateFrame(LightFrame)
   DXScreen.CreateFrame(MeshFrame)

   DXScreen.CreateLightRGB(D3DRMLIGHT_DIRECTIONAL, 0.9, 0.9, 0.9, Light)
   LightFrame.AddLight(Light)


   DXScreen.SetCameraPosition(-5, 10, 0)
   DXScreen.SetCameraOrientation(0.35, -0.65, 1.0, -0.15, 1.0, 0.5)

   MeshFrame.SetPosition(0, 0, 15)
   MeshFrame.SetOrientation(0, 0, 1, 0, 1, 0)
   MeshFrame.SetRotation(0, 0, 0, 0.05)       ' Angle of rotation = 0.05

   DXScreen.CreateMeshBuilder(MeshBuilder)

   MeshBuilder.Load("poly.x")            '-- Egg object

   MeshBuilder.LoadTexture("back.bmp")   '-- New lines
   MeshBuilder.CreateMesh(Mesh)

   MeshFrame.AddVisual(Mesh)

   DXScreen.CreateWrap(WrapType, 0,0,0, 0,0,1, 0,1,0, 0,0, 1,1, Wrap)
   Wrap.Apply(Mesh)

END SUB

SUB DXTimerExpired
   DXScreen.ForceUpdate(0,0,50,50)
   DXScreen.Render
   DXScreen.TextOut(10,10,"FPS: "+STR$(DXTimer.FrameRate), &HFFFFFF, -1)
   DXScreen.Flip
END SUB
Again, if everything worked, you should obtain some output that looks like this (depending on what texture file you used of course):

As you can see, it doesn't take much to add textures to our objects. The only problem is you lose a few frame rates by doing this.

13.5 Rotating/Moving objects
Unfortunately as of this writing, there is no support for Animation sets, but that will be worked on later. You can do simple rotations and scene movements just by calling the method Move or manually setting the camera angles and positions. Using the example from above, add this extra code:

   DXScreen.ForceUpdate(0,0,50,50)
   DXScreen.Move(1)            '-- Add this line
   DXScreen.Render
This moves the camera position by the amount specified. The affect is a rotation about angle Theta. This Theta was specified on the line:
   MeshFrame.SetRotation(0, 0, 0, 0.05)       ' Angle of rotation = 0.05
DXScreen.Move animates the entire scene, to just animate a certain frame, you can use MeshFrame.Move(1).


Prev Глава Содержание Next Глава