HLSL 和照明问题
我正在尝试弄清楚我的 HLSL 代码发生了什么,但我无法调试它,因为 C++ 没有给出任何错误。当我运行该应用程序时,它就会关闭。我正在尝试向我制作的 3D 平面添加照明。下面是我的 HLSL。当我的像素着色器方法返回结构“outColor”时,问题就出现了。如果我将返回值更改回结构“psInput”,一切都会恢复正常。我的光矢量和颜色位于 fx 文件的顶部
// PS_INPUT - input variables to the pixel shader
// This struct is created and fill in by the
// vertex shader
cbuffer Variables
{
matrix Projection;
matrix World;
float TimeStep;
};
struct PS_INPUT
{
float4 Pos : SV_POSITION;
float4 Color : COLOR0;
float3 Normal : TEXCOORD0;
float3 ViewVector : TEXCOORD1;
};
float specpower = 80.0f;
float3 camPos = float3(0.0f, 9.0, -256.0f);
float3 DirectLightColor = float3(1.0f, 1.0f, 1.0f);
float3 DirectLightVector = float3(0.0f, 0.602f, 0.70f);
float3 AmbientLightColor = float3(1.0f, 1.0f, 1.0f);
/***************************************
* Lighting functions
***************************************/
/*********************************
* CalculateAmbient -
* inputs -
* vKa material's reflective color
* lightColor - the ambient color of the lightsource
* output - ambient color
*********************************/
float3 CalculateAmbient(float3 vKa, float3 lightColor)
{
float3 vAmbient = vKa * lightColor;
return vAmbient;
}
/*********************************
* CalculateDiffuse -
* inputs -
* material color
* The color of the direct light
* the local normal
* the vector of the direct light
* output - difuse color
*********************************/
float3 CalculateDiffuse(float3 baseColor, float3 lightColor, float3 normal, float3 lightVector)
{
float3 vDiffuse = baseColor * lightColor * saturate(dot(normal, lightVector));
return vDiffuse;
}
/*********************************
* CalculateSpecular -
* inputs -
* viewVector
* the direct light vector
* the normal
* output - specular highlight
*********************************/
float CalculateSpecular(float3 viewVector, float3 lightVector, float3 normal)
{
float3 vReflect = reflect(lightVector, normal);
float fSpecular = saturate(dot(vReflect, viewVector));
fSpecular = pow(fSpecular, specpower);
return fSpecular;
}
/*********************************
* LightingCombine -
* inputs -
* ambient component
* diffuse component
* specualr component
* output - phong color color
*********************************/
float3 LightingCombine(float3 vAmbient, float3 vDiffuse, float fSpecular)
{
float3 vCombined = vAmbient + vDiffuse + fSpecular.xxx;
return vCombined;
}
////////////////////////////////////////////////
// Vertex Shader - Main Function
///////////////////////////////////////////////
PS_INPUT VS(float4 Pos : POSITION, float4 Color : COLOR, float3 Normal : NORMAL)
{
PS_INPUT psInput;
float4 newPosition;
newPosition = Pos;
newPosition.y = sin((newPosition.x * TimeStep) + (newPosition.z / 3.0f)) * 5.0f;
// Pass through both the position and the color
psInput.Pos = mul(newPosition , Projection );
psInput.Color = Color;
psInput.ViewVector = normalize(camPos - psInput.Pos);
return psInput;
}
///////////////////////////////////////////////
// Pixel Shader
///////////////////////////////////////////////
//Anthony!!!!!!!!!!! Find out how color works when multiplying them
float4 PS(PS_INPUT psInput) : SV_Target
{
float3 normal = -normalize(psInput.Normal);
float3 vAmbient = CalculateAmbient(psInput.Color, AmbientLightColor);
float3 vDiffuse = CalculateDiffuse(psInput.Color, DirectLightColor, normal, DirectLightVector);
float fSpecular = CalculateSpecular(psInput.ViewVector, DirectLightVector, normal);
float4 outColor;
outColor.rgb = LightingCombine(vAmbient, vDiffuse, fSpecular);
outColor.a = 1.0f;
//Below is where the error begins
return outColor;
}
// Define the technique
technique10 Render
{
pass P0
{
SetVertexShader( CompileShader( vs_4_0, VS() ) );
SetGeometryShader( NULL );
SetPixelShader( CompileShader( ps_4_0, PS() ) );
}
}
下面是我的一些 C++ 代码。我之所以展示这一点是因为它几乎是为我的着色器创建表面法线以进行评估的原因。对于照明
modelObject.numIndices = sizeof(indices) / sizeof(DWORD);
// compute normals for each face in the model
for (unsigned int i = 0; i < modelObject.numIndices; i+=3)
{
D3DXVECTOR3 v0 = vertices[indices[i]].pos;
D3DXVECTOR3 v1 = vertices[indices[i + 1]].pos;
D3DXVECTOR3 v2 = vertices[indices[i + 2]].pos;
D3DXVECTOR3 normal;
D3DXVECTOR3 cross;
D3DXVec3Cross(&cross, &D3DXVECTOR3(v2 - v0), &D3DXVECTOR3(v1 - v0));
D3DXVec3Normalize(&normal, &cross);
// assign the computed normal to each vertex in this face
vertices[indices[i]].normal = normal;
vertices[indices[i + 1]].normal = normal;
vertices[indices[i + 2]].normal = normal;
}
,下面是我的完整 C++ 代码。展示图纸并调用通行证
#include "MyGame.h"
typedef struct
{
ID3D10Effect* pEffect;
ID3D10EffectTechnique* pTechnique;
//vertex information
ID3D10Buffer* pVertexBuffer;
ID3D10Buffer* pIndicesBuffer;
ID3D10InputLayout* pVertexLayout;
UINT numVertices;
UINT numIndices;
}ModelObject;
ModelObject modelObject;
// World Matrix
D3DXMATRIX WorldMatrix;
// View Matrix
D3DXMATRIX ViewMatrix;
// Projection Matrix
D3DXMATRIX ProjectionMatrix;
ID3D10EffectMatrixVariable* pProjectionMatrixVariable = NULL;
//grid information
#define NUM_COLS 16
#define NUM_ROWS 16
#define CELL_WIDTH 32
#define CELL_HEIGHT 32
#define NUM_VERTSX (NUM_COLS + 1)
#define NUM_VERTSY (NUM_ROWS + 1)
// timer variables
LARGE_INTEGER timeStart;
LARGE_INTEGER timeEnd;
LARGE_INTEGER timerFreq;
double currentTime;
float anim_rate;
// Variable to hold how long since last frame change
float lastElaspedFrame = 0;
// How long should the frames last
float frameDuration = 0.5;
bool MyGame::InitDirect3D()
{
if(!DX3dApp::InitDirect3D())
{
return false;
}
// Get the timer frequency
QueryPerformanceFrequency(&timerFreq);
float freqSeconds = 1.0f / timerFreq.QuadPart;
lastElaspedFrame = 0;
D3D10_RASTERIZER_DESC rastDesc;
rastDesc.FillMode = D3D10_FILL_WIREFRAME;
rastDesc.CullMode = D3D10_CULL_FRONT;
rastDesc.FrontCounterClockwise = true;
rastDesc.DepthBias = false;
rastDesc.DepthBiasClamp = 0;
rastDesc.SlopeScaledDepthBias = 0;
rastDesc.DepthClipEnable = false;
rastDesc.ScissorEnable = false;
rastDesc.MultisampleEnable = false;
rastDesc.AntialiasedLineEnable = false;
ID3D10RasterizerState *g_pRasterizerState;
mpD3DDevice->CreateRasterizerState(&rastDesc, &g_pRasterizerState);
//mpD3DDevice->RSSetState(g_pRasterizerState);
// Set up the World Matrix
D3DXMatrixIdentity(&WorldMatrix);
D3DXMatrixLookAtLH(&ViewMatrix, new D3DXVECTOR3(200.0f, 60.0f, -20.0f), new D3DXVECTOR3(200.0f, 50.0f, 0.0f), new D3DXVECTOR3(0.0f, 1.0f, 0.0f));
// Set up the projection matrix
D3DXMatrixPerspectiveFovLH(&ProjectionMatrix, (float)D3DX_PI * 0.5f, (float)mWidth/(float)mHeight, 0.1f, 100.0f);
pTimeVariable = NULL;
if(!CreateObject())
{
return false;
}
return true;
}
//These are actions that take place after the clearing of the buffer and before the present
void MyGame::GameDraw()
{
static float rotationAngle = 0.0f;
// create the rotation matrix using the rotation angle
D3DXMatrixRotationY(&WorldMatrix, rotationAngle);
rotationAngle += (float)D3DX_PI * 0.0f;
// Set the input layout
mpD3DDevice->IASetInputLayout(modelObject.pVertexLayout);
// Set vertex buffer
UINT stride = sizeof(VertexPos);
UINT offset = 0;
mpD3DDevice->IASetVertexBuffers(0, 1, &modelObject.pVertexBuffer, &stride, &offset);
mpD3DDevice->IASetIndexBuffer(modelObject.pIndicesBuffer, DXGI_FORMAT_R32_UINT, 0);
pTimeVariable->SetFloat((float)currentTime);
// Set primitive topology
mpD3DDevice->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
// Combine and send the final matrix to the shader
D3DXMATRIX finalMatrix = (WorldMatrix * ViewMatrix * ProjectionMatrix);
pProjectionMatrixVariable->SetMatrix((float*)&finalMatrix);
// make sure modelObject is valid
// Render a model object
D3D10_TECHNIQUE_DESC techniqueDescription;
modelObject.pTechnique->GetDesc(&techniqueDescription);
// Loop through the technique passes
for(UINT p=0; p < techniqueDescription.Passes; ++p)
{
modelObject.pTechnique->GetPassByIndex(p)->Apply(0);
// draw the cube using all 36 vertices and 12 triangles
mpD3DDevice->DrawIndexed(modelObject.numIndices,0,0);
}
}
//Render actually incapsulates Gamedraw, so you can call data before you actually clear the buffer or after you
//present data
void MyGame::Render()
{
// Get the start timer count
QueryPerformanceCounter(&timeStart);
currentTime += anim_rate;
DX3dApp::Render();
QueryPerformanceCounter(&timeEnd);
anim_rate = ( (float)timeEnd.QuadPart - (float)timeStart.QuadPart ) / timerFreq.QuadPart;
}
bool MyGame::CreateObject()
{
VertexPos vertices[NUM_VERTSX * NUM_VERTSY];
for(int z=0; z < NUM_VERTSY; ++z)
{
for(int x = 0; x < NUM_VERTSX; ++x)
{
vertices[x + z * NUM_VERTSX].pos.x = (float)x * CELL_WIDTH;
vertices[x + z * NUM_VERTSX].pos.z = (float)z * CELL_HEIGHT;
vertices[x + z * NUM_VERTSX].pos.y = (float)(rand() % CELL_HEIGHT);
vertices[x + z * NUM_VERTSX].color = D3DXVECTOR4(1.0, 0.0f, 0.0f, 0.0f);
}
}
DWORD indices[NUM_COLS * NUM_ROWS * 6];
int curIndex = 0;
for(int z=0; z < NUM_ROWS; ++z)
{
for(int x = 0; x < NUM_COLS; ++x)
{
int curVertex = x + (z * NUM_VERTSX);
indices[curIndex] = curVertex;
indices[curIndex + 1] = curVertex + NUM_VERTSX;
indices[curIndex + 2] = curVertex + 1;
indices[curIndex + 3] = curVertex + 1;
indices[curIndex + 4] = curVertex + NUM_VERTSX;
indices[curIndex + 5] = curVertex + NUM_VERTSX + 1;
curIndex += 6;
}
}
modelObject.numIndices = sizeof(indices) / sizeof(DWORD);
// compute normals for each face in the model
for (unsigned int i = 0; i < modelObject.numIndices; i+=3)
{
D3DXVECTOR3 v0 = vertices[indices[i]].pos;
D3DXVECTOR3 v1 = vertices[indices[i + 1]].pos;
D3DXVECTOR3 v2 = vertices[indices[i + 2]].pos;
D3DXVECTOR3 normal;
D3DXVECTOR3 cross;
D3DXVec3Cross(&cross, &D3DXVECTOR3(v2 - v0), &D3DXVECTOR3(v1 - v0));
D3DXVec3Normalize(&normal, &cross);
// assign the computed normal to each vertex in this face
vertices[indices[i]].normal = normal;
vertices[indices[i + 1]].normal = normal;
vertices[indices[i + 2]].normal = normal;
}
//Create Layout
D3D10_INPUT_ELEMENT_DESC layout[] = {
{"POSITION",0,DXGI_FORMAT_R32G32B32_FLOAT, 0 , 0, D3D10_INPUT_PER_VERTEX_DATA, 0},
{"COLOR",0,DXGI_FORMAT_R32G32B32A32_FLOAT, 0 , 12, D3D10_INPUT_PER_VERTEX_DATA, 0},
{"NORMAL",0,DXGI_FORMAT_R32G32B32A32_FLOAT, 0 , 28, D3D10_INPUT_PER_VERTEX_DATA, 0}
};
UINT numElements = (sizeof(layout)/sizeof(layout[0]));
modelObject.numVertices = sizeof(vertices)/sizeof(VertexPos);
//Create buffer desc
D3D10_BUFFER_DESC bufferDesc;
bufferDesc.Usage = D3D10_USAGE_DEFAULT;
bufferDesc.ByteWidth = sizeof(VertexPos) * modelObject.numVertices;
bufferDesc.BindFlags = D3D10_BIND_VERTEX_BUFFER;
bufferDesc.CPUAccessFlags = 0;
bufferDesc.MiscFlags = 0;
D3D10_SUBRESOURCE_DATA initData;
initData.pSysMem = vertices;
//Create the buffer
HRESULT hr = mpD3DDevice->CreateBuffer(&bufferDesc, &initData, &modelObject.pVertexBuffer);
if(FAILED(hr))
return false;
bufferDesc.ByteWidth = sizeof(DWORD) * modelObject.numIndices;
bufferDesc.BindFlags = D3D10_BIND_INDEX_BUFFER;
initData.pSysMem = indices;
hr = mpD3DDevice->CreateBuffer(&bufferDesc, &initData, &modelObject.pIndicesBuffer);
if(FAILED(hr))
return false;
/////////////////////////////////////////////////////////////////////////////
//Set up fx files
LPCWSTR effectFilename = L"effect.fx";
modelObject.pEffect = NULL;
hr = D3DX10CreateEffectFromFile(effectFilename,
NULL,
NULL,
"fx_4_0",
D3D10_SHADER_ENABLE_STRICTNESS,
0,
mpD3DDevice,
NULL,
NULL,
&modelObject.pEffect,
NULL,
NULL);
if(FAILED(hr))
return false;
pProjectionMatrixVariable = modelObject.pEffect->GetVariableByName("Projection")->AsMatrix();
pTimeVariable = modelObject.pEffect->GetVariableByName("TimeStep")->AsScalar();
//Dont sweat the technique. Get it!
LPCSTR effectTechniqueName = "Render";
modelObject.pTechnique = modelObject.pEffect->GetTechniqueByName(effectTechniqueName);
if(modelObject.pTechnique == NULL)
return false;
//Create Vertex layout
D3D10_PASS_DESC passDesc;
modelObject.pTechnique->GetPassByIndex(0)->GetDesc(&passDesc);
hr = mpD3DDevice->CreateInputLayout(layout, numElements,
passDesc.pIAInputSignature,
passDesc.IAInputSignatureSize,
&modelObject.pVertexLayout);
if(FAILED(hr))
return false;
return true;
}
I am trying figure out whats going on with my HLSL code but I have no way of debugging it cause C++ gives off no errors. The application just closes when I run it. I am trying to add lighting to a 3d plane I made. below is my HLSL. The problem consist when my Pixel shader method returns the struct "outColor" . If I change the return value back to the struct "psInput" , everything goes back to working again. My light vectors and colors are at the top of the fx file
// PS_INPUT - input variables to the pixel shader
// This struct is created and fill in by the
// vertex shader
cbuffer Variables
{
matrix Projection;
matrix World;
float TimeStep;
};
struct PS_INPUT
{
float4 Pos : SV_POSITION;
float4 Color : COLOR0;
float3 Normal : TEXCOORD0;
float3 ViewVector : TEXCOORD1;
};
float specpower = 80.0f;
float3 camPos = float3(0.0f, 9.0, -256.0f);
float3 DirectLightColor = float3(1.0f, 1.0f, 1.0f);
float3 DirectLightVector = float3(0.0f, 0.602f, 0.70f);
float3 AmbientLightColor = float3(1.0f, 1.0f, 1.0f);
/***************************************
* Lighting functions
***************************************/
/*********************************
* CalculateAmbient -
* inputs -
* vKa material's reflective color
* lightColor - the ambient color of the lightsource
* output - ambient color
*********************************/
float3 CalculateAmbient(float3 vKa, float3 lightColor)
{
float3 vAmbient = vKa * lightColor;
return vAmbient;
}
/*********************************
* CalculateDiffuse -
* inputs -
* material color
* The color of the direct light
* the local normal
* the vector of the direct light
* output - difuse color
*********************************/
float3 CalculateDiffuse(float3 baseColor, float3 lightColor, float3 normal, float3 lightVector)
{
float3 vDiffuse = baseColor * lightColor * saturate(dot(normal, lightVector));
return vDiffuse;
}
/*********************************
* CalculateSpecular -
* inputs -
* viewVector
* the direct light vector
* the normal
* output - specular highlight
*********************************/
float CalculateSpecular(float3 viewVector, float3 lightVector, float3 normal)
{
float3 vReflect = reflect(lightVector, normal);
float fSpecular = saturate(dot(vReflect, viewVector));
fSpecular = pow(fSpecular, specpower);
return fSpecular;
}
/*********************************
* LightingCombine -
* inputs -
* ambient component
* diffuse component
* specualr component
* output - phong color color
*********************************/
float3 LightingCombine(float3 vAmbient, float3 vDiffuse, float fSpecular)
{
float3 vCombined = vAmbient + vDiffuse + fSpecular.xxx;
return vCombined;
}
////////////////////////////////////////////////
// Vertex Shader - Main Function
///////////////////////////////////////////////
PS_INPUT VS(float4 Pos : POSITION, float4 Color : COLOR, float3 Normal : NORMAL)
{
PS_INPUT psInput;
float4 newPosition;
newPosition = Pos;
newPosition.y = sin((newPosition.x * TimeStep) + (newPosition.z / 3.0f)) * 5.0f;
// Pass through both the position and the color
psInput.Pos = mul(newPosition , Projection );
psInput.Color = Color;
psInput.ViewVector = normalize(camPos - psInput.Pos);
return psInput;
}
///////////////////////////////////////////////
// Pixel Shader
///////////////////////////////////////////////
//Anthony!!!!!!!!!!! Find out how color works when multiplying them
float4 PS(PS_INPUT psInput) : SV_Target
{
float3 normal = -normalize(psInput.Normal);
float3 vAmbient = CalculateAmbient(psInput.Color, AmbientLightColor);
float3 vDiffuse = CalculateDiffuse(psInput.Color, DirectLightColor, normal, DirectLightVector);
float fSpecular = CalculateSpecular(psInput.ViewVector, DirectLightVector, normal);
float4 outColor;
outColor.rgb = LightingCombine(vAmbient, vDiffuse, fSpecular);
outColor.a = 1.0f;
//Below is where the error begins
return outColor;
}
// Define the technique
technique10 Render
{
pass P0
{
SetVertexShader( CompileShader( vs_4_0, VS() ) );
SetGeometryShader( NULL );
SetPixelShader( CompileShader( ps_4_0, PS() ) );
}
}
Below is some of my c++ code. Reason I am showing this is because it is pretty much what creates the surface normals for my shaders to evaluate. for the lighting
modelObject.numIndices = sizeof(indices) / sizeof(DWORD);
// compute normals for each face in the model
for (unsigned int i = 0; i < modelObject.numIndices; i+=3)
{
D3DXVECTOR3 v0 = vertices[indices[i]].pos;
D3DXVECTOR3 v1 = vertices[indices[i + 1]].pos;
D3DXVECTOR3 v2 = vertices[indices[i + 2]].pos;
D3DXVECTOR3 normal;
D3DXVECTOR3 cross;
D3DXVec3Cross(&cross, &D3DXVECTOR3(v2 - v0), &D3DXVECTOR3(v1 - v0));
D3DXVec3Normalize(&normal, &cross);
// assign the computed normal to each vertex in this face
vertices[indices[i]].normal = normal;
vertices[indices[i + 1]].normal = normal;
vertices[indices[i + 2]].normal = normal;
}
and below is my c++ code, in it's entirety. showing the drawing and also calling on the passes
#include "MyGame.h"
typedef struct
{
ID3D10Effect* pEffect;
ID3D10EffectTechnique* pTechnique;
//vertex information
ID3D10Buffer* pVertexBuffer;
ID3D10Buffer* pIndicesBuffer;
ID3D10InputLayout* pVertexLayout;
UINT numVertices;
UINT numIndices;
}ModelObject;
ModelObject modelObject;
// World Matrix
D3DXMATRIX WorldMatrix;
// View Matrix
D3DXMATRIX ViewMatrix;
// Projection Matrix
D3DXMATRIX ProjectionMatrix;
ID3D10EffectMatrixVariable* pProjectionMatrixVariable = NULL;
//grid information
#define NUM_COLS 16
#define NUM_ROWS 16
#define CELL_WIDTH 32
#define CELL_HEIGHT 32
#define NUM_VERTSX (NUM_COLS + 1)
#define NUM_VERTSY (NUM_ROWS + 1)
// timer variables
LARGE_INTEGER timeStart;
LARGE_INTEGER timeEnd;
LARGE_INTEGER timerFreq;
double currentTime;
float anim_rate;
// Variable to hold how long since last frame change
float lastElaspedFrame = 0;
// How long should the frames last
float frameDuration = 0.5;
bool MyGame::InitDirect3D()
{
if(!DX3dApp::InitDirect3D())
{
return false;
}
// Get the timer frequency
QueryPerformanceFrequency(&timerFreq);
float freqSeconds = 1.0f / timerFreq.QuadPart;
lastElaspedFrame = 0;
D3D10_RASTERIZER_DESC rastDesc;
rastDesc.FillMode = D3D10_FILL_WIREFRAME;
rastDesc.CullMode = D3D10_CULL_FRONT;
rastDesc.FrontCounterClockwise = true;
rastDesc.DepthBias = false;
rastDesc.DepthBiasClamp = 0;
rastDesc.SlopeScaledDepthBias = 0;
rastDesc.DepthClipEnable = false;
rastDesc.ScissorEnable = false;
rastDesc.MultisampleEnable = false;
rastDesc.AntialiasedLineEnable = false;
ID3D10RasterizerState *g_pRasterizerState;
mpD3DDevice->CreateRasterizerState(&rastDesc, &g_pRasterizerState);
//mpD3DDevice->RSSetState(g_pRasterizerState);
// Set up the World Matrix
D3DXMatrixIdentity(&WorldMatrix);
D3DXMatrixLookAtLH(&ViewMatrix, new D3DXVECTOR3(200.0f, 60.0f, -20.0f), new D3DXVECTOR3(200.0f, 50.0f, 0.0f), new D3DXVECTOR3(0.0f, 1.0f, 0.0f));
// Set up the projection matrix
D3DXMatrixPerspectiveFovLH(&ProjectionMatrix, (float)D3DX_PI * 0.5f, (float)mWidth/(float)mHeight, 0.1f, 100.0f);
pTimeVariable = NULL;
if(!CreateObject())
{
return false;
}
return true;
}
//These are actions that take place after the clearing of the buffer and before the present
void MyGame::GameDraw()
{
static float rotationAngle = 0.0f;
// create the rotation matrix using the rotation angle
D3DXMatrixRotationY(&WorldMatrix, rotationAngle);
rotationAngle += (float)D3DX_PI * 0.0f;
// Set the input layout
mpD3DDevice->IASetInputLayout(modelObject.pVertexLayout);
// Set vertex buffer
UINT stride = sizeof(VertexPos);
UINT offset = 0;
mpD3DDevice->IASetVertexBuffers(0, 1, &modelObject.pVertexBuffer, &stride, &offset);
mpD3DDevice->IASetIndexBuffer(modelObject.pIndicesBuffer, DXGI_FORMAT_R32_UINT, 0);
pTimeVariable->SetFloat((float)currentTime);
// Set primitive topology
mpD3DDevice->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
// Combine and send the final matrix to the shader
D3DXMATRIX finalMatrix = (WorldMatrix * ViewMatrix * ProjectionMatrix);
pProjectionMatrixVariable->SetMatrix((float*)&finalMatrix);
// make sure modelObject is valid
// Render a model object
D3D10_TECHNIQUE_DESC techniqueDescription;
modelObject.pTechnique->GetDesc(&techniqueDescription);
// Loop through the technique passes
for(UINT p=0; p < techniqueDescription.Passes; ++p)
{
modelObject.pTechnique->GetPassByIndex(p)->Apply(0);
// draw the cube using all 36 vertices and 12 triangles
mpD3DDevice->DrawIndexed(modelObject.numIndices,0,0);
}
}
//Render actually incapsulates Gamedraw, so you can call data before you actually clear the buffer or after you
//present data
void MyGame::Render()
{
// Get the start timer count
QueryPerformanceCounter(&timeStart);
currentTime += anim_rate;
DX3dApp::Render();
QueryPerformanceCounter(&timeEnd);
anim_rate = ( (float)timeEnd.QuadPart - (float)timeStart.QuadPart ) / timerFreq.QuadPart;
}
bool MyGame::CreateObject()
{
VertexPos vertices[NUM_VERTSX * NUM_VERTSY];
for(int z=0; z < NUM_VERTSY; ++z)
{
for(int x = 0; x < NUM_VERTSX; ++x)
{
vertices[x + z * NUM_VERTSX].pos.x = (float)x * CELL_WIDTH;
vertices[x + z * NUM_VERTSX].pos.z = (float)z * CELL_HEIGHT;
vertices[x + z * NUM_VERTSX].pos.y = (float)(rand() % CELL_HEIGHT);
vertices[x + z * NUM_VERTSX].color = D3DXVECTOR4(1.0, 0.0f, 0.0f, 0.0f);
}
}
DWORD indices[NUM_COLS * NUM_ROWS * 6];
int curIndex = 0;
for(int z=0; z < NUM_ROWS; ++z)
{
for(int x = 0; x < NUM_COLS; ++x)
{
int curVertex = x + (z * NUM_VERTSX);
indices[curIndex] = curVertex;
indices[curIndex + 1] = curVertex + NUM_VERTSX;
indices[curIndex + 2] = curVertex + 1;
indices[curIndex + 3] = curVertex + 1;
indices[curIndex + 4] = curVertex + NUM_VERTSX;
indices[curIndex + 5] = curVertex + NUM_VERTSX + 1;
curIndex += 6;
}
}
modelObject.numIndices = sizeof(indices) / sizeof(DWORD);
// compute normals for each face in the model
for (unsigned int i = 0; i < modelObject.numIndices; i+=3)
{
D3DXVECTOR3 v0 = vertices[indices[i]].pos;
D3DXVECTOR3 v1 = vertices[indices[i + 1]].pos;
D3DXVECTOR3 v2 = vertices[indices[i + 2]].pos;
D3DXVECTOR3 normal;
D3DXVECTOR3 cross;
D3DXVec3Cross(&cross, &D3DXVECTOR3(v2 - v0), &D3DXVECTOR3(v1 - v0));
D3DXVec3Normalize(&normal, &cross);
// assign the computed normal to each vertex in this face
vertices[indices[i]].normal = normal;
vertices[indices[i + 1]].normal = normal;
vertices[indices[i + 2]].normal = normal;
}
//Create Layout
D3D10_INPUT_ELEMENT_DESC layout[] = {
{"POSITION",0,DXGI_FORMAT_R32G32B32_FLOAT, 0 , 0, D3D10_INPUT_PER_VERTEX_DATA, 0},
{"COLOR",0,DXGI_FORMAT_R32G32B32A32_FLOAT, 0 , 12, D3D10_INPUT_PER_VERTEX_DATA, 0},
{"NORMAL",0,DXGI_FORMAT_R32G32B32A32_FLOAT, 0 , 28, D3D10_INPUT_PER_VERTEX_DATA, 0}
};
UINT numElements = (sizeof(layout)/sizeof(layout[0]));
modelObject.numVertices = sizeof(vertices)/sizeof(VertexPos);
//Create buffer desc
D3D10_BUFFER_DESC bufferDesc;
bufferDesc.Usage = D3D10_USAGE_DEFAULT;
bufferDesc.ByteWidth = sizeof(VertexPos) * modelObject.numVertices;
bufferDesc.BindFlags = D3D10_BIND_VERTEX_BUFFER;
bufferDesc.CPUAccessFlags = 0;
bufferDesc.MiscFlags = 0;
D3D10_SUBRESOURCE_DATA initData;
initData.pSysMem = vertices;
//Create the buffer
HRESULT hr = mpD3DDevice->CreateBuffer(&bufferDesc, &initData, &modelObject.pVertexBuffer);
if(FAILED(hr))
return false;
bufferDesc.ByteWidth = sizeof(DWORD) * modelObject.numIndices;
bufferDesc.BindFlags = D3D10_BIND_INDEX_BUFFER;
initData.pSysMem = indices;
hr = mpD3DDevice->CreateBuffer(&bufferDesc, &initData, &modelObject.pIndicesBuffer);
if(FAILED(hr))
return false;
/////////////////////////////////////////////////////////////////////////////
//Set up fx files
LPCWSTR effectFilename = L"effect.fx";
modelObject.pEffect = NULL;
hr = D3DX10CreateEffectFromFile(effectFilename,
NULL,
NULL,
"fx_4_0",
D3D10_SHADER_ENABLE_STRICTNESS,
0,
mpD3DDevice,
NULL,
NULL,
&modelObject.pEffect,
NULL,
NULL);
if(FAILED(hr))
return false;
pProjectionMatrixVariable = modelObject.pEffect->GetVariableByName("Projection")->AsMatrix();
pTimeVariable = modelObject.pEffect->GetVariableByName("TimeStep")->AsScalar();
//Dont sweat the technique. Get it!
LPCSTR effectTechniqueName = "Render";
modelObject.pTechnique = modelObject.pEffect->GetTechniqueByName(effectTechniqueName);
if(modelObject.pTechnique == NULL)
return false;
//Create Vertex layout
D3D10_PASS_DESC passDesc;
modelObject.pTechnique->GetPassByIndex(0)->GetDesc(&passDesc);
hr = mpD3DDevice->CreateInputLayout(layout, numElements,
passDesc.pIAInputSignature,
passDesc.IAInputSignatureSize,
&modelObject.pVertexLayout);
if(FAILED(hr))
return false;
return true;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
尝试打开 direct3d 调试输出。启动 directx 控制面板,然后转到 Direct3D 10 选项卡。将您的应用程序添加到范围列表中,然后在调试层类别中选中“强制打开”。
您应该发现 D3D 为您提供了更多调试输出。
Try turning up the direct3d debug output. Start the directx control panel then go to the Direct3D 10 tab. Add you application to the scope list then check "Force On" in the debug layer category.
You should find that D3D gives you more debug output.
有一个应用程序,即 DirectX 附带的可执行文件,即 fxc.exe。您可以使用它来消除着色器中的语法错误!
There is an application, an executable file that ships with DirectX, fxc.exe. You can use that to get rid of syntax errors in your shaders!