Wilf LaLonde ©2012Comp 4501
95.450195.4501
Review
Wilf LaLonde ©2012Comp 4501
Getting StartedGetting Started
• Shader lights have generally been covered in other courses…
• We still need some notion of lights with any advanced topic.
• Let’s develop a simplistic library for subsequent use… and in the process get a quick refresher…
Lighting For Dummies
Wilf LaLonde ©2012Comp 4501
Keep in Mind: Understandability is KeyKeep in Mind: Understandability is Key
• Code full of math is generally produced by novices.
• You need math but programming is about providing abstractions that make it understandable in terms of the domain.
Doom Engine Died From Lack Of Understandability
if (normal (side1,side2).alignedWith (toLight) …
if (dot (cross(a,b),c) > 0.01…
Wilf LaLonde ©2012Comp 4501
95.450195.4501
Math for Dummies
Wilf LaLonde ©2012Comp 4501
Math for DummiesMath for Dummies
• Properties of projections: c’s shadow = c cos qc’s height = c sin q
• Properties of cosine:
• Properties of high powers:
1
cos = q 1’s shadowq = 0 +1 aligned with
q = 90 0 q = 180 -1 aligned against
q
1100 10.9100 0.9 * 0.9 * 0.9 … 0.9 0
c
cos q = a / c
bq
a
traditional
c cos q = a
c
c’s shadow
c’s height
q
Wilf LaLonde ©2012Comp 4501
Illustrating “c’s shadow = c cos q” and “c’s height”Illustrating “c’s shadow = c cos q” and “c’s height”
AB
1
a1 a2
b1
b2
b
a
yB
x
• What’s
x,y,a1,b1,ab
Wilf LaLonde ©2012Comp 4501
Math for DummiesMath for Dummies
Properties of the sign of dot product (a number):
U.V = u1v1 + u2v2 + u3v3
U.V = |U| |V| cos q where q Î [0, 180°]
cos 0° = 1 cos 90° = 0 cos 180° = -1
UVq
U
V
qU
V
q
q < 90°U.V > 0
q = 90°U.V = 0
q > 90°U.V < 0
aligned with perpendicular aligned against
Wilf LaLonde ©2012Comp 4501
Math for DummiesMath for Dummies
Dot products as projection lengths: U.V = |U| |V| cos q where q Î [0, 180°]
U
UV
U cos q
If V is a unit vector,
(U.V) V
Is the projection of U on V
q
Wilf LaLonde ©2012Comp 4501
95.450195.4501
Transformation Spaces
for Dummies
Wilf LaLonde ©2012Comp 4501
The transformation PipelineThe transformation Pipeline
• The transformation pipeline WC-1P.
Each space is a different coordinate system.
p W C-1 P
projection space (4D)camera or view space (3D)
world space (3D)local or model space (3D)
+ tangent space
We’ll be using a right handed system if we can.
Wilf LaLonde ©2012Comp 4501
Texture Coordinate Space (Or Tangent Space)Texture Coordinate Space (Or Tangent Space)
In texture, x goes right, y goes up, z goes out,
y
z
x
normal
tangent
bitangent
v
u
at least in a right-handed systemw
Artist Terminology
Wilf LaLonde ©2012Comp 4501
All Spaces are 3D SpacesAll Spaces are 3D Spaces
• Front in texture space might look like
• Side view might look like
Texture coordinates ranging from
0.0 to 1.0
noseT = [0.5, 0.5, -0.3]
T for tangent (texture) spaced
Wilf LaLonde ©2012Comp 4501
In Vertex (Model) SpaceIn Vertex (Model) Space
• You might have a box whose center is the origin... Coordinates are in meters. Suppose it’s a 10 meter wide box.
Coordinate system origin at the center of the object
Twisted a bit so we can see the left side...
The texture is upside down, so the tangent space origin is
the front top left corner
noseM = [-5+0.3, 0, 0] = = [-4.7, 0, 0]
M for model space
Wilf LaLonde ©2012Comp 4501
In World SpaceIn World Space
• To place the box in the world, you could rotate it 180 degrees around y and translate right 1 meter...
Coordinate system origin is 1 meter to the left of the center of the
object
Twisted a bit so we can see the rightside...
noseW = [4.7+1, 0, 0] = [5.7, 0, 0]
W for model space
Wilf LaLonde ©2012Comp 4501
It makes no sense to perform math on points/vectors from different spacesIt makes no sense to perform math on points/vectors from different spaces
• Spaces
T(angent) M(odel) W(orld) C(amera) P(erspective)
• Units
0/+1uv meters meters meters -1/+1 persp.
• Forward ConvertersTBN World View Perspective
• Backward Converters (inverses)TBN-1 World-1 View-1 Perspective-1
If p = qM, then qM = p qMM-1 = pM-1 q = pM-1
noseW = [+5.7, 0, 0]noseM = [-4.7, 0, 0]noseT = [0.5, 0.5, -0.3]
Wilf LaLonde ©2012Comp 4501
95.450195.4501
Lights for Dummies
Wilf LaLonde ©2012Comp 4501
Lighting ComponentsLighting Components
• Ambient Ka background• Diffuse Kd dull light contribution (with shadow)• Specular Ks shinyness light contribution
Wilf LaLonde ©2012Comp 4501
Ambient lightingAmbient lighting
• Usually define via material constant Ka.• We’ll use a demo dependent implemention.
float4 Ka () {return g_materialAmbientColor;}
float4 Ka () {return g_vMaterial * g_vLightAmbient;}
or
float4 ambientColor () {return Ka ();}
Wilf LaLonde ©2012Comp 4501
Diffuse Directional LightingDiffuse Directional Lighting
• Diffuse directional lighting: Kd max (0, n.L)
n L aligned with
aligned against(no contribution)
L
n is the pixel (or face) normal.L is a “to light” vector (usually normalized).
Wilf LaLonde ©2012Comp 4501
Diffuse lighting: Kd max (0, n.L)Diffuse lighting: Kd max (0, n.L)
• Usually define via material constant Kd.• We’ll use a demo dependent implemention.
float4 Kd () {return g_materialDiffuseColor ;}
float4 Kd () {return g_vMaterial * (1 - g_vLightAmbient);}
or
float4 diffuseColor (float3 pixelNormal, float3 normalizedToLight) { return Kd () * clamp01 (dot (pixelNormal, normalizedToLight));}
Wilf LaLonde ©2012Comp 4501
Diffuse lighting: If there are shadowsDiffuse lighting: If there are shadows
float4 diffuseColor (float3 pixelNormal, float3 normalizedToLight,
float shadowIntensity) {return diffuseColor (pixelNormal, normalizedToLight)
* shadowIntensity;}
Wilf LaLonde ©2012Comp 4501
For Spotlights: Need a cone angle .qFor Spotlights: Need a cone angle .q
PL
P is the “to pixel” point.L is a “from light” vector (usually normalized). q is the angle outward from the light vector…
q
pixel outside light cone
Warning: normally, we use a toLight vector
Wilf LaLonde ©2012Comp 4501
Is a point in the spotlight?Is a point in the spotlight?
PL
q
bool inSpotLight (float3 normalizedPixelToLight, float3 normalizedToLightVector, float coneAngleAsCosine) {//Negating each of the above unit directions A and B makes them point away from the light. //Note: -A.-B = A.B = |A||B| cos angle = cos angle. cos 45° = 0.707, cos 0° = 1 return dot (normalizedPixelToLight , normalizedToLightVector ) > coneAngleAsCosine;
}
A.B = |A||B| cos q = cos q if |A| = |B| = 1cos 90° = 0, cos 45° = 0.707, cos 0° = 1
In spotlight from 45° to 0° (> 0.707).
A.B > 0.707 means theangle is 45° OR LESS
35°
cos 35° = 0.8
Inside if P’s cone angle as Cosine > lights Cone angle as Cosine
45°
cos 45° = 0.7
55°
cos 55° = 0.5
65°
cos 65° = 0.4
0°
cos 0° = 1
P out
P in
Wilf LaLonde ©2012Comp 4501
Specular lighting: 2 Models for WHEN we see HIGHLIGHTSpecular lighting: 2 Models for WHEN we see HIGHLIGHT
nR
Reflected light R aligns with camera direction C
L
Phong
nR L
C C
L is “to light” C is “to camera”R is reflection of -L H is (L+C)/2 n is pixel normal
Halfway vector H aligns with normal n
Blinn-Phong
H
Wilf LaLonde ©2012Comp 4501
Specular lighting: The mathematical definitionSpecular lighting: The mathematical definition
• Phong model: Ks max (0,(C.Reflect(-L,n)))
i.e., reflected -L aligns with C.• Blinn-Phong: Ks max (0,Halfway(C,L).n))
i.e., average of C and L aligns with n.
nR L
Phong
nR L
C C
Blinn-Phong
H
Wilf LaLonde ©2012Comp 4501
Specular lightingSpecular lighting
• Usually define via material constant Ks.• We’ll use a demo dependent implemention.
float4 Ks () {return g_materialSpecularColor ;}
float4 Ks () {return float4 (0,0,0,0);} //i.e., no specular
or
Wilf LaLonde ©2012Comp 4501
Specular lighting: Blinn-PhongSpecular lighting: Blinn-Phong
float4 specularColor (float3 pixelNormal, float3 normalizedToLight, float3 normalizedToCamera) {
//Uses Blinn-Phong’s halfway vector… float3 halfway = normalize (normalizedToLight +normalizedToCamera); float intensity = pow (clamp01 (dot (halfway, pixelNormal)), g_SpecularExponent);
return Ks () * intensity;}
Wilf LaLonde ©2012Comp 4501
Combining ALL lighting componentsCombining ALL lighting components
• Multiply texture color by (ambient + diffuse)• Add specular color as an extra…
float4 combinedColor (float4 textureColor, float3 normal, float3 toLight, float3 toCamera , float shadowBrightness) {
//All vectors must be normalized…
return
textureColor * (ambientColor () + diffuseColor (normal, toLight, shadowBrightness)) +
specularColor (normal, toLight, toCamera); }
float4 combinedColor (float4 textureColor, float3 normal, float3 toLight, float3 toCamera) {
return combinedColor (textureColor, normal,toLight,toCamera , 1.0) }
Wilf LaLonde ©2012Comp 4501
95.450195.4501
Shader Concepts for
Dummies
Wilf LaLonde ©2012Comp 4501
Older shadersOlder shaders
• Early GPU work on 2x2 pixels in parallel running in lock step.
• This was to allow gradients to be computed on any variable by taking neighbor differences.
• This is used internally by tex2D to compute the mipmap level to use.
• Dynamic branching breaks lock stepping requiring subsequent access to use tex2DLOD or tex2Dgrad instead.
Wilf LaLonde ©2012Comp 4501
3 Vertex Shaders + thousands of Pixel Shaders3 Vertex Shaders + thousands of Pixel Shaders
X = A + (B-A)t where t = delta pixels / total pixels; e.g., 57/200.
200 total
pixels
57 pixels
A1
A2
A3
A4
Interpolation formula
X1 X2Xinside
1. Use flat top/bottom rectangle.2. Interpolate outside edges.3. Interpolate inside (scanlines)
Perspective correct interpolation interpolates A1/z1 to A2/z2 to get A (along with 1/z1 to 1/z2 to get Z) AND divides to get value without z.
Wilf LaLonde ©2012Comp 4501
Interpolating Vectors Changes the lengthInterpolating Vectors Changes the length
• Consider V1 + (V2 - V1) * t where t = 0.5.V1 + (V2 - V1) * 0.5
= V1 + 0.5 * V2 – 0.5 * V1
= 0.5 * V1 + 0.5 * V2
= 0.5 * (V1 + V2)
= average of V1 and V2.
V1 = [- 0.968, 0.25, 0.0] V2 = [+0.968, 0.25, 0.0]
Average = [0.0, 0.25, 0.0]
0.9682 + 0.252 = 0.9375 + 0.0625 = 1
unit lengthunit length
NOT unit length
Wilf LaLonde ©2012Comp 4501
95.450195.4501
STOP
Rest is Unfinished
Wilf LaLonde ©2012Comp 4501
95.450195.4501
DirectX11
Wilf LaLonde ©2012Comp 4501
CreditsCredits
• Some of this information comes from http://www.directxtutorial.com.
• Some comes from http://rastertek.com which provides a tutorial by building a simplified game engine.
• Additional information comes from “Practical Rendering & Computation with DirectX11, Zink, Pettineo, and Hoxley, CRC Press, 2011.
Wilf LaLonde ©2012Comp 4501
The Swap ChainThe Swap Chain
• The swap chain is the object representing a chain of buffers, swapping position pointers each time a new frame is rendered.
front butter back butter
&front butter &back butter Usage: flip the 2 pointers
What you currently
see
What you are
drawing for next time
Wilf LaLonde ©2012Comp 4501
Can Have More Than 2 BuffersCan Have More Than 2 Buffersfront butter back butter third butter
1 2 3beforeflipping
1 2 3after
flippingonce
1 2 3after
flippingtwice
What you currently see
What you are drawing for next time
What you are drawing for next time
http://rastertek.com
Wilf LaLonde ©2012Comp 4501
Programming DetailsProgramming Details
• Several things are needed to start the ball rolling...
• windowHandle: from windows
• device (“the graphics card”): who youtalk to for creating objects
• deviceContext: who you talk to for performing some action
• a swap chain: buffer flipper
• render target view for a texture resource
• depth stencil view for a depth stencil buffer
Wilf LaLonde ©2012Comp 4501
Programming-WiseProgramming-Wise
• Somwhere, you’ll need variables such as
ID3D11Device *device;
ID3D11DeviceContext *deviceContext;
IDXGISwapChain *swapchain;
Wilf LaLonde ©2012Comp 4501
• Object creation often require description objects of the appropriate type for submission to the create operation.
• Objects so created are reference counted and must subsequently be disposed of via a release operation.
Wilf LaLonde ©2012Comp 4501
Sample from rastertek.comSample from rastertek.com
DXGI_SWAP_CHAIN_DESC swapChainDescription;
//Initialize the swap chain description.ZeroMemory (&swapChainDescription, sizeof (swapChainDescription));
//Set to a single back buffer.swapChainDescription.BufferCount = 1; //Of back buffers (excludes front buffer)
//Set the width and height of the back buffer.swapChainDescription.BufferDesc.Width = screenWidth;swapChainDescription.BufferDesc.Height = screenHeight;
//Set regular 32-bit surface for the back buffer.swapChainDescription.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
//Interpretable as float 0.0 to 1.0.
//Code to determine screen’s refresh rate (DETAILS NOT SHOWN)...
numerator = displayModeList[i].RefreshRate.Numerator;
denominator = displayModeList[i].RefreshRate.Denominator;used on next slide
Wilf LaLonde ©2012Comp 4501
Sample from rastertek.comSample from rastertek.com
//Set the refresh rate of the back buffer.If (m_vsync_enabled) {
swapChainDescription.BufferDesc.RefreshRate.Numerator = numerator;swapChainDescription.BufferDesc.RefreshRate.Denominator =
denominator;} else { swapChainDescription.BufferDesc.RefreshRate.Numerator = 0;
swapChainDescription.BufferDesc.RefreshRate.Denominator = 1;}
//Set the usage of the back buffer.swapChainDescription.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
//Set the handle for the window to render to.swapChainDescription.OutputWindow = windowsHandle;
//Turn multisampling off.swapChainDescription.SampleDesc.Count = 1; //multisamples per pixelswapChainDescription.SampleDesc.Quality = 0;
important
Wilf LaLonde ©2012Comp 4501
Sample from rastertek.comSample from rastertek.com
//Set to full screen or windowed mode.swapChainDescription.Windowed = ! fullscreen;
//Set the scan line ordering and scaling to unspecified.swapChainDescription.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;swapChainDescription.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
//Discard the back buffer contents after presenting.swapChainDescription.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
//Don't set the advanced flags.swapChainDescription.Flags = 0; //Such as DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH
//Set the feature level to DirectX 11.D3D_FEATURE_LEVEL featureLevel = D3D_FEATURE_LEVEL_11_0;
//Create the swap chain, Direct3D device, and Direct3D device context (ALL at once)HRESULT result = D3D11CreateDeviceAndSwapChain (NULL,
D3D_DRIVER_TYPE_HARDWARE, NULL, 0, &featureLevel, 1, D3D11_SDK_VERSION, &swapChainDescription, &m_swapChain,
&m_device,NULL, &m_deviceContext);
If (FAILED (result)) {return false;} //Success or failure (caller quits if it fails)
which card to use
software mode
Wilf LaLonde ©2012Comp 4501
SummarySummary
D3D_FEATURE_LEVEL featureLevel = D3D_FEATURE_LEVEL_11_0;
HRESULT result = D3D11CreateDeviceAndSwapChain (NULL,D3D_DRIVER_TYPE_HARDWARE, NULL, 0, &featureLevel, 1, D3D11_SDK_VERSION, &swapChainDescription, &m_swapChain,
&m_device,NULL, &m_deviceContext);
If (FAILED (result)) {return false;} //Success or failure (caller quits if it fails)
SOMEWHERE IN YOUR DESTRUCTOR OR IN A CLOSEDOWN METHOD...
m_swapChain >Release ();m_device >Release ();m_deviceContext >Release ();
Assuming you have the following directories in VS2010 $(DXSDK_DIR)Include;$(IncludePath)$(DXSDK_DIR)Lib\x86;$(LibraryPath)
WHEN DRAWING IS FINISHED, PERFORM A FLIP...
m_swapChain >Present (0, 0);
immediately
next one
Wilf LaLonde ©2012Comp 4501
Rendering Frames: What You NeedRendering Frames: What You Need
• One or more drawing areas to draw called render target views: back buffer versus texture render target views).
• One depth/stencil view.• What part of the rectangular area to draw
into.
multiple render targets MRT
A FRAMEBUFFER is a concept used to denote the collection of views (so there are at least 2, 1 drawing target and 1 depth/stencil).
Wilf LaLonde ©2012Comp 4501
Rendering Frames: Multiple Frame BuffersRendering Frames: Multiple Frame Buffers
• Drawing into a texture and drawing onto the screen requires 2 frame buffers; i.e., 2+2 views.
copied from directxtutorial.com
one for
one for
Wilf LaLonde ©2012Comp 4501
RenderTargetsRenderTargets
ID3D11RenderTargetView* backbufferRenderTarget;ID3D11RenderTargetView* textureRenderTarget;
A render target view is a FRAMEBUFFER comprised of 1 or more drawing textures
(actually views) and a combined depth+stencil texture (actually a view)
Wilf LaLonde ©2012Comp 4501
Creating BackBuffer RenderTargetsCreating BackBuffer RenderTargets
ID3D11RenderTargetView* backbufferRenderTarget;ID3D11RenderTargetView* textureRenderTarget;
ID3D11Texture2D *backBufferTexture; swapchain->GetBuffer (0 /*First back buffer*/,
__uuidof (ID3D11Texture2D), (LPVOID*) &backBufferTexture);
device->CreateRenderTargetView (backBufferTexture, NULL, &backbufferRenderTarget);
backBufferTexture->Release();
Wilf LaLonde ©2012Comp 4501
Creating Texture RenderTargets: First Create a TextureCreating Texture RenderTargets: First Create a Texture
//Initialize the render target texture description.D3D11_TEXTURE2D_DESC textureDescription;ZeroMemory(&textureDescription, sizeof(textureDescription));
//Setup the render target texture description.textureDescription.Width = textureWidth;textureDescription.Height = textureHeight;textureDescription.MipLevels = 1; //0 means alltextureDescription.ArraySize = 1;textureDescription.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;textureDescription.SampleDesc.Count = 1; //No MSAAtextureDescription.Usage = D3D11_USAGE_DEFAULT;textureDescription.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;textureDescription.CPUAccessFlags = 0;textureDescription.MiscFlags = 0;
//Create the render target texture.device->CreateTexture2D (&textureDescription, NULL, &renderTargetTexture);
first create a texture
ID3D11Texture2D* renderTargetTexture; //Store it somewhere...
ignoring erro
r code
Wilf LaLonde ©2012Comp 4501
Create Texture RenderTargets: Then The RenderTarget or ViewCreate Texture RenderTargets: Then The RenderTarget or View
//Setup the description of the render target view.D3D11_RENDER_TARGET_VIEW_DESC renderTargetViewDescription;renderTargetViewDescription.Format = textureDescription.Format;renderTargetViewDescription.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;renderTargetViewDescription.Texture2D.MipSlice = 0; //Use mipmap level 0
//Create the render target view.device->CreateRenderTargetView (renderTargetTexture,
&renderTargetViewDescription, &textureRenderTarget));
ID3D11RenderTargetView* backbufferRenderTarget;ID3D11RenderTargetView* textureRenderTarget;
ID3D11Texture2D* renderTargetTexture; //Store it somewhere...
Wilf LaLonde ©2012Comp 4501
Create Texture RenderTargets: Need a Shader Resource ViewCreate Texture RenderTargets: Need a Shader Resource View
//Setup the description of the shader resource view.D3D11_SHADER_RESOURCE_VIEW_DESC shaderResourceViewDescription;
shaderResourceViewDescription.Format = textureDescription.Format;shaderResourceViewDescription.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;shaderResourceViewDescription.Texture2D.MostDetailedMip = 0;shaderResourceViewDescription.Texture2D.MipLevels = 1;
//Create the shader resource view.device->CreateShaderResourceView (renderTargetTexture, &shaderResourceViewDescription, &shaderResourceView);
ID3D11Texture2D *renderTargetTexture; //Store it somewhere...ID3D11ShaderResourceView *shaderResourceView; //Store it somewhere...
Wilf LaLonde ©2012Comp 4501
RenderTargetsRenderTargets
ID3D11RenderTargetView* backbufferRenderTarget;ID3D11RenderTargetView* textureRenderTarget;
We also need a combined depth+stencil view
Wilf LaLonde ©2012Comp 4501
Creating a DepthStencilBuffer: First The TestureCreating a DepthStencilBuffer: First The Testure
//Initialize the description of the texture.D3D11_TEXTURE2D_DESC textureDescription;ZeroMemory (&textureDescription, sizeof (textureDescription));
//Set up the description of the texture.textureDescription.Width = width; //such as screenWidthtextureDescription.Height = height; //such as screenHeighttextureDescription.MipLevels = 1;textureDescription.ArraySize = 1;textureDescription.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
//or DXGI_FORMAT_D32_FLOATtextureDescription.SampleDesc.Count = 1; //NO MSAAtextureDescription.SampleDesc.Quality = 0;textureDescription.Usage = D3D11_USAGE_DEFAULT;textureDescription.BindFlags = D3D11_BIND_DEPTH_STENCIL;textureDescription.CPUAccessFlags = 0;textureDescription.MiscFlags = 0;
//Create the texture using the filled out description.device->CreateTexture2D(&textureDescription, NULL, &depthStencilTexture);
ID3D11Texture2D *depthStencilTexture; //Store it somewhere...ID3D11DepthStencilView * depthStencilView; //Store it somewhere...
Wilf LaLonde ©2012Comp 4501
Creating a DepthStencilBuffer: Second the ViewCreating a DepthStencilBuffer: Second the View
//Initialize the depth stencil view.D3D11_DEPTH_STENCIL_VIEW_DESC viewDescripion;ZeroMemory (&viewDescription, sizeof (viewDescription));
//Set up the depth stencil view description.viewDescription.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
//or DXGI_FORMAT_D32_FLOAT viewDescription.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;viewDescription.Texture2D.MipSlice = 0;
//Create the depth stencil view.device->CreateDepthStencilView (depthStencilTexture, &viewDescription,
&depthStencilView
ID3D11Texture2D *depthStencilTexture; //Store it somewhere...ID3D11DepthStencilView *depthStencilView; //Store it somewhere...
Wilf LaLonde ©2012Comp 4501
SwitchingRenderTargetsSwitchingRenderTargets
ID3D11RenderTargetView* backbufferRenderTarget;ID3D11RenderTargetView* textureRenderTarget;
A render target view is a FRAMEBUFFER
We’ve shown how to create one with at least 2 pieces (a draw view and a depth-stencil view)... Now how do we switch to one
deviceContext->OMSetRenderTargets (1, &ANY_RENDER_TARGET, depthStencilView);
number of multiple render targets MRT
the address of an array of render targets
Wilf LaLonde ©2012Comp 4501
ViewportViewport
// Setup the viewport for rendering. viewport.Width = (float)screenWidth; viewport.Height = (float)screenHeight; viewport.MinDepth = 0.0f; viewport.MaxDepth = 1.0f; viewport.TopLeftX = 0.0f; viewport.TopLeftY = 0.0f;
// Create the viewport. m_deviceContext->RSSetViewports(1, &viewport);
// Setup the projection matrix.fieldOfView = (float)D3DX_PI / 4.0f;screenAspect = (float)screenWidth / (float)screenHeight;
// Create the projection matrix for 3D rendering.D3DXMatrixPerspectiveFovLH(&m_projectionMatrix, fieldOfView, screenAspect, screenNear, screenDepth);
// Initialize the world matrix to the identity matrix. D3DXMatrixIdentity(&m_worldMatrix);
// Create an orthographic projection matrix for 2D rendering.D3DXMatrixOrthoLH(&m_orthoMatrix, (float)screenWidth, (float)screenHeight, screenNear, screenDepth);
Wilf LaLonde ©2012Comp 4501
Creating a Vertex BufferCreating a Vertex Buffer
// globalstruct VERTEX{FLOAT X, Y, Z; D3DXCOLOR Color;}; // a struct to define a vertexID3D11Buffer *pVBuffer; // the vertex buffer
void InitGraphics(){ // create a triangle using the VERTEX struct VERTEX OurVertices[] = { {0.0f, 0.5f, 0.0f, D3DXCOLOR(1.0f, 0.0f, 0.0f, 1.0f)}, {0.45f, -0.5, 0.0f, D3DXCOLOR(0.0f, 1.0f, 0.0f, 1.0f)}, {-0.45f, -0.5f, 0.0f, D3DXCOLOR(0.0f, 0.0f, 1.0f, 1.0f)} };
// create the vertex buffer D3D11_BUFFER_DESC bd; ZeroMemory(&bd, sizeof(bd));
bd.Usage = D3D11_USAGE_DYNAMIC; // write access access by CPU and GPU bd.ByteWidth = sizeof(VERTEX) * 3; // size is the VERTEX struct * 3 bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; // use as a vertex buffer bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; // allow CPU to write in buffer
dev->CreateBuffer(&bd, NULL, &pVBuffer); // create the buffer
// copy the vertices into the buffer D3D11_MAPPED_SUBRESOURCE ms; devcon->Map(pVBuffer, NULL, D3D11_MAP_WRITE_DISCARD, NULL, &ms); // map the buffer memcpy(ms.pData, OurVertices, sizeof(OurVertices)); // copy the data devcon->Unmap(pVBuffer, NULL); // unmap the buffer}
Wilf LaLonde ©2012Comp 4501
Creating Vertex and Index BuffersCreating Vertex and Index Buffers
void ModelClass::InitializeBuffers(ID3D11Device* device){VertexType* vertices;unsigned long* indices;D3D11_BUFFER_DESC vertexBufferDesc, indexBufferDesc;D3D11_SUBRESOURCE_DATA vertexData, indexData;int i;
noteMessage ("Failed to create a vertex or index buffer for the model...");// Create the vertex array.vertices = new VertexType[m_vertexCount];
// Create the index array.indices = new unsigned long[m_indexCount];
// Load the vertex array and index array with data.for(i=0; i<m_vertexCount; i++){vertices[i].position = D3DXVECTOR3(m_model[i].x, m_model[i].y, m_model[i].z);vertices[i].texture = D3DXVECTOR2(m_model[i].tu, m_model[i].tv);vertices[i].normal = D3DXVECTOR3(m_model[i].nx, m_model[i].ny, m_model[i].nz);
indices[i] = i;}
// Set up the description of the static vertex buffer. vertexBufferDesc.Usage = D3D11_USAGE_DEFAULT; vertexBufferDesc.ByteWidth = sizeof(VertexType) * m_vertexCount; vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; vertexBufferDesc.CPUAccessFlags = 0; vertexBufferDesc.MiscFlags = 0;vertexBufferDesc.StructureByteStride = 0;
// Give the subresource structure a pointer to the vertex data. vertexData.pSysMem = vertices;vertexData.SysMemPitch = 0;vertexData.SysMemSlicePitch = 0;
// Now create the vertex buffer. TRY (device->CreateBuffer(&vertexBufferDesc, &vertexData, &m_vertexBuffer));
// Set up the description of the static index buffer. indexBufferDesc.Usage = D3D11_USAGE_DEFAULT; indexBufferDesc.ByteWidth = sizeof(unsigned long) * m_indexCount; indexBufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER; indexBufferDesc.CPUAccessFlags = 0; indexBufferDesc.MiscFlags = 0;indexBufferDesc.StructureByteStride = 0;
// Give the subresource structure a pointer to the index data. indexData.pSysMem = indices;indexData.SysMemPitch = 0;indexData.SysMemSlicePitch = 0;
// Create the index buffer.TRY (device->CreateBuffer(&indexBufferDesc, &indexData, &m_indexBuffer));
// Release the arrays now that the vertex and index buffers have been created and loaded.delete [] vertices;delete [] indices;
noteMessage ("");}
Wilf LaLonde ©2012Comp 4501
Compiling ShadersCompiling Shaders
•void InitPipeline(){ // load and compile the two shaders ID3D10Blob *VS, *PS; D3DX11CompileFromFile(L"shaders.hlsl", 0, 0, "VShader", "vs_5_0", 0, 0, 0, &VS, 0, 0); D3DX11CompileFromFile(L"shaders.hlsl", 0, 0, "PShader", "ps_5_0", 0, 0, 0, &PS, 0, 0);
// encapsulate both shaders into shader objects dev->CreateVertexShader(VS->GetBufferPointer(), VS->GetBufferSize(), NULL, &pVS); dev->CreatePixelShader(PS->GetBufferPointer(), PS->GetBufferSize(), NULL, &pPS);
// set the shader objects devcon->VSSetShader(pVS, 0, 0); devcon->PSSetShader(pPS, 0, 0);
// create the input layout object D3D11_INPUT_ELEMENT_DESC ied[] = { {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, {"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0}, };
dev->CreateInputLayout(ied, 2, VS->GetBufferPointer(), VS->GetBufferSize(), &pLayout); devcon->IASetInputLayout(pLayout);}
Wilf LaLonde ©2012Comp 4501
Drawing a Vertex BufferDrawing a Vertex Buffer
•// this is the function used to render a single framevoid RenderFrame(void){ // clear the back buffer to a deep blue devcon->ClearRenderTargetView(backbuffer, D3DXCOLOR(0.0f, 0.2f, 0.4f, 1.0f));
// select which vertex buffer to display UINT stride = sizeof(VERTEX); UINT offset = 0; devcon->IASetVertexBuffers(0, 1, &pVBuffer, &stride, &offset);
// select which primtive type we are using devcon->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
// draw the vertex buffer to the back buffer devcon->Draw(3, 0);
// switch the back buffer and the front buffer swapchain->Present(0, 0);}
Wilf LaLonde ©2012Comp 4501
Setting Up Shader VariablesSetting Up Shader Variables
bool TextureShaderClass::SetShaderParameters(ID3D11DeviceContext* deviceContext, D3DXMATRIX worldMatrix, D3DXMATRIX viewMatrix, D3DXMATRIX projectionMatrix, ID3D11ShaderResourceView* texture){HRESULT result; D3D11_MAPPED_SUBRESOURCE mappedResource;ConstantBufferType* dataPtr;unsigned int bufferNumber;
// Lock the constant buffer so it can be written to.result = deviceContext->Map(m_constantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);if(FAILED(result)){return false;}
// Get a pointer to the data in the constant buffer.dataPtr = (ConstantBufferType*)mappedResource.pData;
// Transpose the matrices to prepare them for the shader.D3DXMatrixTranspose(&worldMatrix, &worldMatrix);D3DXMatrixTranspose(&viewMatrix, &viewMatrix);D3DXMatrixTranspose(&projectionMatrix, &projectionMatrix);
// Copy the matrices into the constant buffer.dataPtr->world = worldMatrix;dataPtr->view = viewMatrix;dataPtr->projection = projectionMatrix;
// Unlock the constant buffer. deviceContext->Unmap(m_constantBuffer, 0);
// Set the position of the constant buffer in the vertex shader.bufferNumber = 0;
// Now set the constant buffer in the vertex shader with the updated values. deviceContext->VSSetConstantBuffers(bufferNumber, 1, &m_constantBuffer);
// Set shader texture resource in the pixel shader.deviceContext->PSSetShaderResources(0, 1, &texture);
return true;}