Immediate
Mode: Multiple Objects
By: Jack Hoxley
Written: August 2000
Download:
IM_MultiObject.Zip
(12kb)
Despite the fact that this is
extremely simple, it caught me out first time around, and from the emails I
get it obviously catches out lots of other people. The problem: When you have
multiple sets of vertices, how do you make one move without the other? Basically
people are getting confused with how matrices work.
People are finding that when
they apply matrix-transformations to a scene it alters everything in the scene
- not just individual objects. The solution to this:
In this case we will have
3 sets of vertices - 3 cubes
1. Set up the matrix for
cube 1, with all modifications that are needed - but dont apply it to
the world
2. Set up the matrix for cube 2, do not apply it to the world
3. Set up the matrix for cube 3, do not apply it to the world
This next part goes between
the Device.BeginScene and the Device.EndScene calls
1. Use Device.SetTransform to apply Matrix 1
2. Use Device.DrawPrimative to render all the vertices that make up cube
1
3. Use Device.SetTransform to apply Matrix 2
4. Use Device.... to render Cube 2
5. Apply matrix 3 to the world
6. Render Cube 3
|
|
|
|
This simple formula will render
all your cubes with their own rotation/scale/translation properties - problem
solved. Two things to note: each matrix change overwrites the existing one -
if you had a matrix that moved -10 on the X axis, and then applied a matrix
that moved +10 on the X axis they wouldn't cancel each other out (ie, move back
to 0 in this case), when you alter the matrix the contents of the previous one
are irrelevant and do not afect the new one.
Assuming you followed that, but
aren't entirely sure what to do, try this code excerpt:
'These two are normally
in the (Declarations) Section
Const Pi as single = 3.14159
Const Rad as single = Pi/180
Dim MatCube1 as D3DMATRIX
Dim MatCube2 as D3DMATRIX
Dim MatCube3 as D3DMATRIX
Dim tmpMatrix as D3DMATRIX 'So we can have more
than one transformation
Dim vTemp as D3DVECTOR 'To hold translation vectors
Dim Angle as Integer 'To hold our rotations
'At this point I am assuming that all the vertices have been placed/created
' - and that this is the render section of the main game loop.
Angle = Angle + 1 'Rotate Slowly
If Angle > 360 then Angle = 0 'Loop the rotation
'###############
'## Setup Matrix 1 ##
'##############
Dx.RotateZMatrix MatCube1, Angle * Rad
vTemp.x = -10
TranslateMatrix tmpMatrix, vTemp
Dx.MatrixMultiply MatCube1, MatCube1,tmpMatrix
'###############
'## Setup Matrix 2 ##
'##############
Dx.RotateXMatrix MatCube2, Angle * Rad
'No need to translate the Matrix - I want it at
an X of 0
'###############
'## Setup Matrix 3 ##
'##############
Dx.RotateYMatrix MatCube3, Angle * Rad
vTemp.x=10
TranslateMatrix tmpMatrix,vTemp
Dx.MatrixMultiply MatCube3,MatCube3,tmpMatrix
'##################
'## Render The Scene ##
#################
Device.BeginScene
'Cube 1
Device.SetTransform D3DTRANSFORMSTATE_WORLD, MatCube1
Device.DrawPrimative D3DPT_TRIANGLESTRIP, D3DFVF_LVERTEX, Cube1(0), 4,
D3DDP_DEFAULT
'Cube 2
Device.SetTransform D3DTRANSFORMSTATE_WORLD, MatCube2
Device.DrawPrimative D3DPT_TRIANGLESTRIP, D3DFVF_LVERTEX, Cube2(0), 4,
D3DDP_DEFAULT
'Cube 3
Device.SetTransform D3DTRANSFORMSTATE_WORLD, MatCube3
Device.DrawPrimative D3DPT_TRIANGLESTRIP, D3DFVF_LVERTEX, Cube3(0), 4,
D3DDP_DEFAULT
Device.EndScene |
|
|
|
If you still dont follow, or
you want to see a working example - download it from the top of the page, or
from the downloads page.
|