MULTIMEDIA

Programming with DirectX : Transformation Demo

1/12/2011 11:48:30 AM
The global section of the Transformations demo starts by adding matrices for the projection, view, and world. It also adds effect variables that allow these matrices to be bound to the shader. The global section from the Transformations demo is shown in Listing 1. Effect matrix variables are represented by the type ID3D10EffectMatrixVariable.
Listing 1. The Global Section from the Transformations Demo
#include<windows.h>
#include<d3d10.h>
#include<d3dx10.h>

#pragma comment(lib, "d3d10.lib")
#pragma comment(lib, "d3dx10.lib")

#define WINDOW_NAME "Transformations"
#define WINDOW_WIDTH 800
#define WINDOW_HEIGHT 600

// Direct3D 10 objects.
ID3D10Device *g_d3dDevice = NULL;
IDXGISwapChain *g_swapChain = NULL;
ID3D10RenderTargetView *g_renderTargetView = NULL;

// Effect objects and variables.
ID3D10Effect *g_shader = NULL;
ID3D10EffectTechnique *g_technique = NULL;
ID3D10EffectMatrixVariable *g_worldEffectVar = NULL;
ID3D10EffectMatrixVariable *g_viewEffectVar = NULL;
ID3D10EffectMatrixVariable *g_projEffectVar = NULL;

// Display object to store scene geometry.
ID3D10InputLayout *g_layout = NULL;
ID3D10Buffer *g_vertexBuffer = NULL;

// Structure used to represent a single vertex.
struct DX10_Vertex
{
D3DXVECTOR3 pos;
};

// Projection, world, and view transformations.
D3DXMATRIX g_worldMat, g_viewMat, g_projMat;

The projection matrix depends on the window’s dimensions. Because of this, the projection matrix is set in the demo’s resizing function, ResizeD3D10Window(). This function in the Transformations demo adds a line of code at the end that creates a left-handed projection matrix using D3DXMatrixPerspectiveFOVLH(), which is shown in Listing 2.

Listing 2. The Resizing Function from the Transformations Demo
void ResizeD3D10Window(int width, int height)
{
if(g_d3dDevice == NULL)
return;

D3D10_VIEWPORT vp;

vp.Width = width;
vp.Height = height;
vp.MinDepth = 0.0f;
vp.MaxDepth = 1.0f;
vp.TopLeftX = 0;
vp.TopLeftY = 0;

g_d3dDevice->RSSetViewports(1, &vp);

D3DXMatrixPerspectiveFovLH(&g_projMat, (float)D3DX_PI * 0.25f,
width/(FLOAT)height, 0.1f, 1000.0f);
}

The demo’s initialization function adds code to bind the effect variables and to set the two remaining matrices. The projection matrix is set and updated by the ResizeD3D10Window() function, so it is not included in the initialize function. The world matrix is not set to anything, so it is cleared by calling D3DXMatrixIdentity(). The D3DXMatrixIdentity() function is essentially used to clear matrices. The view matrix is set 15 units back, which places the view farther back in the scene than what it was in the Primitives demo. The square looks smaller in the scene because perspective projection is being used. There is no difference between the square geometry in the Transformations demo and that in the Primitives demo. The difference is in the camera’s position. The demo’s initialize function is shown in Listing 3. Effect variables are obtained by calling the GetVariableByName() function, which takes as a parameter the name used in the shader file for the variable.

Listing 3. The Demo’s Initialize Function
bool InitializeDemo()
{



g_technique = g_shader->GetTechniqueByName("PassThrough");
g_worldEffectVar = g_shader->GetVariableByName(
"World")->AsMatrix();
g_viewEffectVar = g_shader->GetVariableByName(
"View")->AsMatrix();
g_projEffectVar = g_shader->GetVariableByName(
"Proj")->AsMatrix();


// Clear the matrices.
D3DXMatrixIdentity(&g_worldMat);
D3DXMatrixIdentity(&g_viewMat);

D3DXVECTOR3 eye(0, 0, -15);
D3DXVECTOR3 lookAt(0, 0, 0);
D3DXVECTOR3 up(0, 1, 0);

D3DXMatrixLookAtLH(&g_viewMat, &eye, &lookAt, &up);

return true;
}

In the rendering function, three added lines of code are used to set the matrices to the shader. Technically, it is only necessary to set effect variables when they change or when you switch shaders. The matrices are set by using the effect variable’s function SetMatrix(), which takes as a parameter the matrix represented by a float array. This can be done by casting the matrix to a float pointer. The rendering function from the Transformations demo is shown in Listing 4.

