Rapid-Q Documentation by William Yu (c)1999, John Kelly Appendix B: QD3DFACE

QD3DFACE Component

QD3DFace implements IDirect3DRMFace. A face is at least 3 vertices (1 vertex is an x,y,z point in space) that form a surface or plane. You give it the vertex data and QD3DFACE will generate the face for you. You can have a face with many vertices for a simple 3D shape, but  vertices turned "inward" will not always be rendered. The order of the vertices are important as D3D only renders the "front" face. See D3D_Details for more information. Once a face is made, you add it to a QD3DMeshBuilder object.

QD3DFace Properties
FieldTypeR/WDefault




VertexCountINTEGER Only returns the current QD3DfaceR

QD3DFace Methods
MethodTypeDescriptionParams




AddVertexSUB (X#, Y#, Z#)Add a vertex3
GetVertexSUB (Index AS LONG, Position AS QD3DVector, Normal AS QD3DVector)Retrieve the position and normal of a vertex3
SetColorRGBSUB (R#, G#, B#)Set face color3

QD3DFace Events
EventTypeOccurs when...Params






QD3DFace Examples
$TYPECHECK ON

'*******************************************************************************************
'  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!! This is called "backface culling"
' JohnK
'******************************************************************************************
'
$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

RANDOMIZE
CREATE Form AS QForm
     Caption = "Direct 3D Example - click or move mouse"
    Width = 640
    Height = 480
    Center
    CREATE DXScreen AS QDXScreen	'really a direct draw surface?
        Init(640,480)
        Align = 5			'alClient - need this to center Direct Draw screen onto Form
        BitCount = 24			'24 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
     END CREATE
 ShowModal						'get the program running
END CREATE


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 light
''	*********  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
	DXScreen.CreateLightRGB(D3DRMLIGHT_POINT, .8, .8, 0.1, Light)	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)
   DXScreen.SetRenderMode(D3DRMRENDERMODE_BLENDEDTRANSPARENCY)
END SUB

SUB DXTimerExpired
	LightFrame.SetPosition(Screen.MouseX/200, Screen.MouseY/200,  Screen.MouseY/200)
	DXScreen.ForceUpdate(0,0,50,40)     ' Update FPS text only
	DXScreen.Move(1)                    ' This does the rotation by 2 times
	DXScreen.Render
	DXScreen.TextOut(10,10,"FPS: "+STR$(DXTimer.FrameRate), &HFFFFFF, -1)
	DXScreen.Flip
END SUB

SUB ToggleRotation
	IF RotateIt THEN 
		MeshFrame.SetRotation(0, 0, 0, 0)
		RotateIt= 0 
	ELSE
		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
		DXScreen.CreateFace(Face)
		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

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

		DXScreen.CreateFace(Face)
		Face.AddVertex(MaxX, MaxY, 0)
		Face.AddVertex(-MaxX, MaxY, 0)
		Face.AddVertex(0, 0, .5)
		TheMeshBuilder.AddFace(Face)

		DXScreen.CreateFace(Face)
		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

Prev Component Contents Next Component