11.1

这道题要注意使用了line strip,由于曾经一直用triangle list,所以在几何渲染的时候easy算错定点描绘的顺序。

贴一些代码,大概就能把这个问题解释清楚了,由于框架还不是特别熟,所以是在原有样例的基础上建立的自己的代码

void TreeBillboardApp::BuildCircleBuffers()
{
//
//Create the vertex buffer
//
std::vector<Vertex::Basic32> vertices(32);
for (int i = 0; i < 32; i++)
{
vertices[i].Pos.x = cosf(MathHelper::Pi * i / 16);
vertices[i].Pos.y = 0;
vertices[i].Pos.z = sinf(MathHelper::Pi * i / 16); XMVECTOR p = XMLoadFloat3(&vertices[i].Pos);
XMStoreFloat3(&vertices[i].Normal, XMVector3Normalize(p)); vertices[i].Tex.x = i / 32;
vertices[i].Tex.y = 0;
} D3D11_BUFFER_DESC vbd;
vbd.Usage = D3D11_USAGE_IMMUTABLE;
vbd.ByteWidth = sizeof(Vertex::Basic32) * 32;
vbd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vbd.CPUAccessFlags = 0;
vbd.MiscFlags = 0;
vbd.StructureByteStride = 0;
D3D11_SUBRESOURCE_DATA vinitData;
vinitData.pSysMem = &vertices[0];
HR(md3dDevice->CreateBuffer(&vbd, &vinitData, &mCircleVB)); //
//Create the index buffer
// UINT indices[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
30, 31, 0 }; D3D11_BUFFER_DESC ibd;
ibd.Usage = D3D11_USAGE_IMMUTABLE;
ibd.ByteWidth = sizeof(UINT)* 33;
ibd.BindFlags = D3D11_BIND_INDEX_BUFFER;
ibd.CPUAccessFlags = 0;
ibd.MiscFlags = 0;
ibd.StructureByteStride = 0;
D3D11_SUBRESOURCE_DATA iinitData;
iinitData.pSysMem = indices;
HR(md3dDevice->CreateBuffer(&ibd, &iinitData, &mCircleIB));
} void TreeBillboardApp::DrawCircle(CXMMATRIX viewProj)
{
//--------------------------------------------------------------------------
//
//Draw the circle
//
// Set per object constants.
XMMATRIX world = XMLoadFloat4x4(&mCircleWorld);
XMMATRIX worldInvTranspose = MathHelper::InverseTranspose(world);
XMMATRIX worldViewProj = world*viewProj; Effects::CircleFX->SetWorld(world);
Effects::CircleFX->SetWorldInvTranspose(worldInvTranspose);
Effects::CircleFX->SetWorldViewProj(worldViewProj);
Effects::CircleFX->SetTexTransform(XMMatrixIdentity());
Effects::CircleFX->SetMaterial(mBoxMat);
Effects::CircleFX->SetDiffuseMap(mBoxMapSRV);
Effects::CircleFX->SetDirLights(mDirLights);
Effects::CircleFX->SetEyePosW(mEyePosW);
Effects::CircleFX->SetFogColor(Colors::Silver);
Effects::CircleFX->SetFogStart(15.0f);
Effects::CircleFX->SetFogRange(175.0f); md3dImmediateContext->IASetInputLayout(InputLayouts::Basic32);
md3dImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP); md3dImmediateContext->RSSetState(RenderStates::WireframeRS); UINT stride1 = sizeof(Vertex::Basic32);
UINT offset1 = 0;
md3dImmediateContext->IASetVertexBuffers(0, 1, &mCircleVB, &stride1, &offset1);
md3dImmediateContext->IASetIndexBuffer(mCircleIB, DXGI_FORMAT_R32_UINT, 0); ID3DX11EffectTechnique* circleTech;
D3DX11_TECHNIQUE_DESC techDesc; switch (mRenderOptions)
{
case RenderOptions::Lighting:
circleTech = Effects::CircleFX->Light3Tech;
break;
case RenderOptions::Textures:
circleTech = Effects::CircleFX->Light3TexAlphaClipTech;
break;
case RenderOptions::TexturesAndFog:
circleTech = Effects::CircleFX->Light3TexAlphaClipFogTech;
break;
} circleTech->GetDesc(&techDesc); for (UINT p = 0; p < techDesc.Passes; ++p)
{
//md3dImmediateContext->OMSetBlendState(RenderStates::AlphaToCoverageBS, blendFactor, 0xffffffff);
md3dImmediateContext->RSSetState(RenderStates::NoCullRS);
circleTech->GetPassByIndex(p)->Apply(0, md3dImmediateContext);
md3dImmediateContext->DrawIndexed(33, 0, 0); // Restore default render state.
md3dImmediateContext->RSSetState(0);
}
}

还专给那个circle单写了fx,请无视那凝视

//=============================================================================
// Basic.fx by Frank Luna (C) 2011 All Rights Reserved.
//
// Basic effect that currently supports transformations, lighting, and texturing.
//============================================================================= #include "LightHelper.fx" cbuffer cbPerFrame
{
DirectionalLight gDirLights[3];
float3 gEyePosW; float gFogStart;
float gFogRange;
float4 gFogColor;
}; cbuffer cbPerObject
{
float4x4 gWorld;
float4x4 gWorldInvTranspose;
float4x4 gWorldViewProj;
float4x4 gTexTransform;
Material gMaterial;
}; // Nonnumeric values cannot be added to a cbuffer.
Texture2D gDiffuseMap; SamplerState samAnisotropic
{
Filter = ANISOTROPIC;
MaxAnisotropy = 4; AddressU = WRAP;
AddressV = WRAP;
}; struct VertexIn
{
float3 PosL : POSITION;
float3 NormalL : NORMAL;
float2 Tex : TEXCOORD;
}; struct VertexOut
{
float4 PosH : SV_POSITION;
float3 PosW : POSITION;
float3 NormalW : NORMAL;
float2 Tex : TEXCOORD;
}; struct GeoOut
{
float4 PosH : SV_POSITION;
float3 PosW : POSITION;
float3 NormalW : NORMAL;
float2 Tex : TEXCOORD;
uint PrimID : SV_PrimitiveID;
}; VertexOut VS(VertexIn vin)
{
VertexOut vout; // Transform to world space space.
vout.PosW = mul(float4(vin.PosL, 1.0f), gWorld).xyz;
vout.NormalW = mul(vin.NormalL, (float3x3)gWorldInvTranspose); // Transform to homogeneous clip space.
vout.PosH = mul(float4(vin.PosL, 1.0f), gWorldViewProj); // Output vertex attributes for interpolation across triangle.
vout.Tex = mul(float4(vin.Tex, 0.0f, 1.0f), gTexTransform).xy; return vout;
} [maxvertexcount(4)]
void GS(line VertexOut gin[2],
uint primID : SV_PrimitiveID,
inout TriangleStream<GeoOut> triStream)
{
//
// Compute the local coordinate system of the sprite relative to the world
// space such that the billboard is aligned with the y-axis and faces the eye.
// float3 up = float3(0.0f, 5.0f, 0.0f);
//float3 look = gEyePosW - gin[0].CenterW;
//look.y = 0.0f; // y-axis aligned, so project to xz-plane
//look = normalize(look);
//float3 right = cross(up, look); //
// Compute triangle strip vertices (quad) in world space.
//
//float halfWidth = 0.5f*gin[0].SizeW.x;
//float halfHeight = 0.5f*gin[0].SizeW.y; float4 v[4];
v[0] = float4(gin[0].PosW, 1.0f);
v[1] = float4(gin[0].PosW + up, 1.0f);
v[2] = float4(gin[1].PosW, 1.0f);
v[3] = float4(gin[1].PosW + up, 1.0f); float3 n[4];
n[0] = gin[0].NormalW;
n[1] = gin[0].NormalW;
n[2] = gin[1].NormalW;
n[3] = gin[1].NormalW; float2 t[4];
t[0] = gin[0].Tex;
t[1].x = gin[0].Tex.x;
t[1].y = 1.0f;
t[2] = gin[1].Tex;
t[3].x = gin[1].Tex.x;
t[3].y = 1.0f; //
// Transform quad vertices to world space and output
// them as a triangle strip.
//
GeoOut gout;
[unroll]
for (int i = 0; i < 4; ++i)
{
gout.PosH = mul(v[i], gWorldViewProj);
gout.PosW = v[i].xyz;
gout.NormalW = n[i].xyz;
gout.Tex = t[i].xy;
gout.PrimID = primID; triStream.Append(gout);
}
} float4 PS(GeoOut pin, uniform int gLightCount, uniform bool gUseTexure, uniform bool gAlphaClip, uniform bool gFogEnabled) : SV_Target
{
// Interpolating normal can unnormalize it, so normalize it.
pin.NormalW = normalize(pin.NormalW); // The toEye vector is used in lighting.
float3 toEye = gEyePosW - pin.PosW; // Cache the distance to the eye from this surface point.
float distToEye = length(toEye); // Normalize.
toEye /= distToEye; // Default to multiplicative identity.
//float3 uvw = float3(pin.Tex, pin.PrimID % 4);
float4 texColor = float4(1, 1, 1, 1);
if (gUseTexure)
{
// Sample texture.
texColor = gDiffuseMap.Sample(samAnisotropic, pin.Tex); if (gAlphaClip)
{
// Discard pixel if texture alpha < 0.1. Note that we do this
// test as soon as possible so that we can potentially exit the shader
// early, thereby skipping the rest of the shader code.
clip(texColor.a - 0.1f);
}
} //
// Lighting.
// float4 litColor = texColor;
if (gLightCount > 0)
{
// Start with a sum of zero.
float4 ambient = float4(0.0f, 0.0f, 0.0f, 0.0f);
float4 diffuse = float4(0.0f, 0.0f, 0.0f, 0.0f);
float4 spec = float4(0.0f, 0.0f, 0.0f, 0.0f); // Sum the light contribution from each light source.
[unroll]
for (int i = 0; i < gLightCount; ++i)
{
float4 A, D, S;
ComputeDirectionalLight(gMaterial, gDirLights[i], pin.NormalW, toEye,
A, D, S); ambient += A;
diffuse += D;
spec += S;
} // Modulate with late add.
litColor = texColor*(ambient + diffuse) + spec;
} //
// Fogging
// if (gFogEnabled)
{
float fogLerp = saturate((distToEye - gFogStart) / gFogRange); // Blend the fog color and the lit color.
litColor = lerp(litColor, gFogColor, fogLerp);
} // Common to take alpha from diffuse material and texture.
litColor.a = gMaterial.Diffuse.a * texColor.a; return litColor;
} technique11 Light1
{
pass P0
{
SetVertexShader(CompileShader(vs_5_0, VS()));
SetGeometryShader(CompileShader( gs_5_0, GS() ));
SetPixelShader(CompileShader(ps_5_0, PS(1, false, false, false)));
}
} technique11 Light2
{
pass P0
{
SetVertexShader(CompileShader(vs_5_0, VS()));
SetGeometryShader(CompileShader( gs_5_0, GS() ));
SetPixelShader(CompileShader(ps_5_0, PS(2, false, false, false)));
}
} technique11 Light3
{
pass P0
{
SetVertexShader(CompileShader(vs_5_0, VS()));
SetGeometryShader(CompileShader( gs_5_0, GS() ));
SetPixelShader(CompileShader(ps_5_0, PS(3, false, false, false)));
}
} technique11 Light0Tex
{
pass P0
{
SetVertexShader(CompileShader(vs_5_0, VS()));
SetGeometryShader(CompileShader( gs_5_0, GS() ));
SetPixelShader(CompileShader(ps_5_0, PS(0, true, false, false)));
}
} technique11 Light1Tex
{
pass P0
{
SetVertexShader(CompileShader(vs_5_0, VS()));
SetGeometryShader(CompileShader( gs_5_0, GS() ));
SetPixelShader(CompileShader(ps_5_0, PS(1, true, false, false)));
}
} technique11 Light2Tex
{
pass P0
{
SetVertexShader(CompileShader(vs_5_0, VS()));
SetGeometryShader(CompileShader( gs_5_0, GS() ));
SetPixelShader(CompileShader(ps_5_0, PS(2, true, false, false)));
}
} technique11 Light3Tex
{
pass P0
{
SetVertexShader(CompileShader(vs_5_0, VS()));
SetGeometryShader(CompileShader(gs_5_0, GS()));
SetPixelShader(CompileShader(ps_5_0, PS(3, true, false, false)));
}
} technique11 Light0TexAlphaClip
{
pass P0
{
SetVertexShader(CompileShader(vs_5_0, VS()));
SetGeometryShader(CompileShader( gs_5_0, GS() ));
SetPixelShader(CompileShader(ps_5_0, PS(0, true, true, false)));
}
} technique11 Light1TexAlphaClip
{
pass P0
{
SetVertexShader(CompileShader(vs_5_0, VS()));
SetGeometryShader(CompileShader( gs_5_0, GS() ));
SetPixelShader(CompileShader(ps_5_0, PS(1, true, true, false)));
}
} technique11 Light2TexAlphaClip
{
pass P0
{
SetVertexShader(CompileShader(vs_5_0, VS()));
SetGeometryShader(CompileShader( gs_5_0, GS() ));
SetPixelShader(CompileShader(ps_5_0, PS(2, true, true, false)));
}
} technique11 Light3TexAlphaClip
{
pass P0
{
SetVertexShader(CompileShader(vs_5_0, VS()));
SetGeometryShader(CompileShader( gs_5_0, GS() ));
SetPixelShader(CompileShader(ps_5_0, PS(3, true, true, false)));
}
} technique11 Light1Fog
{
pass P0
{
SetVertexShader(CompileShader(vs_5_0, VS()));
SetGeometryShader(CompileShader( gs_5_0, GS() ));
SetPixelShader(CompileShader(ps_5_0, PS(1, false, false, true)));
}
} technique11 Light2Fog
{
pass P0
{
SetVertexShader(CompileShader(vs_5_0, VS()));
SetGeometryShader(CompileShader(gs_5_0, GS()));
SetPixelShader(CompileShader(ps_5_0, PS(2, false, false, true)));
}
} technique11 Light3Fog
{
pass P0
{
SetVertexShader(CompileShader(vs_5_0, VS()));
SetGeometryShader(CompileShader( gs_5_0, GS() ));
SetPixelShader(CompileShader(ps_5_0, PS(3, false, false, true)));
}
} technique11 Light0TexFog
{
pass P0
{
SetVertexShader(CompileShader(vs_5_0, VS()));
SetGeometryShader(CompileShader( gs_5_0, GS() ));
SetPixelShader(CompileShader(ps_5_0, PS(0, true, false, true)));
}
} technique11 Light1TexFog
{
pass P0
{
SetVertexShader(CompileShader(vs_5_0, VS()));
SetGeometryShader(CompileShader( gs_5_0, GS() ));
SetPixelShader(CompileShader(ps_5_0, PS(1, true, false, true)));
}
} technique11 Light2TexFog
{
pass P0
{
SetVertexShader(CompileShader(vs_5_0, VS()));
SetGeometryShader(CompileShader( gs_5_0, GS() ));
SetPixelShader(CompileShader(ps_5_0, PS(2, true, false, true)));
}
} technique11 Light3TexFog
{
pass P0
{
SetVertexShader(CompileShader(vs_5_0, VS()));
SetGeometryShader(CompileShader( gs_5_0, GS() ));
SetPixelShader(CompileShader(ps_5_0, PS(3, true, false, true)));
}
} technique11 Light0TexAlphaClipFog
{
pass P0
{
SetVertexShader(CompileShader(vs_5_0, VS()));
SetGeometryShader(CompileShader( gs_5_0, GS() ));
SetPixelShader(CompileShader(ps_5_0, PS(0, true, true, true)));
}
} technique11 Light1TexAlphaClipFog
{
pass P0
{
SetVertexShader(CompileShader(vs_5_0, VS()));
SetGeometryShader(CompileShader( gs_5_0, GS() ));
SetPixelShader(CompileShader(ps_5_0, PS(1, true, true, true)));
}
} technique11 Light2TexAlphaClipFog
{
pass P0
{
SetVertexShader(CompileShader(vs_5_0, VS()));
SetGeometryShader(CompileShader( gs_5_0, GS() ));
SetPixelShader(CompileShader(ps_5_0, PS(2, true, true, true)));
}
} technique11 Light3TexAlphaClipFog
{
pass P0
{
SetVertexShader(CompileShader(vs_5_0, VS()));
SetGeometryShader(CompileShader( gs_5_0, GS() ));
SetPixelShader(CompileShader(ps_5_0, PS(3, true, true, true)));
}
}

