2010-05-09 66 views
2

我想弄清楚我的HLSL代码是怎么回事,但我没有办法调试它,导致C++没有发出任何错误。当我运行它时,应用程序会关闭。我正在尝试为我制作的3d平面添加照明。下面是我的HLSL。问题包括当我的Pixel着色器方法返回struct“outColor”。如果我将返回值更改回结构“psInput”,则所有内容都会重新开始工作。我的光矢量和颜色位于fx文件的顶部HLSL和灯光问题

// 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; 
} 
+1

当你没有看到任何有用的错误时,总是很痛苦。你可以加入调试器吗?如果没有,请尝试printf调试? – 2010-05-09 02:23:03

回答

0

尝试调高direct3d调试输出。启动directx控制面板,然后转到Direct3D 10选项卡。将您的应用程序添加到范围列表中,然后在调试层类别中选中“强制”。

你会发现D3D给你更多的调试输出。

+0

谢谢,我会试试看 – numerical25 2010-05-26 21:29:57

+0

我试过了。我没有得到任何更多的调试输出。我甚至试图下载debugview来试图捕获它们。 – numerical25 2010-05-29 18:54:42

1

有一个应用程序,一个随DirectX提供的可执行文件,fxc.exe。您可以使用它来消除着色器中的语法错误!