|
Introduction
This tutorial will be based off the previous tutorial (Transparent
Sprites), so load that project right up (you can download the source
here
if you got lost before). You'll
learn one of the most crucial aspects of Direct3D: Transformations.
The best way to show you what transformations are is through
example.
World Space - We've been using it!
So far, we've been using
World Space. Yeah yeah you might be wondering what world space is.
I'll get to it soon. Just note down this sentence:
An object in world space is untransformed.
Don't worry about why...etc yet. I'll show you by example.
Just delete any traces of alex2 in GameClass, we don't need him. So
don't dim him, don't instantiate him, and don't render him (and
don't transform the world before rendering him either, so delete x2
and y2). <-- I'm assuming you're using my Transparent Sprites
tutorial as a base for this one, and in that tutorial there are
unneeded variables and objects for this tutorial, so I'm asking you
to delete them.
World Space - What is it?
Alright, now we'll get to
what it is. First run your program, note down the position of alex
(should be on the top-left).
Now let's make some changes. In GameClass.Initialize, change:
D3Ddev.Transform.View =
Matrix.OrthoOffCenterLH(0, DP.Width, DP.Height, 0, 1, 10)
to
D3Ddev.Transform.View =
Matrix.OrthoOffCenterLH(0 - 100, DP.Width - 100, DP.Height - 100,
0 - 100, 1, 10)
Remember, the arguments we
changed (underlined above) represent what you can see on the screen.
First argument is Left (the left boundary of the screen), we just
moved it 100 units to the left. Second argument is Right, we moved
it 100 units to the left. 3rd argument is bottom, we moved it 100
units up. Fourth argument is top, we just moved it 100 units up.
Take a piece of paper and draw a square on it. Now draw an X on the
top-left of the square (inside the square of course, the X
represents the character). Draw another square, slightly to
the left of it and slightly above it.
Now try to imagine the character's position relative to the first
square you drew. He's on the top left. Easy. This first square
represents our first view matrix (before we changed it).
Next, look at the character's position relative to the second
square you drew. He just shifted over to the right and down. The
second square represents the second view matrix, shifted up and left
100 units.
Run your program. This is exactly what happens to our character. The
character is still at position 0,0. However, in reality - if you
looked at the actual screen, his position would be 100,100.
We are drawing our alex in the world at position 0,0, but in
the screen his position is 100,100. [Starting to catch on?]
To draw alex in his proper position in the world, Direct3D
transforms him to the screen coordinates of 100,100.
To make the world coordinates
and the screen coordinates the same, set the dimensions of the view
matrix (which represents what you can see in the world) to the
screen dimensions, like so:
D3Ddev.Transform.View =
Matrix.OrthoOffCenterLH(0, DP.Width, DP.Height, 0, 1, 10)
In the 'first' view matrix (the one listed right above), (0,0) was
the same on the world as it was in the screen.
Alright, in 3D (not in this
tutorial), we're going to be working with Z values. Our monitors
cannot physically display depth, this is obvious....
Direct3D gives our monitor a 2d representation of a 3d image when
doing 3d.
For example, take a box. A box is 3d. If you wanted to represent the
box on paper (aka draw it), then you would have to draw a 2d
representation of the 3d image. No matter how much the cube or box
that you drew on the paper looks 3d, you have to realize that
it is still 2d.
The box is some object in our Direct3D world. The paper is the
monitor (capable of displaying 2d only). The process of drawing the
box on to the paper (giving a 2d representation of the 3d world) is
transformation.
Screen Space
So far, I've been blabbering on about
world space. I'm sure you now know what Screen Space is, but how do
you draw an object using screen space (without changing the View
matrix to the matrix I gave you first)?
Create a clsTransformedSprite.
Oh, one more thing I forgot to mention. When an object is
transformed, it's in screen space. When an object is untransformed,
it's in world space.
Copy and paste the code from clsSprite (everything except Public
Class clsSprite... and End Class since you already have those).
We're going to make a few minor changes (Oh by the way, be sure
you're using the View matrix that's been shifted)
Now, there's a vertex type called CustomVertex.TransformedTextured
<-- that's what we need.
In clsTransformedSprite, hit control + F. Press the Replace button
(to expand the box), and fill in the following fields
Find What: CustomVertex.PositionTextured
Replace with: CustomVertex.TransformedTextured
Search: Current Document
Hit replace all.
Now you'll have 4 errors when you instantiate the vertices (for
example: Vertices(0) = New
CustomVertex.TransformedTextured(topleft.X, topleft.Y, 1, 0, 0))
Transformed vertices require an rhw argument, which, I beleive, has
to do with lighting. I usually set that argument to 1. Add a 1 after
the z argument. For example:
Vertices(0) = New CustomVertex.TransformedTextured(topleft.X,
topleft.Y, 1, 0, 0) to
Vertices(0) = New CustomVertex.TransformedTextured(topleft.X,
topleft.Y, 1, 1, 0, 0)
Do this for all the vertices. Go to GameClass and make alex a
clsTransformedSprite instead of a clsSprite. Run it. He should
appear at 0,0 where he belongs!
What's the point?!?!
Hmm. Good point. There is
no point. I just created this tutorial to waste your time as well as
my time.
Of course there's a point!
Remember world transformations? A
Transformed object is not subject to transformations. For example,
if you wanted some type of box to appear at the top right of your
screen telling you the character's current health, you'd use screen
space. When you translate the world to the right, that box will also
move to the right.
There's a way around this, I'm sure you know how, too - you just
translate the world before you render the box, but keep the
translation constant. But still, what if, in your game, the
View matrix was shifted over (like ours was in this tutorial). You
would have to waste your time figuring out how much you need to
shift the box by to keep it in the proper position. Or you would
have to change the View matrix (to the one I gave you originally)
before rendering the box (yes, you can do that :D). However wouldn't
that be a waste of memory? Now you see the point?
Change stuff back
I usually (as you probably
now know), base my Direct3D tutorials off the previous tutorials.
Please go back and make alex a clsSprite instead of a
clsTransformedSprite. Also, please change the view matrix to the one
I gave you originally(D3Ddev.Transform.View
= Matrix.OrthoOffCenterLH(0, DP.Width, DP.Height, 0, 1, 10).
Thanks.
The End
I hope you've enjoyed this tutorial. Actually, the main point
of this tutorial was to introduce you to some Direct3D theory so you
can learn about how these things work. Trust me, you'll find it
useful when we get to the 3d lessons.
The Source
Code for this tutorial is located
here:
You can also
locate this by logging in to vbProgramming Forums and going
to: Tutorials > Tutorial Source Code >
Source Code |