11.2

Basic.fx
#include "LightHelper.fx"

cbuffer cbPerFrame
{
DirectionalLight gDirLights[3];
float3 gEyePosW; float gFogStart;
float gFogRange;
float4 gFogColor;
}; cbuffer cbPerObject
{
float4x4 gWorld;
float4x4 gWorldInvTranspose;
float4x4 gWorldViewProj;
float4x4 gTexTransform;
Material gMaterial;
}; // Nonnumeric values cannot be added to a cbuffer.
Texture2D gDiffuseMap; SamplerState samAnisotropic
{
Filter = ANISOTROPIC;
MaxAnisotropy = 4; AddressU = WRAP;
AddressV = WRAP;
}; struct VertexIn
{
float3 PosL : POSITION;
float3 NormalL : NORMAL;
float2 Tex : TEXCOORD;
}; struct VertexOut
{
float3 PosL : POSITION;
float3 NormalL : NORMAL;
float2 Tex : TEXCOORD;
}; struct GeoOut
{
float4 PosH : SV_POSITION;
float3 PosW : POSITION;
float3 NormalW : NORMAL;
float2 Tex : TEXCOORD;
float FogLerp : FOG;
}; VertexOut VS(VertexIn vin)
{
VertexOut vout; vout.PosL = vin.PosL;
vout.NormalL = vin.NormalL;
vout.Tex = vin.Tex; return vout;
} void SubdivideZero(VertexOut inVerts[3], out VertexOut outVerts[3])
{
outVerts[0] = inVerts[0];
outVerts[1] = inVerts[1];
outVerts[2] = inVerts[2];
} void Subdivide(VertexOut inVerts[3], out VertexOut outVerts[6])
{
VertexOut m[3]; // Compute edge midpoints.
m[0].PosL = 0.5f*(inVerts[0].PosL + inVerts[1].PosL);
m[1].PosL = 0.5f*(inVerts[1].PosL + inVerts[2].PosL);
m[2].PosL = 0.5f*(inVerts[2].PosL + inVerts[0].PosL); // Project onto unit sphere
m[0].PosL = normalize(m[0].PosL);
m[1].PosL = normalize(m[1].PosL);
m[2].PosL = normalize(m[2].PosL); // Derive normals.
m[0].NormalL = m[0].PosL;
m[1].NormalL = m[1].PosL;
m[2].NormalL = m[2].PosL; // Interpolate texture coordinates.
m[0].Tex = 0.5f*(inVerts[0].Tex + inVerts[1].Tex);
m[1].Tex = 0.5f*(inVerts[1].Tex + inVerts[2].Tex);
m[2].Tex = 0.5f*(inVerts[2].Tex + inVerts[0].Tex); outVerts[0] = inVerts[0];
outVerts[1] = m[0];
outVerts[2] = m[2];
outVerts[3] = m[1];
outVerts[4] = inVerts[2];
outVerts[5] = inVerts[1];
} void SubdivideTwice(VertexOut inVerts[3], out VertexOut outVerts[15])
{
VertexOut m[12]; // Compute edge midpoints.
m[0].PosL = 0.75f * inVerts[0].PosL + 0.25 * inVerts[2].PosL;
m[1].PosL = 0.5f * inVerts[0].PosL + 0.5 * inVerts[2].PosL;
m[2].PosL = 0.25f * inVerts[0].PosL + 0.75 * inVerts[2].PosL;
m[3].PosL = 0.75f * inVerts[2].PosL + 0.25 * inVerts[1].PosL;
m[4].PosL = 0.5f * inVerts[2].PosL + 0.5 * inVerts[1].PosL;
m[5].PosL = 0.25f * inVerts[2].PosL + 0.75 * inVerts[1].PosL;
m[6].PosL = 0.75f * inVerts[1].PosL + 0.25 * inVerts[0].PosL;
m[7].PosL = 0.5f * inVerts[1].PosL + 0.5 * inVerts[0].PosL;
m[8].PosL = 0.25f * inVerts[1].PosL + 0.75 * inVerts[0].PosL;
m[9].PosL = 0.5f * m[4].PosL + 0.5 * m[7].PosL;
m[10].PosL = 0.5f * m[1].PosL + 0.5 * m[7].PosL;
m[11].PosL = 0.5f * m[1].PosL + 0.5 * m[4].PosL; // Project onto unit sphere
m[0].PosL = normalize(m[0].PosL);
m[1].PosL = normalize(m[1].PosL);
m[2].PosL = normalize(m[2].PosL);
m[3].PosL = normalize(m[3].PosL);
m[4].PosL = normalize(m[4].PosL);
m[5].PosL = normalize(m[5].PosL);
m[6].PosL = normalize(m[6].PosL);
m[7].PosL = normalize(m[7].PosL);
m[8].PosL = normalize(m[8].PosL);
m[9].PosL = normalize(m[9].PosL);
m[10].PosL = normalize(m[10].PosL);
m[11].PosL = normalize(m[11].PosL); // Derive normals.
m[0].NormalL = m[0].PosL;
m[1].NormalL = m[1].PosL;
m[2].NormalL = m[2].PosL;
m[3].NormalL = m[3].PosL;
m[4].NormalL = m[4].PosL;
m[5].NormalL = m[5].PosL;
m[6].NormalL = m[6].PosL;
m[7].NormalL = m[7].PosL;
m[8].NormalL = m[8].PosL;
m[9].NormalL = m[9].PosL;
m[10].NormalL = m[10].PosL;
m[11].NormalL = m[11].PosL; // Interpolate texture coordinates.
m[0].Tex = 0.75f * inVerts[0].Tex + 0.25 * inVerts[2].Tex;
m[1].Tex = 0.5f * inVerts[0].Tex + 0.5 * inVerts[2].Tex;
m[2].Tex = 0.25f * inVerts[0].Tex + 0.75 * inVerts[2].Tex;
m[3].Tex = 0.75f * inVerts[2].Tex + 0.25 * inVerts[1].Tex;
m[4].Tex = 0.5f * inVerts[2].Tex + 0.5 * inVerts[1].Tex;
m[5].Tex = 0.25f * inVerts[2].Tex + 0.75 * inVerts[1].Tex;
m[6].Tex = 0.75f * inVerts[1].Tex + 0.25 * inVerts[0].Tex;
m[7].Tex = 0.5f * inVerts[1].Tex + 0.5 * inVerts[0].Tex;
m[8].Tex = 0.25f * inVerts[1].Tex + 0.75 * inVerts[0].Tex;
m[9].Tex = 0.5f * m[4].Tex + 0.5 * m[7].Tex;
m[10].Tex = 0.5f * m[1].Tex + 0.5 * m[7].Tex;
m[11].Tex = 0.5f * m[1].Tex + 0.5 * m[4].Tex; outVerts[0] = inVerts[0];
outVerts[1] = m[0];
outVerts[2] = m[1];
outVerts[3] = m[2];
outVerts[4] = inVerts[2];
outVerts[5] = m[3];
outVerts[6] = m[4];
outVerts[7] = m[5];
outVerts[8] = inVerts[1];
outVerts[9] = m[6];
outVerts[10] = m[7];
outVerts[11] = m[8];
outVerts[12] = m[9];
outVerts[13] = m[10];
outVerts[14] = m[11];
} void OutputSubdivisionZero(VertexOut v[3], inout TriangleStream<GeoOut> triStream)
{
GeoOut gout[3]; [unroll]
for (int i = 0; i < 3; ++i)
{
// Transorm to world space space.
gout[i].PosW = mul(float4(v[i].PosL, 1.0f), gWorld).xyz;
gout[i].NormalW = mul(v[i].NormalL, (float3x3)gWorldInvTranspose); // Transform to homogeneous clip space.
gout[i].PosH = mul(float4(v[i].PosL, 1.0f), gWorldViewProj); gout[i].Tex = v[i].Tex;
} [unroll]
for (int j = 0; j < 3; ++j)
{
triStream.Append(gout[j]);
}
} void OutputSubdivision(VertexOut v[6], inout TriangleStream<GeoOut> triStream)
{
GeoOut gout[6]; [unroll]
for (int i = 0; i < 6; ++i)
{
// Transorm to world space space.
gout[i].PosW = mul(float4(v[i].PosL, 1.0f), gWorld).xyz;
gout[i].NormalW = mul(v[i].NormalL, (float3x3)gWorldInvTranspose); // Transform to homogeneous clip space.
gout[i].PosH = mul(float4(v[i].PosL, 1.0f), gWorldViewProj); gout[i].Tex = v[i].Tex;
} [unroll]
for (int j = 0; j < 5; ++j)
{
triStream.Append(gout[j]);
}
triStream.RestartStrip(); triStream.Append(gout[1]);
triStream.Append(gout[5]);
triStream.Append(gout[3]);
} void OutputSubdivisionTwice(VertexOut v[15], inout TriangleStream<GeoOut> triStream)
{
GeoOut gout[15]; [unroll]
for (int i = 0; i < 15; ++i)
{
// Transorm to world space space.
gout[i].PosW = mul(float4(v[i].PosL, 1.0f), gWorld).xyz;
gout[i].NormalW = mul(v[i].NormalL, (float3x3)gWorldInvTranspose); // Transform to homogeneous clip space.
gout[i].PosH = mul(float4(v[i].PosL, 1.0f), gWorldViewProj); gout[i].Tex = v[i].Tex;
} triStream.Append(gout[0]);
triStream.Append(gout[11]);
triStream.Append(gout[1]);
triStream.Append(gout[13]);
triStream.Append(gout[2]);
triStream.Append(gout[14]);
triStream.Append(gout[3]);
triStream.Append(gout[5]);
triStream.Append(gout[4]); triStream.RestartStrip(); triStream.Append(gout[11]);
triStream.Append(gout[10]);
triStream.Append(gout[13]);
triStream.Append(gout[12]);
triStream.Append(gout[14]);
triStream.Append(gout[6]);
triStream.Append(gout[5]); triStream.RestartStrip(); triStream.Append(gout[10]);
triStream.Append(gout[9]);
triStream.Append(gout[12]);
triStream.Append(gout[7]);
triStream.Append(gout[6]); triStream.RestartStrip(); triStream.Append(gout[9]);
triStream.Append(gout[8]);
triStream.Append(gout[7]); } [maxvertexcount(24)]
void GS(triangle VertexOut gin[3], inout TriangleStream<GeoOut> triStream)
{ if (length(gEyePosW) >= 30)
{
VertexOut v[3];
SubdivideZero(gin, v);
OutputSubdivisionZero(v, triStream);
}
else if ((length(gEyePosW) >= 15))
{
VertexOut v[6];
Subdivide(gin, v);
OutputSubdivision(v, triStream);
}else
{
VertexOut v[15];
SubdivideTwice(gin, v);
OutputSubdivisionTwice(v, triStream);
}
} float4 PS(GeoOut pin, uniform int gLightCount, uniform bool gUseTexure, uniform bool gAlphaClip, uniform bool gFogEnabled) : SV_Target
{
// Interpolating normal can unnormalize it, so normalize it.
pin.NormalW = normalize(pin.NormalW); // The toEye vector is used in lighting.
float3 toEye = gEyePosW - pin.PosW; // Cache the distance to the eye from this surface point.
float distToEye = length(toEye); // Normalize.
toEye /= distToEye; // Default to multiplicative identity.
float4 texColor = float4(1, 1, 1, 1);
if(gUseTexure)
{
// Sample texture.
texColor = gDiffuseMap.Sample( samAnisotropic, pin.Tex ); if(gAlphaClip)
{
// Discard pixel if texture alpha < 0.1. Note that we do this
// test as soon as possible so that we can potentially exit the shader
// early, thereby skipping the rest of the shader code.
clip(texColor.a - 0.1f);
}
} //
// Lighting.
// float4 litColor = texColor;
if( gLightCount > 0 )
{
// Start with a sum of zero.
float4 ambient = float4(0.0f, 0.0f, 0.0f, 0.0f);
float4 diffuse = float4(0.0f, 0.0f, 0.0f, 0.0f);
float4 spec = float4(0.0f, 0.0f, 0.0f, 0.0f); // Sum the light contribution from each light source.
[unroll]
for(int i = 0; i < gLightCount; ++i)
{
float4 A, D, S;
ComputeDirectionalLight(gMaterial, gDirLights[i], pin.NormalW, toEye,
A, D, S); ambient += A;
diffuse += D;
spec += S;
} // Modulate with late add.
litColor = texColor*(ambient + diffuse) + spec;
} //
// Fogging
// if( gFogEnabled )
{
float fogLerp = saturate( (distToEye - gFogStart) / gFogRange ); // Blend the fog color and the lit color.
litColor = lerp(litColor, gFogColor, fogLerp);
} // Common to take alpha from diffuse material and texture.
litColor.a = gMaterial.Diffuse.a * texColor.a; return litColor;
} technique11 Light1
{
pass P0
{
SetVertexShader( CompileShader( vs_5_0, VS() ) );
SetGeometryShader(CompileShader(gs_5_0, GS()));
SetPixelShader( CompileShader( ps_5_0, PS(1, false, false, false) ) );
}
} technique11 Light2
{
pass P0
{
SetVertexShader( CompileShader( vs_5_0, VS() ) );
SetGeometryShader( CompileShader(gs_5_0, GS()) );
SetPixelShader( CompileShader( ps_5_0, PS(2, false, false, false) ) );
}
} technique11 Light3
{
pass P0
{
SetVertexShader( CompileShader( vs_5_0, VS() ) );
SetGeometryShader( CompileShader(gs_5_0, GS()) );
SetPixelShader( CompileShader( ps_5_0, PS(3, false, false, false) ) );
}
} technique11 Light0Tex
{
pass P0
{
SetVertexShader( CompileShader( vs_5_0, VS() ) );
SetGeometryShader( CompileShader(gs_5_0, GS()) );
SetPixelShader( CompileShader( ps_5_0, PS(0, true, false, false) ) );
}
} technique11 Light1Tex
{
pass P0
{
SetVertexShader( CompileShader( vs_5_0, VS() ) );
SetGeometryShader( CompileShader(gs_5_0, GS()) );
SetPixelShader( CompileShader( ps_5_0, PS(1, true, false, false) ) );
}
} technique11 Light2Tex
{
pass P0
{
SetVertexShader( CompileShader( vs_5_0, VS() ) );
SetGeometryShader( CompileShader(gs_5_0, GS()) );
SetPixelShader( CompileShader( ps_5_0, PS(2, true, false, false) ) );
}
} technique11 Light3Tex
{
pass P0
{
SetVertexShader( CompileShader( vs_5_0, VS() ) );
SetGeometryShader( CompileShader(gs_5_0, GS()) );
SetPixelShader( CompileShader( ps_5_0, PS(3, true, false, false) ) );
}
} technique11 Light0TexAlphaClip
{
pass P0
{
SetVertexShader( CompileShader( vs_5_0, VS() ) );
SetGeometryShader( CompileShader(gs_5_0, GS()) );
SetPixelShader( CompileShader( ps_5_0, PS(0, true, true, false) ) );
}
} technique11 Light1TexAlphaClip
{
pass P0
{
SetVertexShader( CompileShader( vs_5_0, VS() ) );
SetGeometryShader( CompileShader(gs_5_0, GS()) );
SetPixelShader( CompileShader( ps_5_0, PS(1, true, true, false) ) );
}
} technique11 Light2TexAlphaClip
{
pass P0
{
SetVertexShader( CompileShader( vs_5_0, VS() ) );
SetGeometryShader( CompileShader(gs_5_0, GS()) );
SetPixelShader( CompileShader( ps_5_0, PS(2, true, true, false) ) );
}
} technique11 Light3TexAlphaClip
{
pass P0
{
SetVertexShader( CompileShader( vs_5_0, VS() ) );
SetGeometryShader( CompileShader(gs_5_0, GS()) );
SetPixelShader( CompileShader( ps_5_0, PS(3, true, true, false) ) );
}
} technique11 Light1Fog
{
pass P0
{
SetVertexShader( CompileShader( vs_5_0, VS() ) );
SetGeometryShader( CompileShader(gs_5_0, GS()) );
SetPixelShader( CompileShader( ps_5_0, PS(1, false, false, true) ) );
}
} technique11 Light2Fog
{
pass P0
{
SetVertexShader( CompileShader( vs_5_0, VS() ) );
SetGeometryShader( CompileShader(gs_5_0, GS()) );
SetPixelShader( CompileShader( ps_5_0, PS(2, false, false, true) ) );
}
} technique11 Light3Fog
{
pass P0
{
SetVertexShader( CompileShader( vs_5_0, VS() ) );
SetGeometryShader( CompileShader(gs_5_0, GS()) );
SetPixelShader( CompileShader( ps_5_0, PS(3, false, false, true) ) );
}
} technique11 Light0TexFog
{
pass P0
{
SetVertexShader( CompileShader( vs_5_0, VS() ) );
SetGeometryShader( CompileShader(gs_5_0, GS()) );
SetPixelShader( CompileShader( ps_5_0, PS(0, true, false, true) ) );
}
} technique11 Light1TexFog
{
pass P0
{
SetVertexShader( CompileShader( vs_5_0, VS() ) );
SetGeometryShader( CompileShader(gs_5_0, GS()) );
SetPixelShader( CompileShader( ps_5_0, PS(1, true, false, true) ) );
}
} technique11 Light2TexFog
{
pass P0
{
SetVertexShader( CompileShader( vs_5_0, VS() ) );
SetGeometryShader( CompileShader(gs_5_0, GS()) );
SetPixelShader( CompileShader( ps_5_0, PS(2, true, false, true) ) );
}
} technique11 Light3TexFog
{
pass P0
{
SetVertexShader( CompileShader( vs_5_0, VS() ) );
SetGeometryShader( CompileShader(gs_5_0, GS()) );
SetPixelShader( CompileShader( ps_5_0, PS(3, true, false, true) ) );
}
} technique11 Light0TexAlphaClipFog
{
pass P0
{
SetVertexShader( CompileShader( vs_5_0, VS() ) );
SetGeometryShader( CompileShader(gs_5_0, GS()) );
SetPixelShader( CompileShader( ps_5_0, PS(0, true, true, true) ) );
}
} technique11 Light1TexAlphaClipFog
{
pass P0
{
SetVertexShader( CompileShader( vs_5_0, VS() ) );
SetGeometryShader( CompileShader(gs_5_0, GS()) );
SetPixelShader( CompileShader( ps_5_0, PS(1, true, true, true) ) );
}
} technique11 Light2TexAlphaClipFog
{
pass P0
{
SetVertexShader( CompileShader( vs_5_0, VS() ) );
SetGeometryShader( CompileShader(gs_5_0, GS()) );
SetPixelShader( CompileShader( ps_5_0, PS(2, true, true, true) ) );
}
} technique11 Light3TexAlphaClipFog
{
pass P0
{
SetVertexShader( CompileShader( vs_5_0, VS() ) );
SetGeometryShader( CompileShader(gs_5_0, GS()) );
SetPixelShader( CompileShader( ps_5_0, PS(3, true, true, true) ) );
}
}
LightHelper.fx
//***************************************************************************************
// LightHelper.fx by Frank Luna (C) 2011 All Rights Reserved.
//
// Structures and functions for lighting calculations.
//*************************************************************************************** struct DirectionalLight
{
float4 Ambient;
float4 Diffuse;
float4 Specular;
float3 Direction;
float pad;
}; struct PointLight
{
float4 Ambient;
float4 Diffuse;
float4 Specular; float3 Position;
float Range; float3 Att;
float pad;
}; struct SpotLight
{
float4 Ambient;
float4 Diffuse;
float4 Specular; float3 Position;
float Range; float3 Direction;
float Spot; float3 Att;
float pad;
}; struct Material
{
float4 Ambient;
float4 Diffuse;
float4 Specular; // w = SpecPower
float4 Reflect;
}; //---------------------------------------------------------------------------------------
// Computes the ambient, diffuse, and specular terms in the lighting equation
// from a directional light. We need to output the terms separately because
// later we will modify the individual terms.
//---------------------------------------------------------------------------------------
void ComputeDirectionalLight(Material mat, DirectionalLight L,
float3 normal, float3 toEye,
out float4 ambient,
out float4 diffuse,
out float4 spec)
{
// Initialize outputs.
ambient = float4(0.0f, 0.0f, 0.0f, 0.0f);
diffuse = float4(0.0f, 0.0f, 0.0f, 0.0f);
spec = float4(0.0f, 0.0f, 0.0f, 0.0f); // The light vector aims opposite the direction the light rays travel.
float3 lightVec = -L.Direction; // Add ambient term.
ambient = mat.Ambient * L.Ambient; // Add diffuse and specular term, provided the surface is in
// the line of site of the light. float diffuseFactor = dot(lightVec, normal); // Flatten to avoid dynamic branching.
[flatten]
if( diffuseFactor > 0.0f )
{
float3 v = reflect(-lightVec, normal);
float specFactor = pow(max(dot(v, toEye), 0.0f), mat.Specular.w); diffuse = diffuseFactor * mat.Diffuse * L.Diffuse;
spec = specFactor * mat.Specular * L.Specular;
}
} //---------------------------------------------------------------------------------------
// Computes the ambient, diffuse, and specular terms in the lighting equation
// from a point light. We need to output the terms separately because
// later we will modify the individual terms.
//---------------------------------------------------------------------------------------
void ComputePointLight(Material mat, PointLight L, float3 pos, float3 normal, float3 toEye,
out float4 ambient, out float4 diffuse, out float4 spec)
{
// Initialize outputs.
ambient = float4(0.0f, 0.0f, 0.0f, 0.0f);
diffuse = float4(0.0f, 0.0f, 0.0f, 0.0f);
spec = float4(0.0f, 0.0f, 0.0f, 0.0f); // The vector from the surface to the light.
float3 lightVec = L.Position - pos; // The distance from surface to light.
float d = length(lightVec); // Range test.
if( d > L.Range )
return; // Normalize the light vector.
lightVec /= d; // Ambient term.
ambient = mat.Ambient * L.Ambient; // Add diffuse and specular term, provided the surface is in
// the line of site of the light. float diffuseFactor = dot(lightVec, normal); // Flatten to avoid dynamic branching.
[flatten]
if( diffuseFactor > 0.0f )
{
float3 v = reflect(-lightVec, normal);
float specFactor = pow(max(dot(v, toEye), 0.0f), mat.Specular.w); diffuse = diffuseFactor * mat.Diffuse * L.Diffuse;
spec = specFactor * mat.Specular * L.Specular;
} // Attenuate
float att = 1.0f / dot(L.Att, float3(1.0f, d, d*d)); diffuse *= att;
spec *= att;
} //---------------------------------------------------------------------------------------
// Computes the ambient, diffuse, and specular terms in the lighting equation
// from a spotlight. We need to output the terms separately because
// later we will modify the individual terms.
//---------------------------------------------------------------------------------------
void ComputeSpotLight(Material mat, SpotLight L, float3 pos, float3 normal, float3 toEye,
out float4 ambient, out float4 diffuse, out float4 spec)
{
// Initialize outputs.
ambient = float4(0.0f, 0.0f, 0.0f, 0.0f);
diffuse = float4(0.0f, 0.0f, 0.0f, 0.0f);
spec = float4(0.0f, 0.0f, 0.0f, 0.0f); // The vector from the surface to the light.
float3 lightVec = L.Position - pos; // The distance from surface to light.
float d = length(lightVec); // Range test.
if( d > L.Range )
return; // Normalize the light vector.
lightVec /= d; // Ambient term.
ambient = mat.Ambient * L.Ambient; // Add diffuse and specular term, provided the surface is in
// the line of site of the light. float diffuseFactor = dot(lightVec, normal); // Flatten to avoid dynamic branching.
[flatten]
if( diffuseFactor > 0.0f )
{
float3 v = reflect(-lightVec, normal);
float specFactor = pow(max(dot(v, toEye), 0.0f), mat.Specular.w); diffuse = diffuseFactor * mat.Diffuse * L.Diffuse;
spec = specFactor * mat.Specular * L.Specular;
} // Scale by spotlight factor and attenuate.
float spot = pow(max(dot(-lightVec, L.Direction), 0.0f), L.Spot); // Scale by spotlight factor and attenuate.
float att = spot / dot(L.Att, float3(1.0f, d, d*d)); ambient *= spot;
diffuse *= att;
spec *= att;
}
Effects.h
#ifndef EFFECTS_H
#define EFFECTS_H #include "d3dUtil.h" #pragma region Effect
class Effect
{
public:
Effect(ID3D11Device* device, const std::wstring& filename);
virtual ~Effect(); private:
Effect(const Effect& rhs);
Effect& operator=(const Effect& rhs); protected:
ID3DX11Effect* mFX;
};
#pragma endregion #pragma region BasicEffect
class BasicEffect : public Effect
{
public:
BasicEffect(ID3D11Device* device, const std::wstring& filename);
~BasicEffect(); void SetWorldViewProj(CXMMATRIX M) { WorldViewProj->SetMatrix(reinterpret_cast<const float*>(&M)); }
void SetWorld(CXMMATRIX M) { World->SetMatrix(reinterpret_cast<const float*>(&M)); }
void SetWorldInvTranspose(CXMMATRIX M) { WorldInvTranspose->SetMatrix(reinterpret_cast<const float*>(&M)); }
void SetTexTransform(CXMMATRIX M) { TexTransform->SetMatrix(reinterpret_cast<const float*>(&M)); }
void SetEyePosW(const XMFLOAT3& v) { EyePosW->SetRawValue(&v, 0, sizeof(XMFLOAT3)); }
void SetDirLight(const DirectionalLight* lights) { DirLights->SetRawValue(lights, 0, 3 * sizeof(DirectionalLight)); }
void SetMatrial(const Material& mat) { Mat->SetRawValue(&mat, 0, sizeof(Material)); }
void SetDiffuseMap(ID3D11ShaderResourceView* tex) { DiffuseMap->SetResource(tex); } ID3DX11EffectTechnique* Light1Tech;
ID3DX11EffectTechnique* Light2Tech;
ID3DX11EffectTechnique* Light3Tech; ID3DX11EffectMatrixVariable* WorldViewProj;
ID3DX11EffectMatrixVariable* World;
ID3DX11EffectMatrixVariable* WorldInvTranspose;
ID3DX11EffectMatrixVariable* TexTransform;
ID3DX11EffectVectorVariable* EyePosW;
ID3DX11EffectVariable* DirLights;
ID3DX11EffectVariable* Mat; ID3DX11EffectShaderResourceVariable* DiffuseMap;
};
#pragma endregion #pragma region Effects
class Effects
{
public:
static void InitAll(ID3D11Device* device);
static void DestroyAll(); static BasicEffect* BasicFX;
};
#pragma endregion #endif
RenderStates.h
#ifndef RENDERSTATES_H
#define RENDERSTATES_H #include "d3dUtil.h" class RenderStates
{
public:
static void InitAll(ID3D11Device* device);
static void DestroyAll(); // Rasterize states
static ID3D11RasterizerState* WireframeRS;
static ID3D11RasterizerState* NoCullRS;
static ID3D11RasterizerState* CullClockwiseRS; // Blend states
static ID3D11BlendState* AlphaToCoverageBS;
static ID3D11BlendState* TransparentBS;
static ID3D11BlendState* NoRenderTargetWritesBS; // Depth/stencil states
}; #endif
Vertex.h
#ifndef VERTEX_H
#define VERTEX_H #include "d3dUtil.h" namespace Vertex
{
// Basic 32-byte vertex structure.
struct Basic32
{
Basic32() : Pos(0.0f, 0.0f, 0.0f), Normal(0.0f, 0.0f, 0.0f), Tex(0.0f, 0.0f) {}
Basic32(const XMFLOAT3& p, const XMFLOAT3& n, const XMFLOAT2& uv)
: Pos(p), Normal(n), Tex(uv) {}
Basic32(float px, float py, float pz, float nx, float ny, float nz, float u, float v)
: Pos(px, py, pz), Normal(nx, ny, nz), Tex(u, v) {}
XMFLOAT3 Pos;
XMFLOAT3 Normal;
XMFLOAT2 Tex;
};
} class InputLayoutDesc
{
public:
// Init like const int A::a[4] = {0, 1, 2, 3}; in .cpp file.
static const D3D11_INPUT_ELEMENT_DESC Basic32[3]; }; class InputLayouts
{
public:
static void InitAll(ID3D11Device* device);
static void DestroyAll(); static ID3D11InputLayout* Basic32;
}; #endif
Effects.cpp
#include "Effects.h" #pragma region Effect
Effect::Effect(ID3D11Device* device, const std::wstring& filename)
: mFX(0)
{
std::ifstream fin(filename, std::ios::binary); fin.seekg(0, std::ios_base::end);
int size = (int)fin.tellg();
fin.seekg(0, std::ios_base::beg);
std::vector<char> compiledShader(size); fin.read(&compiledShader[0], size);
fin.close(); HR(D3DX11CreateEffectFromMemory(&compiledShader[0], size,
0, device, &mFX));
} Effect::~Effect()
{
ReleaseCOM(mFX);
}
#pragma endregion #pragma region BasicEffect
BasicEffect::BasicEffect(ID3D11Device* device, const std::wstring& filename)
: Effect(device, filename)
{
Light1Tech = mFX->GetTechniqueByName("Light1");
Light2Tech = mFX->GetTechniqueByName("Light2");
Light3Tech = mFX->GetTechniqueByName("Light3"); WorldViewProj = mFX->GetVariableByName("gWorldViewProj")->AsMatrix();
World = mFX->GetVariableByName("gWorld")->AsMatrix();
WorldInvTranspose = mFX->GetVariableByName("gWorldInvTranspose")->AsMatrix();
TexTransform = mFX->GetVariableByName("gTexTransform")->AsMatrix();
EyePosW = mFX->GetVariableByName("gEyePosW")->AsVector();
DirLights = mFX->GetVariableByName("gDirLights");
Mat = mFX->GetVariableByName("gMaterial");
DiffuseMap = mFX->GetVariableByName("gDiffuseMap")->AsShaderResource();
} BasicEffect::~BasicEffect()
{
}
#pragma endregion #pragma region Effects BasicEffect* Effects::BasicFX = 0; void Effects::InitAll(ID3D11Device* device)
{
BasicFX = new BasicEffect(device, L"FX/Basic.fxo");
} void Effects::DestroyAll()
{
SafeDelete(BasicFX);
}
#pragma endregion
Main.cpp
#include "d3dApp.h"
#include "d3dx11Effect.h"
#include "GeometryGenerator.h"
#include "MathHelper.h"
#include "Effects.h"
#include "Vertex.h"
#include "RenderStates.h" enum RenderOptions
{
Lit = 0,
Lit2 = 1,
}; enum TextureOptions
{
Wireframe = 0,
Color = 1,
};
class Icosahedron : public D3DApp
{
public:
Icosahedron(HINSTANCE hInstance);
~Icosahedron(); bool Init();
void OnResize();
void UpdateScene(float dt);
void DrawScene(); void OnMouseDown(WPARAM btnState, int x, int y);
void OnMouseUp(WPARAM btnState, int x, int y);
void OnMouseMove(WPARAM btnState, int x, int y); private:
void BuildIcosahedronGeometryBuffers(); private:
ID3D11Buffer* mIcosahedronVB;
ID3D11Buffer* mIcosahedronIB; ID3D11ShaderResourceView* mIcosahedronMapSRV; DirectionalLight mDirLights[3];
Material mIcosahedronMat; XMFLOAT4X4 mIcosahedronWorld; UINT mIcosahedronIndexCount; XMFLOAT4X4 mView;
XMFLOAT4X4 mProj; RenderOptions mRenderOptions;
TextureOptions mTexOptions; XMFLOAT3 mEyePosW; float mTheta;
float mPhi;
float mRadius; POINT mLastMousePos;
}; int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance,
PSTR cmdLine, int showCmd)
{
#if defined(DEBUG) | defined(_DEBUG)
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
#endif Icosahedron theApp(hInstance); if (!theApp.Init())
return 0; return theApp.Run();
} Icosahedron::Icosahedron(HINSTANCE hInstance)
: D3DApp(hInstance), mIcosahedronVB(0), mIcosahedronIB(0), mEyePosW(0.0f, 0.0f, 0.0f), mRenderOptions(RenderOptions::Lit),
mIcosahedronIndexCount(0), mTheta(1.3f*MathHelper::Pi), mPhi(0.4f*MathHelper::Pi), mRadius(80.0f), mTexOptions(TextureOptions::Color)
{
mMainWndCaption = L"Icosahedron";
mEnable4xMsaa = true; mLastMousePos.x = 0;
mLastMousePos.y = 0; XMMATRIX I = XMMatrixIdentity();
XMStoreFloat4x4(&mView, I);
XMStoreFloat4x4(&mProj, I); XMMATRIX icosahedronScale = XMMatrixScaling(5.0f, 5.0f, 5.0f);
XMMATRIX icosahedronOffset = XMMatrixTranslation(0.0f, 0.0f, 0.0f);
XMStoreFloat4x4(&mIcosahedronWorld, icosahedronScale*icosahedronOffset); mDirLights[0].Ambient = XMFLOAT4(0.2f, 0.2f, 0.2f, 1.0f);
mDirLights[0].Diffuse = XMFLOAT4(0.5f, 0.5f, 0.5f, 1.0f);
mDirLights[0].Specular = XMFLOAT4(0.5f, 0.5f, 0.5f, 1.0f);
mDirLights[0].Direction = XMFLOAT3(0.57735f, -0.57735f, 0.57735f); mDirLights[1].Ambient = XMFLOAT4(0.0f, 0.0f, 0.0f, 1.0f);
mDirLights[1].Diffuse = XMFLOAT4(0.20f, 0.20f, 0.20f, 1.0f);
mDirLights[1].Specular = XMFLOAT4(0.25f, 0.25f, 0.25f, 1.0f);
mDirLights[1].Direction = XMFLOAT3(-0.57735f, -0.57735f, 0.57735f); mDirLights[2].Ambient = XMFLOAT4(0.0f, 0.0f, 0.0f, 1.0f);
mDirLights[2].Diffuse = XMFLOAT4(0.2f, 0.2f, 0.2f, 1.0f);
mDirLights[2].Specular = XMFLOAT4(0.0f, 0.0f, 0.0f, 1.0f);
mDirLights[2].Direction = XMFLOAT3(0.0f, -0.707f, -0.707f); mIcosahedronMat.Ambient = XMFLOAT4(0.48f, 0.77f, 0.46f, 1.0f);
mIcosahedronMat.Diffuse = XMFLOAT4(0.48f, 0.77f, 0.46f, 1.0f);
mIcosahedronMat.Specular = XMFLOAT4(0.2f, 0.2f, 0.2f, 16.0f);
} Icosahedron::~Icosahedron()
{
md3dImmediateContext->ClearState();
ReleaseCOM(mIcosahedronVB);
ReleaseCOM(mIcosahedronIB); Effects::DestroyAll();
InputLayouts::DestroyAll();
RenderStates::DestroyAll();
} bool Icosahedron::Init()
{
if (!D3DApp::Init())
return false; Effects::InitAll(md3dDevice);
InputLayouts::InitAll(md3dDevice);
RenderStates::InitAll(md3dDevice); BuildIcosahedronGeometryBuffers(); return true;
} void Icosahedron::OnResize()
{
D3DApp::OnResize(); XMMATRIX P = XMMatrixPerspectiveFovLH(0.25f*MathHelper::Pi, AspectRatio(), 1.0f, 1000.0f);
XMStoreFloat4x4(&mProj, P);
} void Icosahedron::UpdateScene(float dt)
{
float x = mRadius*sinf(mPhi)*cosf(mTheta);
float z = mRadius*sinf(mPhi)*sinf(mTheta);
float y = mRadius*cosf(mPhi); mEyePosW = XMFLOAT3(x, y, z); // Build the view matrix.
XMVECTOR pos = XMVectorSet(x, y, z, 1.0f);
XMVECTOR target = XMVectorZero();
XMVECTOR up = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f); XMMATRIX V = XMMatrixLookAtLH(pos, target, up);
XMStoreFloat4x4(&mView, V); //
// Switch the render mode based in key input
//
if (GetAsyncKeyState('1') & 0x8000)
mRenderOptions = RenderOptions::Lit; if (GetAsyncKeyState('2') & 0x8000)
mRenderOptions = RenderOptions::Lit2; if (GetAsyncKeyState('W') & 0x8000)
mTexOptions = TextureOptions::Wireframe; if (GetAsyncKeyState('C') & 0x8000)
mTexOptions = TextureOptions::Color;
} void Icosahedron::DrawScene()
{
md3dImmediateContext->ClearRenderTargetView(mRenderTargetView, reinterpret_cast<const float*>(&Colors::Silver));
md3dImmediateContext->ClearDepthStencilView(mDepthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0); md3dImmediateContext->IASetInputLayout(InputLayouts::Basic32);
md3dImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); XMMATRIX view = XMLoadFloat4x4(&mView);
XMMATRIX proj = XMLoadFloat4x4(&mProj);
XMMATRIX viewProj = view*proj; Effects::BasicFX->SetEyePosW(mEyePosW);
Effects::BasicFX->SetDirLight(mDirLights); //
// Figure out which technique to use
//
ID3DX11EffectTechnique* IcosahedronTech; switch (mRenderOptions)
{
case RenderOptions::Lit:
IcosahedronTech = Effects::BasicFX->Light1Tech;
break;
case RenderOptions::Lit2:
IcosahedronTech = Effects::BasicFX->Light2Tech;
break;
} UINT stride = sizeof(Vertex::Basic32);
UINT offset = 0; D3DX11_TECHNIQUE_DESC techDesc; //
// DraW the icosahedron.
// IcosahedronTech->GetDesc(&techDesc);
for (UINT p = 0; p < techDesc.Passes; ++p)
{ md3dImmediateContext->IASetVertexBuffers(0, 1, &mIcosahedronVB, &stride, &offset);
md3dImmediateContext->IASetIndexBuffer(mIcosahedronIB, DXGI_FORMAT_R32_UINT, 0); // Set per object constants.
XMMATRIX world = XMLoadFloat4x4(&mIcosahedronWorld);
XMMATRIX worldInvTranspose = MathHelper::InverseTranspose(world);
XMMATRIX worldViewProj = world*view*proj; Effects::BasicFX->SetWorld(world);
Effects::BasicFX->SetWorldInvTranspose(worldInvTranspose);
Effects::BasicFX->SetWorldViewProj(worldViewProj);
Effects::BasicFX->SetTexTransform(XMMatrixIdentity());
Effects::BasicFX->SetMatrial(mIcosahedronMat);
//Effects::BasicFX->SetDiffuseMap(mIcosahedronMapSRV); switch (mTexOptions)
{
case TextureOptions::Color:
md3dImmediateContext->RSSetState(RenderStates::NoCullRS);
break;
case TextureOptions::Wireframe:
md3dImmediateContext->RSSetState(RenderStates::WireframeRS);
break;
} IcosahedronTech->GetPassByIndex(p)->Apply(0, md3dImmediateContext);
md3dImmediateContext->DrawIndexed(mIcosahedronIndexCount, 0, 0); // Restore default render state.
md3dImmediateContext->RSSetState(0);
} HR(mSwapChain->Present(0, 0));
} void Icosahedron::OnMouseDown(WPARAM btnState, int x, int y)
{
mLastMousePos.x = x;
mLastMousePos.y = y; SetCapture(mhMainWnd);
} void Icosahedron::OnMouseUp(WPARAM btnState, int x, int y)
{
ReleaseCapture();
} void Icosahedron::OnMouseMove(WPARAM btnState, int x, int y)
{
if ((btnState & MK_LBUTTON) != 0)
{
// Make each pixel correspond to a quater of a degree.
float dx = XMConvertToRadians(0.25f*static_cast<float>(x - mLastMousePos.x));
float dy = XMConvertToRadians(0.25f*static_cast<float>(y - mLastMousePos.y)); // Update angles based on input to orbit camera around box.
mTheta += dx;
mPhi += dy; // Restric the angle mPhi.
mPhi = MathHelper::Clamp(mPhi, 0.1f, MathHelper::Pi - 0.1f);
}
else if ((btnState & MK_RBUTTON) != 0)
{
// Make each pixel correspond to 0.01 unit in the scene.
float dx = 0.1f*static_cast<float>(x - mLastMousePos.x);
float dy = 0.1f*static_cast<float>(y - mLastMousePos.y); //Update the camera radius based on inputs.
mRadius += dx - dy; // Restrict the radius.
mRadius = MathHelper::Clamp(mRadius, 10.0f, 500.0f);
} mLastMousePos.x = x;
mLastMousePos.y = y;
} void Icosahedron::BuildIcosahedronGeometryBuffers()
{
GeometryGenerator::MeshData icosahedron; GeometryGenerator geoGen;
geoGen.CreateGeosphere(1.0f, 0u, icosahedron); //
// Extract the vertex elements we are interested in and pack the
// vertices of all the meshes into one vertex buffer
// std::vector<Vertex::Basic32> vertices(icosahedron.Vertices.size()); for (UINT i = 0; i < icosahedron.Vertices.size(); ++i)
{
vertices[i].Pos = icosahedron.Vertices[i].Position;
vertices[i].Normal = icosahedron.Vertices[i].Normal;
vertices[i].Tex = icosahedron.Vertices[i].TexC;
} D3D11_BUFFER_DESC vbd;
vbd.Usage = D3D11_USAGE_IMMUTABLE;
vbd.ByteWidth = sizeof(Vertex::Basic32) * icosahedron.Vertices.size();
vbd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vbd.CPUAccessFlags = 0;
vbd.MiscFlags = 0;
D3D11_SUBRESOURCE_DATA vinitData;
vinitData.pSysMem = &vertices[0];
HR(md3dDevice->CreateBuffer(&vbd, &vinitData, &mIcosahedronVB)); //
// Pack the indices of all the meshes into one index buffer.
// D3D11_BUFFER_DESC ibd;
ibd.Usage = D3D11_USAGE_IMMUTABLE;
ibd.ByteWidth = sizeof(UINT)* icosahedron.Indices.size();
ibd.BindFlags = D3D11_BIND_INDEX_BUFFER;
ibd.CPUAccessFlags = 0;
ibd.MiscFlags = 0;
D3D11_SUBRESOURCE_DATA iinitData;
iinitData.pSysMem = &icosahedron.Indices[0];
mIcosahedronIndexCount = icosahedron.Indices.size();
HR(md3dDevice->CreateBuffer(&ibd, &iinitData, &mIcosahedronIB));
}
RenderStates.cpp
#include "RenderStates.h" ID3D11RasterizerState* RenderStates::WireframeRS = 0;
ID3D11RasterizerState* RenderStates::NoCullRS = 0;
ID3D11RasterizerState* RenderStates::CullClockwiseRS = 0; ID3D11BlendState* RenderStates::AlphaToCoverageBS = 0;
ID3D11BlendState* RenderStates::TransparentBS = 0;
ID3D11BlendState* RenderStates::NoRenderTargetWritesBS = 0; void RenderStates::InitAll(ID3D11Device* device)
{
//
// WireframeRS
//
D3D11_RASTERIZER_DESC wireframeDesc;
ZeroMemory(&wireframeDesc, sizeof(D3D11_RASTERIZER_DESC));
wireframeDesc.FillMode = D3D11_FILL_WIREFRAME;
wireframeDesc.CullMode = D3D11_CULL_BACK;
wireframeDesc.FrontCounterClockwise = false;
wireframeDesc.DepthClipEnable = true; HR(device->CreateRasterizerState(&wireframeDesc, &WireframeRS)); //
// NoCullRS
//
D3D11_RASTERIZER_DESC noCullDesc;
ZeroMemory(&noCullDesc, sizeof(D3D11_RASTERIZER_DESC));
noCullDesc.FillMode = D3D11_FILL_SOLID;
noCullDesc.CullMode = D3D11_CULL_NONE;
noCullDesc.FrontCounterClockwise = false;
noCullDesc.DepthClipEnable = true; HR(device->CreateRasterizerState(&noCullDesc, &NoCullRS)); //
// CullClockwiseRS
// // Note: Define such that we still cull backfaces by making front faces CCW.
// If we did not cull bacefaces, then we have to worry about the BackFace
// property in the D3D11_DEPTH_STENCIL_DESC
D3D11_RASTERIZER_DESC cullClockwiseDesc;
ZeroMemory(&cullClockwiseDesc, sizeof(D3D11_RASTERIZER_DESC));
cullClockwiseDesc.FillMode = D3D11_FILL_SOLID;
cullClockwiseDesc.CullMode = D3D11_CULL_BACK;
cullClockwiseDesc.FrontCounterClockwise = true;
cullClockwiseDesc.DepthClipEnable = true; HR(device->CreateRasterizerState(&cullClockwiseDesc, &CullClockwiseRS)); //
// AlphaToCoverageBS
// D3D11_BLEND_DESC alphaToCoverageDesc = { 0 };
alphaToCoverageDesc.AlphaToCoverageEnable = true;
alphaToCoverageDesc.IndependentBlendEnable = false;
alphaToCoverageDesc.RenderTarget[0].BlendEnable = false;
alphaToCoverageDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; HR(device->CreateBlendState(&alphaToCoverageDesc, &AlphaToCoverageBS)); //
// TransparentBS
// D3D11_BLEND_DESC transparentDesc = { 0 };
transparentDesc.AlphaToCoverageEnable = false;
transparentDesc.IndependentBlendEnable = false; transparentDesc.RenderTarget[0].BlendEnable = true;
transparentDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
transparentDesc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
transparentDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
transparentDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
transparentDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
transparentDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
transparentDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; HR(device->CreateBlendState(&transparentDesc, &TransparentBS)); //
//NoRenderTargetWritesBS
// D3D11_BLEND_DESC noRenderTargetWritesDesc = { 0 };
noRenderTargetWritesDesc.AlphaToCoverageEnable = false;
noRenderTargetWritesDesc.IndependentBlendEnable = false; noRenderTargetWritesDesc.RenderTarget[0].BlendEnable = false;
noRenderTargetWritesDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE;
noRenderTargetWritesDesc.RenderTarget[0].DestBlend = D3D11_BLEND_ZERO;
noRenderTargetWritesDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
noRenderTargetWritesDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
noRenderTargetWritesDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
noRenderTargetWritesDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
noRenderTargetWritesDesc.RenderTarget[0].RenderTargetWriteMask = 0; HR(device->CreateBlendState(&noRenderTargetWritesDesc, &NoRenderTargetWritesBS));
} void RenderStates::DestroyAll()
{
ReleaseCOM(WireframeRS);
ReleaseCOM(NoCullRS);
ReleaseCOM(CullClockwiseRS); ReleaseCOM(AlphaToCoverageBS);
ReleaseCOM(TransparentBS);
ReleaseCOM(NoRenderTargetWritesBS);
}
Vertex.cpp
#include "Vertex.h"
#include "Effects.h" #pragma region InputLayoutDesc const D3D11_INPUT_ELEMENT_DESC InputLayoutDesc::Basic32[3] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0 }
}; #pragma endregion #pragma region InputLayouts ID3D11InputLayout* InputLayouts::Basic32 = 0; void InputLayouts::InitAll(ID3D11Device* device)
{
D3DX11_PASS_DESC passDesc; //
// Basic32
// Effects::BasicFX->Light1Tech->GetPassByIndex(0)->GetDesc(&passDesc);
HR(device->CreateInputLayout(InputLayoutDesc::Basic32, 3, passDesc.pIAInputSignature,
passDesc.IAInputSignatureSize, &Basic32));
} void InputLayouts::DestroyAll()
{
ReleaseCOM(Basic32);
} #pragma endregion

