Title: Vertex Buffers, Index Buffers
1Vertex Buffers, Index Buffers Textures
2To draw a 3D object
- We store the vertices of the 3D object in a
vertex buffer. - The vertices are the corners of the triangles
that make up the object
3Vertex Buffers
- A chunk of contiguous memory that contains vertex
data - A place to hold the vertices we want to draw.
- Can be placed in VRAM for faster rendering
- Represented by a IDirect3DVertexBuffer9 object
4You decide the format of the vertex
- Depending on whether you want colour, texturing
etc. - E.g.
- struct Vertex
-
- Vertex()
- Vertex(float x, float y, float z)
-
- _x x _y y _z z
-
- float _x, _y, _z
- static const DWORD FVF
-
- const DWORD VertexFVF D3DFVF_XYZ
5Vertices with colours
- struct ColorVertex
-
- ColorVertex()
- ColorVertex(float x, float y, float z, D3DCOLOR
c) -
- _x x _y y _z z _color c
-
- float _x, _y, _z
- D3DCOLOR _color
- static const DWORD FVF
-
- const DWORD ColorVertexFVF D3DFVF_XYZ
D3DFVF_DIFFUSE
6Vertices with textures
- struct TexelVertex
-
- TexelVertex()
- TexelVertex(float x, float y, float z, float u,
float v) -
- _x x _y y _z z
- _u u _v v
-
- float _x, _y, _z
- float _u, _v
- static const DWORD FVF
-
- const DWORD TexelVertexFVF D3DFVF_XYZ
D3DFVF_TEX1
7To create one
- HRESULTÂ CreateVertexBuffer(Â Â Â Â Â Â
- UINTÂ Length, Â Â Â Â DWORDÂ Usage,DWORDÂ FVF,
D3DPOOLÂ Pool, Â Â Â Â IDirect3DVertexBuffer9Â ppVer
texBuffer, HANDLEÂ pSharedHandle - )
- Length Number of bytes (number_of_vertices
sizeof(Vertex) - Usage Well usually use D3DUSAGE_WRITEONLY
- FVF Flexible vertex format The static member
of the struct - Pool - D3DPOOL_MANAGED Let DirectX manage the
pool - pSharedHandle Usually 0
8Example
- device-gtCreateVertexBuffer(
- 36 sizeof(TexelVertex), // size in bytes
- D3DUSAGE_WRITEONLY, // flags
- TexelVertexFVF, // vertex format
- D3DPOOL_MANAGED, // managed memory pool
- _landscapeVertices,// return create vertex
buffer - 0
- )
9To write to the buffer
- Obtain a pointer to the contents by
- Vertex vertices
- IDirect3DVertexBuffer9Lock(
- UINT Offset,
- UNIT size,
- BYTE vertices,
- DWORD flags
- )
- Offset Offset in bytes from the start of the
buffer - Size Number of bytes to lock
- vertices Pointer to the start of the locked
data. We can write to this pointer after we lock
the buffer - Flags Usually 0.
- E.g.
- landscapeVertices-gtLock(0, 0, (void)vertices,
0) - vertices0 Vertex(1,2,3)
- vertices1 Vertex(1,2,3)
10To draw the buffer
- Set the vertex stream source
- device-gtSetStreamSource(0, _landscapeVertices,
0, sizeof(Vertex)) - Set the format of the stream
- device-gtSetFVF(VertexFVF)
- Perform any transformations necessary
- D3DXMATRIX landscapeScale
- D3DXMatrixScaling(landscapeScale, 1,1,1)
- device-gtSetTransform(D3DTS_WORLD,
landscapeScale) - Draw the vertices
- device-gtDrawPrimitive(D3DPT_TRIANGLELIST, 0, 2)
-
11Duplicated vertices
- Most 3D shapes contain duplicated vertices. For
example
This vertex is shared by 4 triangles
12As a solution we can use
- Index buffers
- Create the vertex buffer, with just one instance
of each vertex - Create an index buffer with multiple pointers
into to the vertex buffer
13Or triangle strips
- device-gtDrawPrimitive(D3DPT_TRIANGLESTRIP
- Renders the vertices as a triangle strip. The
backface-culling flag is automatically flipped on
even-numbered triangles.
14Or triangle fans
- device-gtDrawPrimitive(D3DPT_TRIANGLEFAN
- Renders the vertices as a triangle fan
15Rendering mode
- We can configure the rendering mode with
- device-gtSetRenderState(D3DRS_FILLMODE, value)
- Where value is
- D3DFILL_POINT
- Fill points.
- D3DFILL_WIREFRAME
- Fill wireframes.
- D3DFILL_SOLID
- Fill solids.
16Shading mode
- We can configure the shading mode with
- device-gtSetRenderState(D3DRS_SHADEMODE, value)
- Where value is
- D3DSHADE_FLAT
- Flat shading mode. The color and specular
component of the first vertex in the triangle are
used to determine the color and specular
component of the face. These colors remain
constant across the triangle that is, they are
not interpolated. The specular alpha is
interpolated. - D3DSHADE_GOURAUD
- Gouraud shading mode. The color and specular
components of the face are determined by a linear
interpolation between all three of the triangle's
vertices.
17Flat shading
18Gourad Shading
19Texturing
- A texture is a bitmap that gets painted onto a 3D
polygon - To load a texture, use
- IDirect3DTexture9 _boxTexture
- D3DXCreateTextureFromFile(device, "rocks.bmp",
_boxTexture)
20Texels
- A texel is like a pixel, but is a point on a
texture - The origin for texels, is the top left
- The bounds of a texture are 1,1
u-axis
(0, 0)
v-axis
(1, 1)
21To apply a texture to a polygon
- Define the texel that applies to a vertex
-Vertices- -Texel- vertices24
TexelVertex(-1, 1, -1, 0, 1) - Set the vertex format when you create the buffer
- device-gtCreateVertexBuffer(
- 30 sizeof(TexelVertex),
- D3DUSAGE_WRITEONLY,
- TexelVertexFVF, // vertex format
- D3DPOOL_MANAGED, _boxVertices,
- 0)
- Set the vertex before drawing
- device-gtSetFVF(TexelVertexFVF)
-
- Set the texture before drawing
- device-gtSetTexture(0,_boxTexture)
-
22Outside the vertex range
- Set the texels beyond 0, 1
- Set the SamplerState to be
- wrap
- border colour
- clamp
- mirror
- E.g.
- _device-gtSetSamplerState(D3DSAMP_ADDRESSU,
D3DTADRESS_WRAP) - _device-gtSetSamplerState(D3DSAMP_ADDRESSV,
D3DTADRESS_WRAP)
23Mesh
- A mesh is a
- File
- Memory representation (vertex buffer etc)
- Loader
- It holds
- Vertices
- Indexes
- Normals
- Textures
- Materials
- Animation
- We can create a mesh in a 3D Editor
243D Editors
- Milkshape
- 3D Studio Max
- Maya
- GMax
25X Files
- In Direct X, meshes are stored with a .x
extension - Can be binary or text format
- We can use a 3D editor to export to the .x file
format - There is a .x file viewer with the DirectX SDK
26xof 0303txt 0032 // DirectX - from
MilkShape3D Frame dalekFrame
FrameTransformMatrix
1.000000,0.000000,0.000000,0.000000,
0.000000,1.000000,0.000000,0.000000,
0.000000,0.000000,1.000000,0.000000,
0.000000,0.000000,0.000000,1.000000
Mesh dalekMesh 15872
0.0774927.0544702.468911,
0.1152847.0469692.468383,
0.1152847.0208392.466543,
0.0674677.0303272.467211,
0.0875177.0786102.470611,
27Other formats
- FarCry
- Quake
- Half Life 1/2
- 3DS
- Etc.
28Mesh concepts
- Subsets
- Meshes are divided into subsets parts of the
mesh with different materials textures - Materials
- Determine how the light interacts with the subset
29Mesh API Calls
- To create a mesh from a file
- ID3DXBuffer adjBuffer 0
- ID3DXBuffer mtrlBuffer 0
- DWORD numMtrls 0
- hr D3DXLoadMeshFromX(
- _meshName.c_str(),
- D3DXMESH_MANAGED,
- device,
- adjBuffer,
- mtrlBuffer,
- 0,
- numMtrls,
- _mesh)
30Mesh API Calls
- mtrlBuffer points to a buffer for materials (used
for lighting) and texture file names - We then have to iterate through this buffer and
load any required textures
31In code
- for(int i 0 i lt numMtrls i)
-
- // the MatD3D property doesn't have an ambient
value set - // when its loaded, so set it now
- mtrlsi.MatD3D.Ambient mtrlsi.MatD3D.Diffuse
- // save the ith material
- _materials.push_back( mtrlsi.MatD3D )
- // check if the ith material has an associative
texture - if( mtrlsi.pTextureFilename ! 0 )
-
- // yes, load the texture for the ith subset
- IDirect3DTexture9 tex 0
- D3DXCreateTextureFromFile(
- device,
- mtrlsi.pTextureFilename,
- tex)
32Optimise the mesh
- hr _mesh-gtOptimizeInplace(
- D3DXMESHOPT_ATTRSORT
- D3DXMESHOPT_COMPACT
- D3DXMESHOPT_VERTEXCACHE,
- (DWORD)adjBuffer-gtGetBufferPointer(),
- 0, 0, 0)
33Drawing the mesh
- We iterate through the subsets and draw each one
with the appropriate material and texture - for(int i 0 i lt _materials.size() i)
-
- Device-gtSetMaterial( _materialsi )
- Device-gtSetTexture(0, 0)
- Device-gtSetTexture(0, _texturesi)
- _mesh-gtDrawSubset(i)
-
34Other useful Mesh API calls
- D3DXCreateBox
- D3DXCreateSphere
- D3DXCreateCylinder
- D3DXCreateTeapot
- D3DXCreatePolygon
- D3DXCreateTorus
35Bounding volumes
- D3DXComputeBoundingBox
- D3DXComputeBoundingSphere
- Do these return coordinates in local space or
world space?