Anda di halaman 1dari 10

MAE4060 Virtual Reality Systems And Application 2010

Tutorial 2 Vertices, Transformation and Lighting


Flexible Vertex Format (FVF)
3D models are created from triangles. Each triangle has 3 vertices. It is the data elements in
each vertex that determines how it is rendered as it passes through the Direct3D pipeline.
Direct3D uses what is known as Flexible Vertex Formats (FVF) to describe the make up of a
vertex. This allows you to design your own vertex format for your own requirements using
Direct3D Flags.

Direct3D Flags Representation Data order and type


D3DFVF_XYZ Position in 3D space D3DXVECTOR3 or {float, float, float}
D3DFVF_NORMAL Normal D3DXVECTOR3 or {float, float, float}
D3DFVF_XYZRHW Already transformed co‐ordinate {float, float, float, float}
(2D space)
D3DFVF_DIFFUSE Diffuse color D3DCOLOR_ARGB or DWORD
D3DFVF_SPECULAR Specular color D3DCOLOR_ARGB or DWORD
D3DFVF_TEX1 One texture co‐ordinate {float, float}
For others, please link to http://msdn.microsoft.com/en‐us/library/bb172559(VS.85).aspx

#include <d3dx9.h> is needed for D3DXVECTOR3

Example 1:
typedef struct CUSTOMVERTEX
{
D3DXVECTOR3 position; // The 3D position for the vertex
D3DXVECTOR3 normal; // The surface normal for the vertex
} CUSTOMVERTEX;
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_NORMAL) // The flexible vertex format
Example 2:
typedef struct CUSTOMVERTEX
{
float x,y,z; // vertex position
float nx,ny,nz; // vertex normal
float tu,tv; // texture co‐ordinate
DWORD colour;
} CUSTOMVERTEX;
#define D3DFVF_CUSTOMVERTEX(D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1|D3DFVF_DIFFUSE)

Notes: if using diffuse color, the light should be turn off: d3dDevice‐>SetRenderState( D3DRS_LIGHTING,
FALSE );
MAE4060 Virtual Reality Systems And Application 2010

Vertex Buffers
Vertex buffers, represented by the IDirect3DVertexBuffer9 interface, are memory buffers that
contain vertex data. Vertex buffers can contain any vertex type ‐ transformed or
untransformed, lit or unlit ‐ that can be rendered through the use of the rendering methods in
the IDirect3DDevice9 interface. You can process the vertices in a vertex buffer to perform
operations such as transformation, lighting, or generating clipping flags.

 Creating a Vertex Buffer

HRESULT CreateVertexBuffer(UINT length, DWORD usage, DWORD FVF,


D3DPOOL pool, IDirect3DVertexBuffer9** vertexBuffer, HANDLE* handle );

Parameter:

length Size of the vertex buffer in bytes.


E.g. if we wanted 4 vertices using our CUSTOMVERTEX structure
we would write: 4*sizeof(CUSTOMVERTEX)
usage Allows you to indicate how you will use this vertex buffer.
It can be 0, which indicates no usage value.
FVF The flexible vertex format (FVF) you are using for your vertex.
Pool Use D3DPOOL_MANAGED to let Direct 3D handle where to put it
vertexBuffer The address of your declared vertex buffer pointer.
handle This is never used, always set it to NULL.

 Accessing the contents of a Vertex Buffer


You can retrieve a pointer to vertex buffer memory by calling the Lock method, and then
accessing the memory as needed to fill the buffer with new vertex data or to read any
data it already contains. After you finish filling or reading the vertex data, call the Unlock
method, as shown in the following code example.
VOID* pVertices;
if(FAILED(g_pVB‐>Lock(0, sizeof(g_Vertices), (BYTE**)&pVertices, 0 ) ) )
return E_FAIL;

… fill data to the buffer g_Vertices …

g_pVB‐>Unlock();

Lock method: http://msdn.microsoft.com/en‐us/library/bb205917(VS.85).aspx

The above two steps are included in the InitGeometry(). We should run it in InitInstance().
MAE4060 Virtual Reality Systems And Application 2010
 Rendering from a Vertex Buffer