11.3 那个primitiveID用的有点问题,GS的第一个參数用了个数组,所以primitiveID依照数组的第一个元素设置了

void Explosion(VertexOut inVerts[3], uint primID : SV_PrimitiveID, inout TriangleStream<GeoOut> triStream)
{
VertexOut explosionVerts[3];
GeoOut gout[3];
float3 u = inVerts[1].PosL - inVerts[0].PosL;
float3 v = inVerts[2].PosL - inVerts[0].PosL;
float3 n = cross(u, v);
[unroll]
for (int i = 0; i < 3; ++i)
{
explosionVerts[i].PosL = inVerts[i].PosL + /*primID * */gScale * gTime * n;
// Transorm to world space space.
gout[i].PosW = mul(float4(explosionVerts[i].PosL, 1.0f), gWorld).xyz;
gout[i].NormalW = mul(normalize(explosionVerts[i].PosL), (float3x3)gWorldInvTranspose); // Transform to homogeneous clip space.
gout[i].PosH = mul(float4(explosionVerts[i].PosL, 1.0f), gWorldViewProj); gout[i].Tex = inVerts[i].Tex;
} [unroll]
for (int j = 0; j < 3; ++j)
{
triStream.Append(gout[j]);
}
} [maxvertexcount(24)]
void GS(triangle VertexOut gin[3], uint primID : SV_PrimitiveID, inout TriangleStream<GeoOut> triStream)
{ if (length(gEyePosW) >= 30)
{
//VertexOut v[3];
//SubdivideZero(gin, v);
//OutputSubdivisionZero(v, triStream);
Explosion(gin, primID, triStream);
}
else if ((length(gEyePosW) >= 15))
{
VertexOut v[6];
Subdivide(gin, v);
OutputSubdivision(v, triStream);
}else
{
VertexOut v[15];
SubdivideTwice(gin, v);
OutputSubdivisionTwice(v, triStream);
}
}
    if (GetAsyncKeyState('E') & 0x8000)
{
fExpTimeBase = mTimer.TotalTime();
bExplosion = true;
} if (GetAsyncKeyState('F') & 0x8000)
fScale++;
}
    Effects::BasicFX->SetExpTime(mExpTime);
