2010-05-09 4 views
2

Я пытаюсь выяснить, что происходит с моим кодом HLSL, но у меня нет возможности отладки, потому что C++ не дает никаких ошибок. Приложение просто закрывается, когда я запускаю его. Я пытаюсь добавить освещение в 3d-самолет, который я сделал. ниже мой HLSL. Проблема заключается в том, что мой метод пиксельного шейдера возвращает структуру «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())); 
    } 
} 

Ниже некоторые из моих с ++ кода. Причина, по которой я показываю это, - это то, что создает поверхностные нормали для моих шейдеров для оценки. для освещения

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

Это всегда болезненно, когда вы не видите никаких полезных ошибок. Можете ли вы вмешаться в отладчик? Если нет, попробуйте отладить отпечаток? –

ответ

0

Попробуйте включить вывод отладки direct3d. Запустите панель управления directx, затем перейдите на вкладку Direct3D 10. Добавьте приложение в список областей, затем установите флажок «Принудительное включение» в категории уровня отладки.

Вы должны обнаружить, что D3D дает вам больше отладочного вывода.

+0

спасибо, я попробую это – numerical25

+0

Я попробовал. Я больше не получал отладочный вывод. Я даже пытался загрузить debugview, чтобы попытаться их поймать. – numerical25

1

Прилагается приложение, исполняемый файл, который поставляется с DirectX, fxc.exe. Вы можете использовать это, чтобы избавиться от синтаксических ошибок в ваших шейдерах!