We render the vertex data in Render(). Rendering vertex data from a vertex buffer
requires a few steps.
1) you need to set the stream source by calling the IDirect3DDevice9::SetStreamSource
method, as shown in the following example.
d3dDevice‐>SetStreamSource( 0, g_pVB, sizeof(CUSTOMVERTEX) );
2) to inform Direct3D which vertex shader to use by calling the
IDirect3DDevice9::SetVertexShader method. The following sample code sets an FVF
code for the vertex shader. This informs Direct3D of the types of vertices it is dealing
with.
d3dDevice‐>SetFVF( D3DFVF_CUSTOMVERTEX );
3) After setting the stream source and vertex shader, any draw methods will use the
vertex buffer. The code example below shows how to render vertices from a vertex
buffer with the IDirect3DDevice9::DrawPrimitive method.
g_pd3dDevice‐>DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2*50‐2 );

D3DPRIMITIVETYPE:

D3DPT_POINTLIST Renders the vertices as a collection of isolated points. This value is


unsupported for indexed primitives.
D3DPT_LINELIST Renders the vertices as a list of isolated straight line segments.
D3DPT_LINESTRIP Renders the vertices as a single polyline.
D3DPT_TRIANGLELIST Renders the specified vertices as a sequence of isolated triangles.
Each group of three vertices defines a separate triangle. Back‐face
culling is affected by the current winding‐order render state.
D3DPT_TRIANGLESTRIP Renders the vertices as a triangle strip. The backface‐culling flag is
automatically flipped on even‐numbered triangles.
D3DPT_TRIANGLEFAN Renders the vertices as a triangle fan.
MAE4060 Virtual Reality Systems And Application 2010

Coordinate Transformation Matrices

Vertices

Clipping and
World View Projection
Viewport
Transformation Transformation Transformation
Scaling

rasterizer
World Transform
A world transform changes coordinates from model space, where vertices are defined relative
to a model’s local origin, to World Space, where vertices are defined relative to an origin
common to all the objects in a scene. In essence, the world transform places a model into the
world; hence its name. The following diagram illustrates the relationship between the world
coordinate system and a model’s local coordinate system.

𝑟11 𝑟12 𝑟13 𝑡1


𝑟21 𝑟22 𝑟23 𝑡2
𝑟31 𝑟32 𝑟33 𝑡3
0 0 0 𝑠

The world transform can include any combination of translations, rotations and scalings.
Perform World Transformation in D3D:
1) Declare the transformation matrix
2) Set the transformation and get the transformation matrix
3) Use SetTransform interface to perform the transformation
// Set up world matrix

D3DXMATRIXA16 matWorld;

D3DXMatrixIdentity(&matWorld);

D3DXMatrixRotationX(&matWorld, timeGetTime()/500.0f);

g_pd3dDevice->SetTransform(D3DTS_WORLD, &matWorld);
Math Functions of D3D : http://msdn.microsoft.com/en-us/library/bb172972(VS.85).aspx
MAE4060 Virtual Reality Systems And Application 2010

View Transform
The view transform locates the viewer in world space, transforming vertices into camera
space. In camera space, the camera, or viewer, is at the origin, looking in the positive
z-direction. Recall that Direct3D uses a left-handed coordinate system, so z is positive
into a scene. The view matrix relocates the objects in the world around a camera's
position - the origin of camera space - and orientation.

Perform View Transformation in D3D:


1. Set the eye position
2. Set the look-at-point
3. Set the direction for which way is up
4. To get the transformation matrix with D3DXMatrixLookAtLH method
5. Use SetTransform interface to perform the transformation

D3DXVECTOR3 vEyePt( 0.0f, 3.0f,-5.0f );


D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );
D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );
D3DXMATRIXA16 matView;
D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );
g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );
MAE4060 Virtual Reality Systems And Application 2010

Projection Transform
You can think of the projection transformation as controlling the camera's internals; it is
analogous to choosing a lens for the camera. This is the most complicated of the three
transformation types.

Perform Projection Transformation in D3D:


To build a perspective transform, we need the field of view (π/4 is common), the aspect
ratio, and the near and far clipping planes (which define at what distances geometry
should be no longer be rendered).

D3DXMATRIXA16 matProj;
D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, 1.0f, 1.0f, 100.0f );
g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
MAE4060 Virtual Reality Systems And Application 2010

Lighting
Light Types

 Point Light
Point lights have color and position within a scene, but no single direction. They give off
light equally in all directions, as shown in the following illustration.

 Directional Light
Directional lights have only color and direction, not position. They emit parallel light.
This means that all light generated by directional lights travels through a scene in the same
direction. Imagine a directional light as a light source at near infinite distance, such as the sun.

 Spotlight
Spotlights have color, position, and direction in which they emit light. Light emitted
from a spotlight is made up of a bright inner cone and a larger outer cone, with the light
intensity diminishing between the two, as shown in the following illustration.
MAE4060 Virtual Reality Systems And Application 2010
D3DMATERIAL9 properties:
http://msdn.microsoft.com/en‐us/library/bb147175.aspx