Effects::BasicFX->SetExplosionScalar(fScale);

和上一题比,代码变动不大

由于有爆炸效果,所以做了个gif,可能网页上看不到,下载就能看到

11.4代码写的非常乱,变量名设定的也不合适,但还好,效果出来了

//=============================================================================
// Basic.fx by Frank Luna (C) 2011 All Rights Reserved.
//
// Basic effect that currently supports transformations, lighting, and texturing.
//============================================================================= #include "LightHelper.fx" cbuffer cbPerFrame
{
DirectionalLight gDirLights[3];
float3 gEyePosW; float gFogStart;
float gFogRange;
float4 gFogColor;
}; cbuffer cbPerObject
{
float4x4 gWorld;
float4x4 gWorldInvTranspose;
float4x4 gWorldViewProj;
float4x4 gTexTransform;
Material gMaterial; }; // Nonnumeric values cannot be added to a cbuffer.
Texture2D gDiffuseMap; SamplerState samAnisotropic
{
Filter = ANISOTROPIC;
MaxAnisotropy = 4; AddressU = WRAP;
AddressV = WRAP;
}; struct VertexIn
{
float3 PosL : POSITION;
float3 NormalL : NORMAL;
float2 Tex : TEXCOORD;
}; struct VertexOut
{
float4 PosH : SV_POSITION;
float3 PosW : POSITION;
float3 NormalW : NORMAL;
float2 Tex : TEXCOORD;
}; struct GeoOut
{
float4 PosH : SV_POSITION;
float3 PosW : POSITION;
float3 NormalW : NORMAL;
float2 Tex : TEXCOORD;
}; VertexOut VS(VertexIn vin)
{
VertexOut vout; // Transform to world space space.
vout.PosW = mul(float4(vin.PosL, 1.0f), gWorld).xyz;
vout.NormalW = mul(vin.NormalL, (float3x3)gWorldInvTranspose); // Transform to homogeneous clip space.
vout.PosH = mul(float4(vin.PosL, 1.0f), gWorldViewProj); // Output vertex attributes for interpolation across triangle.
vout.Tex = mul(float4(vin.Tex, 0.0f, 1.0f), gTexTransform).xy;
return vout;
} VertexOut VSONE(VertexIn vin)
{
VertexOut vout; // Transform to world space space.
vout.PosW = vin.PosL;
vout.NormalW = vin.NormalL; // Transform to homogeneous clip space.
vout.PosH = (vin.PosL, 1.0f); // Output vertex attributes for interpolation across triangle.
vout.Tex = vin.Tex;
return vout;
} [maxvertexcount(3)]
void GS(point VertexOut gin[1], inout LineStream<GeoOut> lineStream)
{
GeoOut gout[2];
gout[0].PosH = mul(float4(gin[0].PosW, 1.0f), gWorldViewProj);
gout[0].PosW = mul(float4(gin[0].PosW, 1.0f), gWorld).xyz;
gout[0].NormalW = mul(gin[0].NormalW, (float3x3)gWorldInvTranspose);
gout[0].Tex = mul(float4(gin[0].Tex, 0.0f, 1.0f), gTexTransform).xy;
gout[1].PosW = mul(float4((gin[0].PosW + gin[0].NormalW), 1.0f), gWorld).xyz;
gout[1].NormalW = mul(normalize((gin[0].PosW + gin[0].NormalW)), (float3x3)gWorldInvTranspose);
gout[1].PosH = mul(float4((gin[0].PosW + gin[0].NormalW), 1.0f), gWorldViewProj);
gout[1].Tex = gout[0].Tex; lineStream.Append(gout[1]);
lineStream.Append(gout[0]); } float4 PS(GeoOut pin, uniform int gLightCount, uniform bool gUseTexure, uniform bool gAlphaClip, uniform bool gFogEnabled) : SV_Target
{
// Interpolating normal can unnormalize it, so normalize it.
pin.NormalW = normalize(pin.NormalW); // The toEye vector is used in lighting.
float3 toEye = gEyePosW - pin.PosW; // Cache the distance to the eye from this surface point.
float distToEye = length(toEye); // Normalize.
toEye /= distToEye; // Default to multiplicative identity.
float4 texColor = float4(1, 1, 1, 1);
if(gUseTexure)
{
// Sample texture.
texColor = gDiffuseMap.Sample( samAnisotropic, pin.Tex ); if(gAlphaClip)
{
// Discard pixel if texture alpha < 0.1. Note that we do this
// test as soon as possible so that we can potentially exit the shader
// early, thereby skipping the rest of the shader code.
clip(texColor.a - 0.1f);
}
} //
// Lighting.
// float4 litColor = texColor;
if( gLightCount > 0 )
{
// Start with a sum of zero.
float4 ambient = float4(0.0f, 0.0f, 0.0f, 0.0f);
float4 diffuse = float4(0.0f, 0.0f, 0.0f, 0.0f);
float4 spec = float4(0.0f, 0.0f, 0.0f, 0.0f); // Sum the light contribution from each light source.
[unroll]
for(int i = 0; i < gLightCount; ++i)
{
float4 A, D, S;
ComputeDirectionalLight(gMaterial, gDirLights[i], pin.NormalW, toEye,
A, D, S); ambient += A;
diffuse += D;
spec += S;
} // Modulate with late add.
litColor = texColor*(ambient + diffuse) + spec;
} //
// Fogging
// if( gFogEnabled )
{
float fogLerp = saturate( (distToEye - gFogStart) / gFogRange ); // Blend the fog color and the lit color.
litColor = lerp(litColor, gFogColor, fogLerp);
} // Common to take alpha from diffuse material and texture.
litColor.a = gMaterial.Diffuse.a * texColor.a; return litColor;
} technique11 Light1
{
pass P0
{
SetVertexShader( CompileShader( vs_5_0, VSONE() ) );
SetGeometryShader( CompileShader(gs_5_0, GS()) );
SetPixelShader( CompileShader( ps_5_0, PS(1, false, false, false) ) );
} pass P1
{
SetVertexShader(CompileShader(vs_5_0, VS()));
SetGeometryShader(NULL);
SetPixelShader(CompileShader(ps_5_0, PS(1, false, false, false)));
}
} technique11 Light2
{
pass P0
{
SetVertexShader(CompileShader(vs_5_0, VSONE()));
SetGeometryShader( CompileShader(gs_5_0, GS()) );
SetPixelShader( CompileShader( ps_5_0, PS(2, false, false, false) ) );
} pass P1
{
SetVertexShader(CompileShader(vs_5_0, VS()));
SetGeometryShader(NULL);
SetPixelShader(CompileShader(ps_5_0, PS(2, false, false, false)));
}
} technique11 Light3
{
pass P0
{
SetVertexShader(CompileShader(vs_5_0, VSONE()));
SetGeometryShader( CompileShader(gs_5_0, GS()) );
SetPixelShader( CompileShader( ps_5_0, PS(3, false, false, false) ) );
} pass P1
{
SetVertexShader(CompileShader(vs_5_0, VS()));
SetGeometryShader(NULL);
SetPixelShader(CompileShader(ps_5_0, PS(3, false, false, false)));
}
} technique11 Light0Tex
{
pass P0
{
SetVertexShader(CompileShader(vs_5_0, VSONE()));
SetGeometryShader( CompileShader(gs_5_0, GS()) );
SetPixelShader( CompileShader( ps_5_0, PS(0, true, false, false) ) );
} pass P1
{
SetVertexShader(CompileShader(vs_5_0, VS()));
SetGeometryShader(NULL);
SetPixelShader(CompileShader(ps_5_0, PS(0, true, false, false)));
}
} technique11 Light1Tex
{
pass P0
{
SetVertexShader(CompileShader(vs_5_0, VSONE()));
SetGeometryShader( CompileShader(gs_5_0, GS()) );
SetPixelShader( CompileShader( ps_5_0, PS(1, true, false, false) ) );
} pass P1
{
SetVertexShader(CompileShader(vs_5_0, VS()));
SetGeometryShader(NULL);
SetPixelShader(CompileShader(ps_5_0, PS(1, true, false, false)));
}
} technique11 Light2Tex
{
pass P0
{
SetVertexShader(CompileShader(vs_5_0, VSONE()));
SetGeometryShader( CompileShader(gs_5_0, GS()) );
SetPixelShader( CompileShader( ps_5_0, PS(2, true, false, false) ) );
} pass P1
{
SetVertexShader(CompileShader(vs_5_0, VS()));
SetGeometryShader(NULL);
SetPixelShader(CompileShader(ps_5_0, PS(2, true, false, false)));
}
} technique11 Light3Tex
{
pass P0
{
SetVertexShader(CompileShader(vs_5_0, VSONE()));
SetGeometryShader( CompileShader(gs_5_0, GS()) );
SetPixelShader( CompileShader( ps_5_0, PS(3, true, false, false) ) );
} pass P1
{
SetVertexShader(CompileShader(vs_5_0, VS()));
SetGeometryShader(NULL);
SetPixelShader(CompileShader(ps_5_0, PS(3, true, false, false)));
}
} technique11 Light0TexAlphaClip
{
pass P0
{
SetVertexShader(CompileShader(vs_5_0, VSONE()));
SetGeometryShader( CompileShader(gs_5_0, GS()) );
SetPixelShader( CompileShader( ps_5_0, PS(0, true, true, false) ) );
} pass P1
{
SetVertexShader(CompileShader(vs_5_0, VS()));
SetGeometryShader(NULL);
SetPixelShader(CompileShader(ps_5_0, PS(0, true, true, false)));
}
} technique11 Light1TexAlphaClip
{
pass P0
{
SetVertexShader(CompileShader(vs_5_0, VSONE()));
SetGeometryShader( CompileShader(gs_5_0, GS()) );
SetPixelShader( CompileShader( ps_5_0, PS(1, true, true, false) ) );
} pass P1
{
SetVertexShader(CompileShader(vs_5_0, VS()));
SetGeometryShader(NULL);
SetPixelShader(CompileShader(ps_5_0, PS(1, true, true, false)));
}
} technique11 Light2TexAlphaClip
{
pass P0
{
SetVertexShader(CompileShader(vs_5_0, VSONE()));
SetGeometryShader( CompileShader(gs_5_0, GS()) );
SetPixelShader( CompileShader( ps_5_0, PS(2, true, true, false) ) );
} pass P1
{
SetVertexShader(CompileShader(vs_5_0, VS()));
SetGeometryShader(NULL);
SetPixelShader(CompileShader(ps_5_0, PS(2, true, true, false)));
}
} technique11 Light3TexAlphaClip
{
pass P0
{
SetVertexShader(CompileShader(vs_5_0, VSONE()));
SetGeometryShader( CompileShader(gs_5_0, GS()) );
SetPixelShader( CompileShader( ps_5_0, PS(3, true, true, false) ) );
} pass P1
{
SetVertexShader(CompileShader(vs_5_0, VS()));
SetGeometryShader(NULL);
SetPixelShader(CompileShader(ps_5_0, PS(3, true, true, false)));
}
} technique11 Light1Fog
{
pass P0
{
SetVertexShader(CompileShader(vs_5_0, VSONE()));
SetGeometryShader( CompileShader(gs_5_0, GS()) );
SetPixelShader( CompileShader( ps_5_0, PS(1, false, false, true) ) );
} pass P1
{
SetVertexShader(CompileShader(vs_5_0, VS()));
SetGeometryShader(NULL);
SetPixelShader(CompileShader(ps_5_0, PS(1, false, false, true)));
}
} technique11 Light2Fog
{
pass P0
{
SetVertexShader(CompileShader(vs_5_0, VSONE()));
SetGeometryShader( CompileShader(gs_5_0, GS()) );
SetPixelShader( CompileShader( ps_5_0, PS(2, false, false, true) ) );
} pass P1
{
SetVertexShader(CompileShader(vs_5_0, VS()));
SetGeometryShader(NULL);
SetPixelShader(CompileShader(ps_5_0, PS(2, false, false, true)));
}
} technique11 Light3Fog
{
pass P0
{
SetVertexShader(CompileShader(vs_5_0, VSONE()));
SetGeometryShader( CompileShader(gs_5_0, GS()) );
SetPixelShader( CompileShader( ps_5_0, PS(3, false, false, true) ) );
} pass P1
{
SetVertexShader(CompileShader(vs_5_0, VS()));
SetGeometryShader(NULL);
SetPixelShader(CompileShader(ps_5_0, PS(3, false, false, true)));
}
} technique11 Light0TexFog
{
pass P0
{
SetVertexShader(CompileShader(vs_5_0, VSONE()));
SetGeometryShader( CompileShader(gs_5_0, GS()) );
SetPixelShader( CompileShader( ps_5_0, PS(0, true, false, true) ) );
} pass P1
{
SetVertexShader(CompileShader(vs_5_0, VS()));
SetGeometryShader(NULL);
SetPixelShader(CompileShader(ps_5_0, PS(0, true, false, true)));
}
} technique11 Light1TexFog
{
pass P0
{
SetVertexShader(CompileShader(vs_5_0, VSONE()));
SetGeometryShader( CompileShader(gs_5_0, GS()) );
SetPixelShader( CompileShader( ps_5_0, PS(1, true, false, true) ) );
} pass P1
{
SetVertexShader(CompileShader(vs_5_0, VS()));
SetGeometryShader(NULL);
SetPixelShader(CompileShader(ps_5_0, PS(1, true, false, true)));
}
} technique11 Light2TexFog
{
pass P0
{
SetVertexShader(CompileShader(vs_5_0, VSONE()));
SetGeometryShader( CompileShader(gs_5_0, GS()) );
SetPixelShader( CompileShader( ps_5_0, PS(2, true, false, true) ) );
} pass P1
{
SetVertexShader(CompileShader(vs_5_0, VS()));
SetGeometryShader(NULL);
SetPixelShader(CompileShader(ps_5_0, PS(2, true, false, true)));
}
} technique11 Light3TexFog
{
pass P0
{
SetVertexShader(CompileShader(vs_5_0, VSONE()));
SetGeometryShader( CompileShader(gs_5_0, GS()) );
SetPixelShader( CompileShader( ps_5_0, PS(3, true, false, true) ) );
} pass P1
{
SetVertexShader(CompileShader(vs_5_0, VS()));
SetGeometryShader(NULL);
SetPixelShader(CompileShader(ps_5_0, PS(3, true, false, true)));
}
} technique11 Light0TexAlphaClipFog
{
pass P0
{
SetVertexShader(CompileShader(vs_5_0, VSONE()));
SetGeometryShader( CompileShader(gs_5_0, GS()) );
SetPixelShader( CompileShader( ps_5_0, PS(0, true, true, true) ) );
} pass P1
{
SetVertexShader(CompileShader(vs_5_0, VS()));
SetGeometryShader(NULL);
SetPixelShader(CompileShader(ps_5_0, PS(0, true, true, true)));
}
} technique11 Light1TexAlphaClipFog
{
pass P0
{
SetVertexShader(CompileShader(vs_5_0, VSONE()));
SetGeometryShader( CompileShader(gs_5_0, GS()) );
SetPixelShader( CompileShader( ps_5_0, PS(1, true, true, true) ) );
} pass P1
{
SetVertexShader(CompileShader(vs_5_0, VS()));
SetGeometryShader(NULL);
SetPixelShader(CompileShader(ps_5_0, PS(1, true, true, true)));
}
} technique11 Light2TexAlphaClipFog
{
pass P0
{
SetVertexShader(CompileShader(vs_5_0, VSONE()));
SetGeometryShader( CompileShader(gs_5_0, GS()) );
SetPixelShader( CompileShader( ps_5_0, PS(2, true, true, true) ) );
} pass P1
{
SetVertexShader(CompileShader(vs_5_0, VS()));
SetGeometryShader(NULL);
SetPixelShader(CompileShader(ps_5_0, PS(2, true, true, true)));
}
} technique11 Light3TexAlphaClipFog
{
pass P0
{
SetVertexShader(CompileShader(vs_5_0, VSONE()));
SetGeometryShader( CompileShader(gs_5_0, GS()) );
SetPixelShader( CompileShader( ps_5_0, PS(3, true, true, true) ) );
} pass P1
{
SetVertexShader(CompileShader(vs_5_0, VS()));
SetGeometryShader(NULL);
SetPixelShader(CompileShader(ps_5_0, PS(3, true, true, true)));
}
}
//***************************************************************************************
// BlendDemo.cpp by Frank Luna (C) 2011 All Rights Reserved.
//
// Demonstrates blending, HLSL clip(), and fogging.
//
// Controls:
// Hold the left mouse button down and move the mouse to rotate.
// Hold the right mouse button down to zoom in and out.
//
// Press '1' - Lighting only render mode.
// Press '2' - Texture render mode.
// Press '3' - Fog render mode.
//
//*************************************************************************************** #include "d3dApp.h"
#include "d3dx11Effect.h"
#include "GeometryGenerator.h"
#include "MathHelper.h"
#include "LightHelper.h"
#include "Effects.h"
#include "Vertex.h"
#include "RenderStates.h"
#include "Waves.h" enum RenderOptions
{
Lighting = 0,
Textures = 1,
TexturesAndFog = 2
}; class BlendApp : public D3DApp
{
public:
BlendApp(HINSTANCE hInstance);
~BlendApp(); bool Init();
void OnResize();
void UpdateScene(float dt);
void DrawScene(); void OnMouseDown(WPARAM btnState, int x, int y);
void OnMouseUp(WPARAM btnState, int x, int y);
void OnMouseMove(WPARAM btnState, int x, int y); private:
float GetHillHeight(float x, float z)const;
XMFLOAT3 GetHillNormal(float x, float z)const;
void BuildLandGeometryBuffers();
void BuildWaveGeometryBuffers();
void BuildCrateGeometryBuffers(); private:
ID3D11Buffer* mLandVB;
ID3D11Buffer* mLandIB; ID3D11Buffer* mWavesVB;
ID3D11Buffer* mWavesIB; ID3D11Buffer* mBoxVB;
ID3D11Buffer* mBoxIB; ID3D11ShaderResourceView* mGrassMapSRV;
ID3D11ShaderResourceView* mWavesMapSRV;
ID3D11ShaderResourceView* mBoxMapSRV; Waves mWaves; DirectionalLight mDirLights[3];
Material mLandMat;
Material mWavesMat;
Material mBoxMat; XMFLOAT4X4 mGrassTexTransform;
XMFLOAT4X4 mWaterTexTransform;
XMFLOAT4X4 mLandWorld;
XMFLOAT4X4 mWavesWorld;
XMFLOAT4X4 mBoxWorld; XMFLOAT4X4 mView;
XMFLOAT4X4 mProj; UINT mLandIndexCount; XMFLOAT2 mWaterTexOffset; RenderOptions mRenderOptions; XMFLOAT3 mEyePosW; float mTheta;
float mPhi;
float mRadius; POINT mLastMousePos;
}; int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance,
PSTR cmdLine, int showCmd)
{
// Enable run-time memory check for debug builds.
#if defined(DEBUG) | defined(_DEBUG)
_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
#endif BlendApp theApp(hInstance); if( !theApp.Init() )
return 0; return theApp.Run();
} BlendApp::BlendApp(HINSTANCE hInstance)
: D3DApp(hInstance), mLandVB(0), mLandIB(0), mWavesVB(0), mWavesIB(0), mBoxVB(0), mBoxIB(0), mGrassMapSRV(0), mWavesMapSRV(0), mBoxMapSRV(0),
mWaterTexOffset(0.0f, 0.0f), mEyePosW(0.0f, 0.0f, 0.0f), mLandIndexCount(0), mRenderOptions(RenderOptions::TexturesAndFog),
mTheta(1.3f*MathHelper::Pi), mPhi(0.4f*MathHelper::Pi), mRadius(80.0f)
{
mMainWndCaption = L"Blend Demo";
mEnable4xMsaa = false; mLastMousePos.x = 0;
mLastMousePos.y = 0; XMMATRIX I = XMMatrixIdentity();
XMStoreFloat4x4(&mLandWorld, I);
XMStoreFloat4x4(&mWavesWorld, I);
XMStoreFloat4x4(&mView, I);
XMStoreFloat4x4(&mProj, I); XMMATRIX boxScale = XMMatrixScaling(15.0f, 15.0f, 15.0f);
XMMATRIX boxOffset = XMMatrixTranslation(8.0f, 5.0f, -15.0f);
XMStoreFloat4x4(&mBoxWorld, boxScale*boxOffset); XMMATRIX grassTexScale = XMMatrixScaling(5.0f, 5.0f, 0.0f);
XMStoreFloat4x4(&mGrassTexTransform, grassTexScale); mDirLights[0].Ambient = XMFLOAT4(0.2f, 0.2f, 0.2f, 1.0f);
mDirLights[0].Diffuse = XMFLOAT4(0.5f, 0.5f, 0.5f, 1.0f);
mDirLights[0].Specular = XMFLOAT4(0.5f, 0.5f, 0.5f, 1.0f);
mDirLights[0].Direction = XMFLOAT3(0.57735f, -0.57735f, 0.57735f); mDirLights[1].Ambient = XMFLOAT4(0.0f, 0.0f, 0.0f, 1.0f);
mDirLights[1].Diffuse = XMFLOAT4(0.20f, 0.20f, 0.20f, 1.0f);
mDirLights[1].Specular = XMFLOAT4(0.25f, 0.25f, 0.25f, 1.0f);
mDirLights[1].Direction = XMFLOAT3(-0.57735f, -0.57735f, 0.57735f); mDirLights[2].Ambient = XMFLOAT4(0.0f, 0.0f, 0.0f, 1.0f);
mDirLights[2].Diffuse = XMFLOAT4(0.2f, 0.2f, 0.2f, 1.0f);
mDirLights[2].Specular = XMFLOAT4(0.0f, 0.0f, 0.0f, 1.0f);
mDirLights[2].Direction = XMFLOAT3(0.0f, -0.707f, -0.707f); mLandMat.Ambient = XMFLOAT4(0.5f, 0.5f, 0.5f, 1.0f);
mLandMat.Diffuse = XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f);
mLandMat.Specular = XMFLOAT4(0.2f, 0.2f, 0.2f, 16.0f); mWavesMat.Ambient = XMFLOAT4(0.5f, 0.5f, 0.5f, 1.0f);
mWavesMat.Diffuse = XMFLOAT4(1.0f, 1.0f, 1.0f, 0.5f);
mWavesMat.Specular = XMFLOAT4(0.8f, 0.8f, 0.8f, 32.0f); mBoxMat.Ambient = XMFLOAT4(0.5f, 0.5f, 0.5f, 1.0f);
mBoxMat.Diffuse = XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f);
mBoxMat.Specular = XMFLOAT4(0.4f, 0.4f, 0.4f, 16.0f);
} BlendApp::~BlendApp()
{
md3dImmediateContext->ClearState();
ReleaseCOM(mLandVB);
ReleaseCOM(mLandIB);
ReleaseCOM(mWavesVB);
ReleaseCOM(mWavesIB);
ReleaseCOM(mBoxVB);
ReleaseCOM(mBoxIB);
ReleaseCOM(mGrassMapSRV);
ReleaseCOM(mWavesMapSRV);
ReleaseCOM(mBoxMapSRV); Effects::DestroyAll();
InputLayouts::DestroyAll();
RenderStates::DestroyAll();
} bool BlendApp::Init()
{
if(!D3DApp::Init())
return false; mWaves.Init(160, 160, 1.0f, 0.03f, 5.0f, 0.3f); // Must init Effects first since InputLayouts depend on shader signatures.
Effects::InitAll(md3dDevice);
InputLayouts::InitAll(md3dDevice);
RenderStates::InitAll(md3dDevice); HR(D3DX11CreateShaderResourceViewFromFile(md3dDevice,
L"Textures/grass.dds", 0, 0, &mGrassMapSRV, 0 )); HR(D3DX11CreateShaderResourceViewFromFile(md3dDevice,
L"Textures/water2.dds", 0, 0, &mWavesMapSRV, 0 )); HR(D3DX11CreateShaderResourceViewFromFile(md3dDevice,
L"Textures/WireFence.dds", 0, 0, &mBoxMapSRV, 0 )); BuildLandGeometryBuffers();
BuildWaveGeometryBuffers();
BuildCrateGeometryBuffers(); return true;
} void BlendApp::OnResize()
{
D3DApp::OnResize(); XMMATRIX P = XMMatrixPerspectiveFovLH(0.25f*MathHelper::Pi, AspectRatio(), 1.0f, 1000.0f);
XMStoreFloat4x4(&mProj, P);
} void BlendApp::UpdateScene(float dt)
{
// Convert Spherical to Cartesian coordinates.
float x = mRadius*sinf(mPhi)*cosf(mTheta);
float z = mRadius*sinf(mPhi)*sinf(mTheta);
float y = mRadius*cosf(mPhi); mEyePosW = XMFLOAT3(x, y, z); // Build the view matrix.
XMVECTOR pos = XMVectorSet(x, y, z, 1.0f);
XMVECTOR target = XMVectorZero();
XMVECTOR up = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f); XMMATRIX V = XMMatrixLookAtLH(pos, target, up);
XMStoreFloat4x4(&mView, V); //
// Every quarter second, generate a random wave.
//
static float t_base = 0.0f;
if( (mTimer.TotalTime() - t_base) >= 0.1f )
{
t_base += 0.1f; DWORD i = 5 + rand() % (mWaves.RowCount()-10);
DWORD j = 5 + rand() % (mWaves.ColumnCount()-10); float r = MathHelper::RandF(0.5f, 1.0f); mWaves.Disturb(i, j, r);
} mWaves.Update(dt); //
// Update the wave vertex buffer with the new solution.
// D3D11_MAPPED_SUBRESOURCE mappedData;
HR(md3dImmediateContext->Map(mWavesVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedData)); Vertex::Basic32* v = reinterpret_cast<Vertex::Basic32*>(mappedData.pData);
for(UINT i = 0; i < mWaves.VertexCount(); ++i)
{
v[i].Pos = mWaves[i];
v[i].Normal = mWaves.Normal(i); // Derive tex-coords in [0,1] from position.
v[i].Tex.x = 0.5f + mWaves[i].x / mWaves.Width();
v[i].Tex.y = 0.5f - mWaves[i].z / mWaves.Depth();
} md3dImmediateContext->Unmap(mWavesVB, 0); //
// Animate water texture coordinates.
// // Tile water texture.
XMMATRIX wavesScale = XMMatrixScaling(5.0f, 5.0f, 0.0f); // Translate texture over time.
mWaterTexOffset.y += 0.05f*dt;
mWaterTexOffset.x += 0.1f*dt;
XMMATRIX wavesOffset = XMMatrixTranslation(mWaterTexOffset.x, mWaterTexOffset.y, 0.0f); // Combine scale and translation.
XMStoreFloat4x4(&mWaterTexTransform, wavesScale*wavesOffset); //
// Switch the render mode based in key input.
//
if( GetAsyncKeyState('1') & 0x8000 )
mRenderOptions = RenderOptions::Lighting; if( GetAsyncKeyState('2') & 0x8000 )
mRenderOptions = RenderOptions::Textures; if( GetAsyncKeyState('3') & 0x8000 )
mRenderOptions = RenderOptions::TexturesAndFog;
} void BlendApp::DrawScene()
{
md3dImmediateContext->ClearRenderTargetView(mRenderTargetView, reinterpret_cast<const float*>(&Colors::Silver));
md3dImmediateContext->ClearDepthStencilView(mDepthStencilView, D3D11_CLEAR_DEPTH|D3D11_CLEAR_STENCIL, 1.0f, 0); md3dImmediateContext->IASetInputLayout(InputLayouts::Basic32);
//md3dImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); float blendFactor[] = {0.0f, 0.0f, 0.0f, 0.0f}; UINT stride = sizeof(Vertex::Basic32);
UINT offset = 0; XMMATRIX view = XMLoadFloat4x4(&mView);
XMMATRIX proj = XMLoadFloat4x4(&mProj);
XMMATRIX viewProj = view*proj; // Set per frame constants.
Effects::BasicFX->SetDirLights(mDirLights);
Effects::BasicFX->SetEyePosW(mEyePosW);
Effects::BasicFX->SetFogColor(Colors::Silver);
Effects::BasicFX->SetFogStart(15.0f);
Effects::BasicFX->SetFogRange(175.0f); ID3DX11EffectTechnique* boxTech;
ID3DX11EffectTechnique* landAndWavesTech; switch(mRenderOptions)
{
case RenderOptions::Lighting:
boxTech = Effects::BasicFX->Light3Tech;
landAndWavesTech = Effects::BasicFX->Light3Tech;
break;
case RenderOptions::Textures:
boxTech = Effects::BasicFX->Light3TexAlphaClipTech;
landAndWavesTech = Effects::BasicFX->Light3TexTech;
break;
case RenderOptions::TexturesAndFog:
boxTech = Effects::BasicFX->Light3TexAlphaClipFogTech;
landAndWavesTech = Effects::BasicFX->Light3TexFogTech;
break;
} D3DX11_TECHNIQUE_DESC techDesc; //
// Draw the box with alpha clipping.
// boxTech->GetDesc( &techDesc );
for(UINT p = 0; p < techDesc.Passes; ++p)
{
if (0 == p)
{
md3dImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);
}
else
{
md3dImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
} md3dImmediateContext->IASetVertexBuffers(0, 1, &mBoxVB, &stride, &offset);
md3dImmediateContext->IASetIndexBuffer(mBoxIB, DXGI_FORMAT_R32_UINT, 0); // Set per object constants.
XMMATRIX world = XMLoadFloat4x4(&mBoxWorld);
XMMATRIX worldInvTranspose = MathHelper::InverseTranspose(world);
XMMATRIX worldViewProj = world*view*proj; Effects::BasicFX->SetWorld(world);
Effects::BasicFX->SetWorldInvTranspose(worldInvTranspose);
Effects::BasicFX->SetWorldViewProj(worldViewProj);
Effects::BasicFX->SetTexTransform(XMMatrixIdentity());
Effects::BasicFX->SetMaterial(mBoxMat);
Effects::BasicFX->SetDiffuseMap(mBoxMapSRV); md3dImmediateContext->RSSetState(RenderStates::NoCullRS);
boxTech->GetPassByIndex(p)->Apply(0, md3dImmediateContext);
md3dImmediateContext->DrawIndexed(36, 0, 0); // Restore default render state.
md3dImmediateContext->RSSetState(0);
} //
// Draw the hills and water with texture and fog (no alpha clipping needed).
// landAndWavesTech->GetDesc( &techDesc );
for(UINT p = 0; p < techDesc.Passes; ++p)
{
if (0 == p)
{
md3dImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);
}
else
{
md3dImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
}
//
// Draw the hills.
//
md3dImmediateContext->IASetVertexBuffers(0, 1, &mLandVB, &stride, &offset);
md3dImmediateContext->IASetIndexBuffer(mLandIB, DXGI_FORMAT_R32_UINT, 0); // Set per object constants.
XMMATRIX world = XMLoadFloat4x4(&mLandWorld);
XMMATRIX worldInvTranspose = MathHelper::InverseTranspose(world);
XMMATRIX worldViewProj = world*view*proj; Effects::BasicFX->SetWorld(world);
Effects::BasicFX->SetWorldInvTranspose(worldInvTranspose);
Effects::BasicFX->SetWorldViewProj(worldViewProj);
Effects::BasicFX->SetTexTransform(XMLoadFloat4x4(&mGrassTexTransform));
Effects::BasicFX->SetMaterial(mLandMat);
Effects::BasicFX->SetDiffuseMap(mGrassMapSRV); landAndWavesTech->GetPassByIndex(p)->Apply(0, md3dImmediateContext);
md3dImmediateContext->DrawIndexed(mLandIndexCount, 0, 0); //
// Draw the waves.
//
md3dImmediateContext->IASetVertexBuffers(0, 1, &mWavesVB, &stride, &offset);
md3dImmediateContext->IASetIndexBuffer(mWavesIB, DXGI_FORMAT_R32_UINT, 0); // Set per object constants.
world = XMLoadFloat4x4(&mWavesWorld);
worldInvTranspose = MathHelper::InverseTranspose(world);
worldViewProj = world*view*proj; Effects::BasicFX->SetWorld(world);
Effects::BasicFX->SetWorldInvTranspose(worldInvTranspose);
Effects::BasicFX->SetWorldViewProj(worldViewProj);
Effects::BasicFX->SetTexTransform(XMLoadFloat4x4(&mWaterTexTransform));
Effects::BasicFX->SetMaterial(mWavesMat);
Effects::BasicFX->SetDiffuseMap(mWavesMapSRV); md3dImmediateContext->OMSetBlendState(RenderStates::TransparentBS, blendFactor, 0xffffffff);
landAndWavesTech->GetPassByIndex(p)->Apply(0, md3dImmediateContext);
md3dImmediateContext->DrawIndexed(3*mWaves.TriangleCount(), 0, 0); // Restore default blend state
md3dImmediateContext->OMSetBlendState(0, blendFactor, 0xffffffff);
} HR(mSwapChain->Present(0, 0));
} void BlendApp::OnMouseDown(WPARAM btnState, int x, int y)
{
mLastMousePos.x = x;
mLastMousePos.y = y; SetCapture(mhMainWnd);
} void BlendApp::OnMouseUp(WPARAM btnState, int x, int y)
{
ReleaseCapture();
} void BlendApp::OnMouseMove(WPARAM btnState, int x, int y)
{
if( (btnState & MK_LBUTTON) != 0 )
{
// Make each pixel correspond to a quarter of a degree.
float dx = XMConvertToRadians(0.25f*static_cast<float>(x - mLastMousePos.x));
float dy = XMConvertToRadians(0.25f*static_cast<float>(y - mLastMousePos.y)); // Update angles based on input to orbit camera around box.
mTheta += dx;
mPhi += dy; // Restrict the angle mPhi.
mPhi = MathHelper::Clamp(mPhi, 0.1f, MathHelper::Pi-0.1f);
}
else if( (btnState & MK_RBUTTON) != 0 )
{
// Make each pixel correspond to 0.01 unit in the scene.
float dx = 0.1f*static_cast<float>(x - mLastMousePos.x);
float dy = 0.1f*static_cast<float>(y - mLastMousePos.y); // Update the camera radius based on input.
mRadius += dx - dy; // Restrict the radius.
mRadius = MathHelper::Clamp(mRadius, 20.0f, 500.0f);
} mLastMousePos.x = x;
mLastMousePos.y = y;
} float BlendApp::GetHillHeight(float x, float z)const
{
return 0.3f*( z*sinf(0.1f*x) + x*cosf(0.1f*z) );
} XMFLOAT3 BlendApp::GetHillNormal(float x, float z)const
{
// n = (-df/dx, 1, -df/dz)
XMFLOAT3 n(
-0.03f*z*cosf(0.1f*x) - 0.3f*cosf(0.1f*z),
1.0f,
-0.3f*sinf(0.1f*x) + 0.03f*x*sinf(0.1f*z)); XMVECTOR unitNormal = XMVector3Normalize(XMLoadFloat3(&n));
XMStoreFloat3(&n, unitNormal); return n;
} void BlendApp::BuildLandGeometryBuffers()
{
GeometryGenerator::MeshData grid; GeometryGenerator geoGen; geoGen.CreateGrid(160.0f, 160.0f, 50, 50, grid); mLandIndexCount = grid.Indices.size(); //
// Extract the vertex elements we are interested and apply the height function to
// each vertex.
// std::vector<Vertex::Basic32> vertices(grid.Vertices.size());
for(UINT i = 0; i < grid.Vertices.size(); ++i)
{
XMFLOAT3 p = grid.Vertices[i].Position; p.y = GetHillHeight(p.x, p.z); vertices[i].Pos = p;
vertices[i].Normal = GetHillNormal(p.x, p.z);
vertices[i].Tex = grid.Vertices[i].TexC;
} D3D11_BUFFER_DESC vbd;
vbd.Usage = D3D11_USAGE_IMMUTABLE;
vbd.ByteWidth = sizeof(Vertex::Basic32) * grid.Vertices.size();
vbd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vbd.CPUAccessFlags = 0;
vbd.MiscFlags = 0;
D3D11_SUBRESOURCE_DATA vinitData;
vinitData.pSysMem = &vertices[0];
HR(md3dDevice->CreateBuffer(&vbd, &vinitData, &mLandVB)); //
// Pack the indices of all the meshes into one index buffer.
// D3D11_BUFFER_DESC ibd;
ibd.Usage = D3D11_USAGE_IMMUTABLE;
ibd.ByteWidth = sizeof(UINT) * mLandIndexCount;
ibd.BindFlags = D3D11_BIND_INDEX_BUFFER;
ibd.CPUAccessFlags = 0;
ibd.MiscFlags = 0;
D3D11_SUBRESOURCE_DATA iinitData;
iinitData.pSysMem = &grid.Indices[0];
HR(md3dDevice->CreateBuffer(&ibd, &iinitData, &mLandIB));
} void BlendApp::BuildWaveGeometryBuffers()
{
// Create the vertex buffer. Note that we allocate space only, as
// we will be updating the data every time step of the simulation. D3D11_BUFFER_DESC vbd;
vbd.Usage = D3D11_USAGE_DYNAMIC;
vbd.ByteWidth = sizeof(Vertex::Basic32) * mWaves.VertexCount();
vbd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vbd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
vbd.MiscFlags = 0;
HR(md3dDevice->CreateBuffer(&vbd, 0, &mWavesVB)); // Create the index buffer. The index buffer is fixed, so we only
// need to create and set once. std::vector<UINT> indices(3*mWaves.TriangleCount()); // 3 indices per face // Iterate over each quad.
UINT m = mWaves.RowCount();
UINT n = mWaves.ColumnCount();
int k = 0;
for(UINT i = 0; i < m-1; ++i)
{
for(DWORD j = 0; j < n-1; ++j)
{
indices[k] = i*n+j;
indices[k+1] = i*n+j+1;
indices[k+2] = (i+1)*n+j; indices[k+3] = (i+1)*n+j;
indices[k+4] = i*n+j+1;
indices[k+5] = (i+1)*n+j+1; k += 6; // next quad
}
} D3D11_BUFFER_DESC ibd;
ibd.Usage = D3D11_USAGE_IMMUTABLE;
ibd.ByteWidth = sizeof(UINT) * indices.size();
ibd.BindFlags = D3D11_BIND_INDEX_BUFFER;
ibd.CPUAccessFlags = 0;
ibd.MiscFlags = 0;
D3D11_SUBRESOURCE_DATA iinitData;
iinitData.pSysMem = &indices[0];
HR(md3dDevice->CreateBuffer(&ibd, &iinitData, &mWavesIB));
} void BlendApp::BuildCrateGeometryBuffers()
{
GeometryGenerator::MeshData box; GeometryGenerator geoGen;
geoGen.CreateBox(1.0f, 1.0f, 1.0f, box); //
// Extract the vertex elements we are interested in and pack the
// vertices of all the meshes into one vertex buffer.
// std::vector<Vertex::Basic32> vertices(box.Vertices.size()); for(UINT i = 0; i < box.Vertices.size(); ++i)
{
vertices[i].Pos = box.Vertices[i].Position;
vertices[i].Normal = box.Vertices[i].Normal;
vertices[i].Tex = box.Vertices[i].TexC;
} D3D11_BUFFER_DESC vbd;
vbd.Usage = D3D11_USAGE_IMMUTABLE;
vbd.ByteWidth = sizeof(Vertex::Basic32) * box.Vertices.size();
vbd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vbd.CPUAccessFlags = 0;
vbd.MiscFlags = 0;
D3D11_SUBRESOURCE_DATA vinitData;
vinitData.pSysMem = &vertices[0];
HR(md3dDevice->CreateBuffer(&vbd, &vinitData, &mBoxVB)); //
// Pack the indices of all the meshes into one index buffer.
// D3D11_BUFFER_DESC ibd;
ibd.Usage = D3D11_USAGE_IMMUTABLE;
ibd.ByteWidth = sizeof(UINT) * box.Indices.size();
ibd.BindFlags = D3D11_BIND_INDEX_BUFFER;
ibd.CPUAccessFlags = 0;
ibd.MiscFlags = 0;
D3D11_SUBRESOURCE_DATA iinitData;
iinitData.pSysMem = &box.Indices[0];
HR(md3dDevice->CreateBuffer(&ibd, &iinitData, &mBoxIB));
}

