Section 4 - Drawing Colors
Section 4 - Drawing Colors
Using Direct 3D
Drawing & Colors
Outline
• Vertex Buffers
• Drawing Primitives
• Indexed Primitives & Index Buffers
• Color Representation
• Shading
• Rendering State
• Moving to 3D
2
Outline
• Vertex Buffers
• Drawing Primitives
• Indexed Primitives & Index Buffers
• Color Representation
• Shading
• Rendering State
• Moving to 3D
3
Vertex Buffer
• As mentioned before, the basic
drawing elements are vertices and
primitives.
• Vertices hold information such as
coordinates, colors and texture
coordinates while primitives are basic
elements composed of these
vertices.
4
Vertex Buffer (Cont.)
• Vertex information is placed in a
vertex buffer.
• What we need is to
– Create a vertex buffer
– Fill it
– Use it to draw primitives
5
Vertex Buffer (Cont.)
• To create a vertex buffer we mainly
need to specify
– The size of the buffer.
– What kind of information each vertex will
hold.
6
Vertex Buffer (Cont.)
7
Vertex Buffer (Cont.)
• FVF (Flexible Vertex Format) code is
an OR-Combination of flags that
indicates
– The information stored in each vertex
– How the vertex will be processed by the
fixed pipeline
8
Vertex Buffer (Cont.)
• Example FVF Flags
– D3DFVF_DIFFUSE : Indicates the presence of a diffuse color
component
– D3DFVF_XYZ : Indicates the presence of untransformed
coordinates
– D3DFVF_XYZRHW : Indicates the presence of transformed
coordinates
– D3DFVF_NORMAL : Indicates the presence of normal vector
component, which means the vertex is unlit
– D3DFVF_TEX1 : Indicates the presence of texture coordinates
for 1 texture
9
Vertex Buffer (Cont.)
• The Usage parameter indicates how the buffer
will be used. For example:
– D3DUSAGE_POINTS flag indicates that the buffer
will be used to store point primitives.
– D3DUSAGE_WRITEONLY indicates that the
application will only write to the buffer. D3D tries to
place the buffer in the bast memory for writing.
• We will set this parameter to 0 in most cases.
10
Vertex Buffer (Cont.)
• The Pool parameter determines the memory
area that will hold the buffer
• D3D Resources can be placed in system
memory, local video memory, AGP memory ...
etc
• Each has its pros & cons
• We will use D3DPOOL_DEFAULT or
D3DPOOL_MANAGED
11
Vertex Buffer (Cont.)
• To fill the vertex buffer we
– Lock it (and obtain memory address)
– Unlock it
13
Vertex Buffer (Cont.)
• Example: Transformed Lit Vertices
struct TransformedLitVertex
{
FLOAT x, y, z;
FLOAT rhw;
DWORD color;
};
#define FVF_TL (D3DFVF_XYZRHW | D3DFVF_DIFFUSE)
14
Vertex Buffer (Cont.)
• Example: Transformed Lit Vertices
//Creating a vertex buffer
IDirect3DVertexBuffer9* VB = NULL;
if( FAILED(Device>CreateVertexBuffer
( 3*sizeof(TransformedLitVertex), 0 /*Usage*/,
FVF_TL, D3DPOOL_DEFAULT, &VB, NULL ) ) )
{
//Handle failure
}
15
Vertex Buffer (Cont.)
• Example: Transformed Lit Vertices
//Filling the vertex buffer
TransformedLitVertex vertices[] = { ... };
VOID* pVertices;
//1. Lock and obtain address
if( FAILED( VB>Lock( 0, 0, (void**)&pVertices, 0 ) ) ) { /*Handle
Failure*/ }
//2. Write
memcpy( pVertices, vertices, sizeof(vertices) );
//3. Unlock
VB>Unlock();
16
Outline
• Vertex Buffers
• Drawing Primitives
• Indexed Primitives & Index Buffers
• Color Representation
• Shading
• Rendering State
• Moving to 3D
17
Drawing Primitives
• Having prepared the vertex buffer it
is time to draw objects using the
vertices in that buffer.
• Before drawing we have to
– Set the vertex buffer to read from
18
Drawing Primitives (Cont.)
• To draw a primitive we use
DrawPrimitive method
19
Drawing Primitives (Cont.)
• Some primitive types are
– D3DPT_POINTLIST
– D3DPT_LINELIST
– D3DPT_LINESTRIP
– D3DPT_TRIANGLELIST
– D3DPT_TRIANGLESTRIP
– D3DPT_TRIANGLEFAN
20
Drawing Primitives (Cont.)
• Some primitive types are
– D3DPT_POINTLIST
– D3DPT_LINELIST
– D3DPT_LINESTRIP Image from MSDN
– D3DPT_TRIANGLELIST
– D3DPT_TRIANGLESTRIP
– D3DPT_TRIANGLEFAN
21
Drawing Primitives (Cont.)
• Some primitive types are
– D3DPT_POINTLIST
– D3DPT_LINELIST
– D3DPT_LINESTRIP
– D3DPT_TRIANGLELIST Image from MSDN
– D3DPT_TRIANGLESTRIP
– D3DPT_TRIANGLEFAN
22
Drawing Primitives (Cont.)
• Some primitive types are
– D3DPT_POINTLIST
– D3DPT_LINELIST
– D3DPT_LINESTRIP
– D3DPT_TRIANGLELIST
– D3DPT_TRIANGLESTRIP
– D3DPT_TRIANGLEFAN Image from MSDN
23
Drawing Primitives (Cont.)
• Drawing commands are issued between
IDirect3DDevice9::BeginScene and
IDirect3DDevice9::EndScene methods
• Example
Device>Clear(0, 0, D3DCLEAR_TARGET , 0x0, 0, 0);
Device>BeginScene();
Device>SetStreamSource( 0, VB, 0, sizeof(CUSTOMVERTEX) );
Device>SetFVF( D3DFVF_CUSTOMVERTEX );
Device>DrawPrimitive( D3DPT_TRIANGLELIST, 0, 2 );
Device>EndScene();
Device>Present(NULL,NULL,NULL,NULL);
24
Summing it up
• Setup
– Initialize D3D
– Create & Fill Vertex Buffer
• Render
– Clear Buffers
– Begin Scene
– Set Stream Source
– Set FVF
– Drawing Commands
– End Scene
– Present
25
Think about it
• Can you draw a cube using one drawing
command without specifying a vertex
in the buffer twice ?
26
Think about it
• Remember, redundant vertices =
wasted memory BW + redundant
vertex processing
27
Outline
• Vertex Buffers
• Drawing Primitives
• Indexed Primitives & Index Buffers
• Color Representation
• Shading
• Rendering State
• Moving to 3D
28
Indexed Primitives
• Indexed primitives are the solution to the problem of
redundant vertices
• Instead of accessing the vertices in the vertex buffer in
strict sequential order, provide an index array (called index
buffer) that specifies the order in which vertices in the
vertex buffer are accessed. The point is that a vertex can be
referenced more than once in that array.
29
Image from alt.pluralsight.com
Indexed Primitives (Cont.)
• Index buffers are almost identical in
creation and usage to vertex buffers
N * sizeof(WORD)
or N * sizeof(DWORD)
Depending on Format
D3DFMT_INDEX16
30
or D3DFMT_INDEX32 (Check device caps)
Indexed Primitives (Cont.)
• Index buffers are almost identical in
creation and usage to vertex buffers
31
Indexed Primitives (Cont.)
• Just as we call
IDirect3DDevice9::SetStreamSource
to the set the vertex buffer to be used, we
also call
Idirect3DDevice9::SetIndices to set
the index buffer to be used
32
Indexed Primitives (Cont.)
• To draw a primitive using a vertex buffer and an
index buffer, we use
IDirect3DDevice9::DrawIndexedPrimitive
33
Summing it up again
• Setup
– Initialize D3D
– Create & Fill Vertex Buffer
– Create & Fill Index Buffer
• Render
– Clear Buffers
– Begin Scene
– Set Stream Source
– Set Indices
– Set FVF
– Drawing Commands
– End Scene
34
– Present
Outline
• Vertex Buffers
• Drawing Primitives
• Indexed Primitives & Index Buffers
• Color Representation
• Shading
• Rendering State
• Moving to 3D
35
Color Representation
• A color is represented by an RGB
triplet. Each component occupies a
byte (0~255)
36
Color Representation
(Cont.)
• Direct3D9 provides
– D3DCOLOR type
• An alias for DWORD
– D3DCOLOR_ARGB(a, r, g, b) macro
• Accepts color components and returns the
corresponding D3DColor e.g.
D3DCOLOR red = D3DCOLOR_ARGB(255, 255, 0, 0)
37
Color Representation
(Cont.)
• Direct3D9 provides
– D3DCOLORVALUE
• A 128-bit color structure where each
component is represented by a floating point
(0 = no intensity, 1 = max intensity)
38
Color Representation
(Cont.)
• Direct3D9 provides
– D3DXCOLOR
• Similar to D3DCOLORVALUE but provides
useful constructors and overloaded operators
for e.g. (color addition and component-wise
multiplication)
39
Color Representation
(Cont.)
• The color of a primitive by the color
of the vertices that constitute it.
• To add color to vertices we add a
D3DCOLOR (or DWORD) component
the vertex structure and set the
D3DFVF_DIFFUSE flag in the FVF
code.
40
Color Representation
(Cont.)
• Note that you must use 32-bit color
representation.
41
Outline
• Vertex Buffers
• Drawing Primitives
• Indexed Primitives & Index Buffers
• Color Representation
• Shading
• Rendering State
• Moving to 3D
42
Shading
• Shading is the process of determining
the colors of the pixels in a primitive
given the colors of vertices that
constitute that primitive.
43
Shading (Cont.)
• The simplest shading technique is flat
shading. Simply, the pixels in a
primitive get the color of the first
vertex in that primitive.
44
Shading (Cont.)
• The more elegant shading technique is
Gouraoud shading (a.k.a smooth
shading), where the color of a pixel is
linearly interpolated using the colors
of all vertices in the primitive.
45
Shading (Cont.)
• Gouraud shading is the default
shading technique in D3D.
46
Shading (Cont.)
• The following figure shows flat vs.
Gouraud shading
47
Outline
• Vertex Buffers
• Drawing Primitives
• Indexed Primitives & Index Buffers
• Color Representation
• Shading
• Rendering State
• Moving to 3D
48
Rendering State
• IDirect3DDevice9::SetRenderState is used to set
a number of state variables that determine how D3D
will render the scene.
• We saw the shading technique as an example.
• In general
Device>SetRenderState(StateVariableName,
NewValue);
• State variables have default values so you set them only
when needed. When set, they retain their new values
until set again.
49
Outline
• Vertex Buffers
• Drawing Primitives
• Indexed Primitives & Index Buffers
• Color Representation
• Shading
• Rendering State
• Moving to 3D
50
Moving to 3D
51
Moving to 3D
• We need to
– Enable depth buffer.
– Tell D3D that from now on, the vertices
are untransformed.
– Tell D3D how to map 3D vertex
coordinates to 2D screen coordinates
(specify transformation matrices).
52
Moving to 3D (Cont.)
• To enable the depth buffer, set the presentation
parameters during initialization
d3dpp.EnableAutoDepthStencil = true;
d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
• You have also to clear the depth buffer before
rendering a new frame
Device>Clear(0, 0, D3DCLEAR_TARGET |
D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
53
Moving to 3D (Cont.)
• To indicate untransformed vertices
– Remove rhw component from vertex structure.
structure ColoredVertex
{
FLOAT x, y, z; D3DCOLOR color;
};
54
Moving to 3D (Cont.)
• To set a transformation we call
Device>SetTransformation(TransformationType,
TransformationMatrix)
55
Moving to 3D (Cont.)
• Recall that we have three kinds of
transformations
– World Transformation
– Camera Transformation
– Projection Transformation
• So, TransformationType can be D3DTS_WORLD,
D3DTS_VIEW or D3DTS_PROJECTION
56
Moving to 3D (Cont.)
• We do not need to fill the matrices by hand.
Direct3D provides utility functions that create
matrices given the information we care about.
Examples of such functions are:
– D3DXMatrixTranslation, D3DXMatrixRotationX and
D3DXMatrixScaling for world transformation
– D3DXLookAtRH for view transformation
– D3DXMatrixPerspectiveLH for projection
transformation
» Details will be given in the lab
57
Moving to 3D (Cont.)
• Recall that transformations can be combined
by multiplying the corresponding matrices.
58
Summing it up again
• Setup
– Initialize D3D
– Create & Fill Vertex Buffer
– Create & Fill Index Buffer
– Set Fixed Transformations
• Render
– Clear Buffers
– Begin Scene
– Set Stream Source
– Set Indices
– Set FVF
– Set Frame-level/Object-level Transformations
– Drawing Commands
– End Scene 59
– Present
Any Questions ??
60