Diffuse Value specifying the diffuse color of the material. See D3DCOLORVALUE
Ambient Value specifying the ambient color of the material. See D3DCOLORVALUE.
Specular Value specifying the specular color of the material. See D3DCOLORVALUE.
Emissive Value specifying the emissive color of the material. See D3DCOLORVALUE.
Power Floating‐point value specifying the sharpness of specular highlights. The higher
the value, the sharper the highlight.

Example:

// Set up a material. The material here just has the diffuse and ambient
// colors set to yellow. Note that only one material can be used at a time.
D3DMATERIAL9 mtrl;
ZeroMemory( &mtrl, sizeof(D3DMATERIAL9) );
mtrl.Diffuse.r = mtrl.Ambient.r = 1.0f;
mtrl.Diffuse.g = mtrl.Ambient.g = 1.0f;
mtrl.Diffuse.b = mtrl.Ambient.b = 0.0f;
mtrl.Diffuse.a = mtrl.Ambient.a = 1.0f;
g_pd3dDevice‐>SetMaterial( &mtrl );
MAE4060 Virtual Reality Systems And Application 2010
D3DLIGHT9 Data Structure Members:
http://msdn.microsoft.com/en‐us/library/bb172566(VS.85).aspx

Type Type of the light source. This value is one of the


members of the D3DLIGHTTYPE enumerated type.
(http://msdn.microsoft.com/en‐us/library/bb174697.aspx)
Diffuse Diffuse, Specular and Ambient colors emitted by the light.
Specular This member is a D3DCOLORVALUE structure.
Ambient
Position Position of the light in world space, specified by a
D3DVECTOR structure. This member has no meaning for
directional lights and is ignored in that case.
Direction Direction that the light is pointing in world space, specified
by a D3DVECTOR structure. This member has meaning
only for directional and spotlights. This vector need not be
normalized, but it should have a nonzero length.
Range Distance beyond which the light has no effect. The
maximum allowable value for this member is the square
root of FLT_MAX. This member does not affect directional
lights.
Falloff Decrease in illumination between a spotlight's inner cone
(the angle specified by Theta) and the outer edge of the
outer cone (the angle specified by Phi). The effect of falloff
on the lighting is subtle. Furthermore, a small performance
penalty is incurred by shaping the falloff curve. For these
reasons, most developers set this value to 1.0.
Attenuation0 Value specifying how the light intensity changes over
Attenuation1 distance. Attenuation values are ignored for directional
Attenuation2 lights. This member represents an attenuation constant. For
information about attenuation, see Light Properties
(Direct3D 9). Valid values for this member range from 0.0 to
infinity. For non‐directional lights, all three attenuation
values should not be set to 0.0 at the same time.
Theta Angle, in radians, of a spotlight's inner cone ‐ that is, the
fully illuminated spotlight cone. This value must be in the
range from 0 through the value specified by Phi.
Phi Angle, in radians, defining the outer edge of the spotlight's
outer cone. Points outside this cone are not lit by the
spotlight. This value must be between 0 and pi.
MAE4060 Virtual Reality Systems And Application 2010
Example:

// Set up a white, directional light, with an oscillating direction.


// Note that many Lights may be active at a time (but each one slows down
// the rendering of our scene). However, here we are just using one. Also,
// we need to set the D3DRS_LIGHTING renderstate to enable lighting

D3DXVECTOR3 vecDir;
D3DLIGHT9 light;
ZeroMemory( &light, sizeof(D3DLIGHT9) );
light.Type = D3DLIGHT_DIRECTIONAL;
light.Diffuse.r = 1.0f;
light.Diffuse.g = 1.0f;
light.Diffuse.b = 1.0f;
vecDir = D3DXVECTOR3(cosf(timeGetTime()/350.0f), 1.0f, sinf(timeGetTime()/350.0f) );
D3DXVec3Normalize( (D3DXVECTOR3*)&light.Direction, &vecDir );
light.Range = 1000.0f;
g_pd3dDevice‐>SetLight( 0, &light );
g_pd3dDevice‐>LightEnable( 0, TRUE );
g_pd3dDevice‐>SetRenderState( D3DRS_LIGHTING, TRUE );

// Finally, turn on some ambient light.


g_pd3dDevice‐>SetRenderState( D3DRS_AMBIENT, 0x00202020 );

Anda mungkin juga menyukai