11.6-11.7注意那个DrawIndexed要自己create index buffer,由于是改原有代码,所以也没贴代码,还有要注意的是那个纹理地址越界时開始几个纹理太小了,可能以为全部纹理都一样,事实上不是的,细致看前四个小树,是有差别的

Introdution to 3D Game Programming With DirectX11 第11章 习题解答的更多相关文章

  1. 【鸡渣饲料系列】《Introdution to 3D Game Programming With DirectX11》 代码转移至vs2015

    <Introdution to 3D Game Programming With DirectX11>我是从这本书学习的directx,被称为“龙书”dx11版,由于是通过这本书学习的所以 ...

  2. 《Programming Massively Parallel Processors》Chapter5 习题解答

    自己做的部分习题解答,因为时间关系,有些马虎,也不全面,欢迎探讨或指出错误 5.1 Consider the matrixaddition in Exercise 3.1. Can one use s ...

  3. Civil 3D .NET二次开发第11章代码升级至2018版注意事项

    原来涉及2017的,均需要改为2018 原来的21改为22 代码中AeccXUiLand.AeccApplication.11.0"改为AeccXUiLand.AeccApplication ...

  4. 《Focus On 3D Terrain Programming》中一段代码的注释三

    取自<Focus On 3D Terrain Programming>中的一段: //--------------------------------------------------- ...

  5. 《Focus On 3D Terrain Programming》中一段代码的注释二

    取自<Focus On 3D Terrain Programming>中的一段: bool CTERRAIN::MakeTerrainFault( int iSize, int iIter ...

  6. 《Focus On 3D Terrain Programming》中一段代码的注释一

    取自<Focus On 3D Terrain Programming>中的一段: //--------------------------------------------------- ...

  7. Introduction to 3D Game Programming with DirectX 11 翻译--开篇

    Direct3D 11简介 Direct3D 11是一个渲染库,用于在Windows平台上使用现代图形硬件编写高性能3D图形应用程序.Direct3D是一个windows底层库,因为它的应用程序编程接 ...

  8. Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 全书总结

    原文:Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 全书总结 本系列文章中可能有很多翻译有问题或者错误的地方:并且有些章节 ...

  9. Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- Direct12优化

    原文:Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- Direct12优化 第一章:向量代数 1.向量计算的时候,使用XMV ...

随机推荐

  1. 职责链实现的apache.chain使用

    其实职责链在老早就使用过了,以前在HW给Vodafone做金融项目的时候,使用职责链完成交易步骤,那时觉得这东西真好用,可以直接通过配置决定业务流程,现在终于有机会实践一下.       项目地址:h ...

  2. bzoj1855

    让我们继续练习dp 首先这道题约束条件很多 但实际上方程还是很好写的,f[i,j]表示第i天时拥有j只股票的最大收益 令p=max(0,i-k-1) 上一次较交易 易得f[i,j]=max(f[i-1 ...

  3. bzoj2243:[SDOI2011]染色

    链剖就可以了.一开始的想法错了.但也非常接近了.妈呀调的要死...然后把字体再缩小一号查错起来比较容易QAQ. #include<cstdio> #include<cstring&g ...

  4. 装饰器模式(Decorator)

    转自http://blog.csdn.net/hust_is_lcd/article/details/7884320 1.认识装饰器模式 装饰模式能够实现动态的为对象添加功能,是从一个对象外部来给对象 ...

  5. Live555研究之三 RTSP Server处理请求

    RTSP Server会不断用select查询是否有socket连接,如果有则在(*handler->handlerProc)(handler->clientData, resultCon ...

  6. NOIP2004 合唱队列

    三.合唱队形 (chorus.pas/dpr/c/cpp) [问题描述] N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学排成合唱队形. 合唱队形是指这样的一种队形:设K位 ...

  7. [Orchard CMS系列] 创建主题(Writing a new theme)

    本文需要对Orchard CMS有基本了解. 开启模块 code generation 创建新的主题工程骨架 Codegen theme MyTheme 创建主题样式 src\Orchard.Web\ ...

  8. 检索表中所有列的名称、DB中的用户表

    一.检索某个表中所有列的名称 SELECT name FROM syscolumns WHERE ID = OBJECT_ID('Departments') syscolumns (sys.sysco ...

  9. [转载]C++命名规则

    在软件开发这一高度抽象而且十分复杂的活动中,命名规则的重要性更显得尤为突出.一套定义良好并且完整的.在整个项目中统一使用的命名规范将大大提升源代码的可读性和软件的可维护性. 在引入细节之前,先说明一下 ...

  10. linux 配置静态IP

    ip配置方法是编辑sudo nano  /etc/network/interfaces 树莓派默认配置 auto lo iface lo inet loopback iface eth0 inet d ...