Listing 4. The Rendering Function from the Transformations Demo
void RenderScene()
{
float col[4] = { 0, 0, 0, 1 };

// Clear the rendering destination to a specified color.

g_d3dDevice->ClearRenderTargetView(g_renderTargetView, col);

unsigned int stride = sizeof(DX10_Vertex);
unsigned int offset = 0;

// Setup the geometry buffer that will be rendered.

g_d3dDevice->IASetInputLayout(g_layout);
g_d3dDevice->IASetVertexBuffers(0, 1, &g_vertexBuffer,
&stride, &offset);
g_d3dDevice->IASetPrimitiveTopology(
D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

// Prepare the effect we will use to draw the geometry.

g_viewEffectVar->SetMatrix((float*)&g_viewMat);
g_projEffectVar->SetMatrix((float*)&g_projMat);
g_worldEffectVar->SetMatrix((float*)&g_worldMat);

D3D10_TECHNIQUE_DESC techDesc;
g_technique->GetDesc(&techDesc);

// Loop through each pass of the technique and draw.

for(unsigned int i = 0; i < techDesc.Passes; i++)
{
g_technique->GetPassByIndex(i)->Apply(0);
g_d3dDevice->Draw(6, 0);
}

// Display the results to the target window (swap chain).

g_swapChain->Present(0, 0);
}


The last code that needs to be seen is the Transformations demo’s shader. This shader starts by defining three variables (World, View, and Proj), each of which are obtained by the application by name. These variables are used by the vertex shader to multiply the matrices against the incoming vertex position. The vertex is transformed by the world matrix first, then the view, and then the projection. If the world, view, and projection matrices where concatenated into one, then one multiplication would be used. In this demo we’ll see the longer form by multiplying against each in order. The rest of the shader is the same from the Primitives demo. The shader from the Transformation demo is shown in Listing 5. Figure 1 shows a screenshot of the demo.

Listing 5. The Transformations Demo’s Shader
/*
Chapter 5 - Transformations
Ultimate Game Programming with DirectX 2nd Edition
Created by Allen Sherrod
*/

matrix World;
matrix View;
matrix Proj;

struct VS_INPUT
{
float4 Pos : POSITION;
};

struct PS_INPUT
{
float4 Pos : SV_POSITION;
};

PS_INPUT VS(VS_INPUT input)
{
PS_INPUT output = (PS_INPUT)0;

output.Pos = mul(input.Pos, World);
output.Pos = mul(output.Pos, View);
output.Pos = mul(output.Pos, Proj);
return output;
}

float4 PS(PS_INPUT input) : SV_Target
{
return float4(1, 0, 1, 1);
}

technique10 PassThrough
{
pass P0
{
SetVertexShader(CompileShader(vs_4_0, VS()));

SetGeometryShader(NULL);

SetPixelShader(CompileShader(ps_4_0, PS()));
}
}

Figure 1. A screenshot from the Transformations demo.

Other  
  •  Programming with DirectX : View Transformations
  •  Programming with DirectX : World Transformations
  •  Programming with DirectX : Projection Transformations
  •  iPhone 3D Programming : Adding Depth and Realism - Lighting Up (part 2)
  •  iPhone 3D Programming : Adding Depth and Realism - Lighting Up (part 1)
  •  iPhone 3D Programming : Adding Depth and Realism - Surface Normals (part 2)
  •  iPhone 3D Programming : Adding Depth and Realism - Surface Normals (part 1)
  •  iPhone 3D Programming : Adding Depth and Realism - Filling the Wireframe with Triangles
  •  iPhone 3D Programming : Adding Depth and Realism - Creating and Using the Depth Buffer
  •  iPhone 3D Programming : Adding Depth and Realism - Examining the Depth Buffer
  •  iPhone 3D Programming : HelloCone with Fixed Function
  •  iPhone 3D Programming : Vector Beautification with C++
  •  jQuery 1.3 : An image carousel
  •  jQuery 1.3 : Headline rotator
  •  Silverlight : Print a Document
  •  Silverlight : Capture a Webcam
  •  Silverlight : Make Your Application Run out of the Browser
  •  Silverlight : Put Content into a 3D Perspective
  •  Silverlight : Response to Timer Events on the UI Thread
  •  Silverlight : Build a Download and Playback Progress Bar
  •  
    Top 10
    Windows Vista : Installing and Running Applications - Launching Applications
    Windows Vista : Installing and Running Applications - Applications and the Registry, Understanding Application Compatibility
    Windows Vista : Installing and Running Applications - Practicing Safe Setups
    Windows Server 2003 : Domain Name System - Command-Line Utilities
    Microsoft .NET : Design Principles and Patterns - From Principles to Patterns (part 2)
    Microsoft .NET : Design Principles and Patterns - From Principles to Patterns (part 1)
    Brother MFC-J4510DW - An Innovative All-In-One A3 Printer
    Computer Planet I7 Extreme Gaming PC
    All We Need To Know About Green Computing (Part 4)
    All We Need To Know About Green Computing (Part 3)
    Most View
    Managing Xen : Xen Domain Configuration Files
    Programming WCF Services : Queued Services - Transactions
    Alienware M17X - Best In Class Gaming Performance
    We Help You Find Your Ideal Smartphone (Part 4)
    Choosing The Right Parts For Your Build (Part 3) - Picking the right video card
    Homeplug Problems In A Factory Setting (Part 2)
    Guide To Upgrades With The Greatest Effects (Part 2)
    Microsoft ASP.NET 4 : Profiles - Understanding Profiles
    VMware Fusion 5 - Your Mac is Virtually a PC
    Running Windows 8 (part 2) - Power Plans, Sleep Modes, and Shutdown
    The Ultimate PC Security Toolbox (Part 1)
    The big test … Inter Core Power (Part 1) - Acer Aspire Ethos 8951G
    Windows Vista : Build Your Network (part 4) - Troubleshoot Wireless Networks
    Mac - That Syncing Feeling
    Macbook Air vs. Ultrabook Platform (Part 2)
    Find Yourself With Geolocation Technology (Part 3)
    The Complete Guide To Garageband (Part 1)
    Generation I (For Insecure)?
    Kingston SSDNow mS100 64GB - One Of The Cheapest SSDs Around
    You Can Master RAW (Part 4)