software / rapidq / Examples / Game / directx & direct3d / Lights motion / Lights_pyramid.bas

Search 搜索
Home Home

' 	 simple program demonstrating manual meshes built in DIRECT 3D in RapidQ
'	lights are moved by mouse by the QD3DFrame it is attached to
' Notice that each face of the polygon has one normal on the outside surface
' and is transparent on opposite side!!
' JohnK

     $TYPECHECK ON							'this will make you a better programmer in the end
     $INCLUDE "RapidQ_D3D.INC"		'constants

     DECLARE SUB DXInitialize(Sender AS QDXSCREEN)		'initalize Direct3D Retained mode interface
     DECLARE SUB DXInitializeSurface(Sender AS QDXSCREEN)'initialize Direct Draw surface
     DECLARE SUB DXTimerExpired
     DECLARE SUB MakePyramidMesh (TheMeshBuilder AS QD3DMESHBUILDER)
     DECLARE SUB ToggleRotation

     DIM DXTimer AS QDXTIMER					'regularly update display
     DXTimer.Enabled = 1
     DXTimer.Interval = 0
     DXTimer.Activeonly = 0
     DXTimer.OnTimer = DXTimerExpired

     DIM MeshFrame AS QD3DFRAME			'possible for root frame all 3d objects should be attached to a frame
     DIM LightFrame AS QD3DFRAME			'lights must be placed on a frame. Camera is attached to a frame by RapidQ for you
     DIM MeshBuilder AS QD3DMESHBUILDER	'mesh builder to create a mesh out of the face
     DIM i AS SINGLE						'increment a translation
     DIM RotAngl AS SINGLE : RotAngl = 0.03
     DIM RotateIt AS SINGLE: RotateIt = 0 ' toggle on/off rotation

      CAPTION = "Direct 3D Example - click or move mouse"
      Width = 640
      Height = 480
      CREATE DXScreen AS QDXSCREEN	'really a direct draw surface?
       Align = 5					'alClient - need this to center Direct Draw screen onto Form
       BitCount = 16				'16 bits/pixel use 32 for alpha bending on fast 3d cards
       Use3D = 1					'load Direct3D Retained mode
       UseHardware = 1				'get real!! 3D accelerated video cards are cheap
       OnInitialize = DXInitialize					'load your meshs/faces to the frames, set lights, camera
       OnInitializeSurface = DXInitializeSurface	'screen is ready to be drawn
       OnMouseDown = ToggleRotation					'mouse click stops/starts rotation
      SHOWMODAL						'get the program running

     SUB DXInitialize(Sender AS QDXSCREEN)
      DIM Ambient AS QD3DLIGHT			'need at least one light this can be local sub-- we won't modify it
      DIM Light AS QD3DLIGHT				'will define as point ligth that gives rich illumination to see the walls

''		*********  First we create the Frames  ******************
      DXScreen.CreateFrame(MeshFrame)		'create the frames objects will be attached to
      DXScreen.CreateFrame(LightFrame)	'probably allocates memory, handles, etc
      DXScreen.CreateMeshBuilder(MeshBuilder)	' all DXscreen.CreateXX are actually functions and return err codes!!

''		*********  next create the lights  ******************
      DXScreen.CreateLightRGB(D3DRMLIGHT_AMBIENT, 0.2, 0.2, 0.3, Ambient)	'ambient is dim grey
      DXScreen.AddLight(Ambient)			'ambient light moves with root frame (and object since it is on root frame)
      DXScreen.CreateLightRGB(D3DRMLIGHT_POINT, .8, .8, 0.1, Light)		'point light is bright yellow, units depend on MeshBuilder.SetRGB(1, 1, 1)
      LightFrame.AddLight(Light)			'attach light to frame to move the light
      LightFrame.SetPosition(0, 2, -1)			'position the point light, units are x,y,z

      MakePyramidMesh(MeshBuilder)				'create your own mesh
      MeshBuilder.SetRGB(1, 1, 1)					'reflects all light on it
      MeshBuilder.SetQuality(D3DRMRENDER_GOURAUD)	'highest rendering Quality is D3DRMRENDER_PHONG, but not much diff
      MeshFrame.AddVisual(MeshBuilder)			'add it to a frame to move, translate, etc.
      MeshFrame.SetRotation(0, 0, 0,RotAngl)		' Angle of rotation on center for the planes we just made
      DXScreen.SetCameraPosition(1.5, 2, 0)		'you can move the camera around instead of rotating 3d object
      DXScreen.CameraLookAt(MeshFrame, D3DRMCONSTRAIN_Z)			'constrain the angle that the camera looks at
     END SUB

     SUB DXInitializeSurface(Sender AS QDXSCREEN)
     END SUB

     SUB DXTimerExpired
      LightFrame.SetPosition(Screen.MOUSEX/200, Screen.MOUSEY/200,  Screen.MOUSEY/200)	'units are x,y,z
      DXScreen.ForceUpdate(0,0,50,40)     ' Update FPS text only
      DXScreen.Move(1)                    ' This does the rotation by 2 times
      DXScreen.TextOut(10,10,"FPS: "+STR$(DXTimer.FrameRate), &HFFFFFF, -1)
     END SUB

     SUB ToggleRotation
      IF RotateIt THEN
       MeshFrame.SetRotation(0, 0, 0, 0)
       RotateIt= 0
       MeshFrame.SetRotation(0, 0, 0, RotAngl)		' rotate on center, Angle of rotation is variable
       LightFrame.SetPosition(-1, 2, 0)			'units are x,y,z
       RotateIt = 1
      END IF
     END SUB

     SUB MakePyramidMesh (TheMeshBuilder AS QD3DMESHBUILDER)
''		*********  next create a pyramid of 3-sided polygons  ******************

      DIM MaxX AS DOUBLE, MaxY AS DOUBLE			'terrain dimension
      DIM Face AS QD3DFACE						'won't modify in main program so just declare it in sub
      MaxX = .5: MaxY = .5
      Face.AddVertex(-MaxX, -MaxY, 0)
      Face.AddVertex(MaxX, -MaxY, 0)
      Face.AddVertex(0, 0, .5)
      TheMeshBuilder.AddFace(Face)				'make 3-sided polygons on the face into a mesh for rendering

      Face.AddVertex(MaxX, -MaxY, 0)
      Face.AddVertex(MaxX, MaxY, 0)
      Face.AddVertex(0, 0, .5)
      TheMeshBuilder.AddFace(Face)				'work in a counter-clockwise fashion

      Face.AddVertex(MaxX, MaxY, 0)
      Face.AddVertex(-MaxX, MaxY, 0)
      Face.AddVertex(0, 0, .5)

      Face.AddVertex(-MaxX, MaxY, 0)
      Face.AddVertex(-MaxX, -MaxY, 0)
      Face.AddVertex(0, 0, .5)
      TheMeshBuilder.AddFace(Face)			'these are not OPTIMIZED faces since they share vertices
     END SUB
© Sat 2023-3-25  Guidance Laboratory Inc. Hits:0 Last modified:2004-01-20 14:02:59