HLSL 和照明问题

发布于 2024-09-01 00:14:35 字数 13781 浏览 8 评论 0原文

我正在尝试弄清楚我的 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

长亭外,古道边 2024-09-08 00:15:03

尝试打开 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.

黎夕旧梦 2024-09-08 00:14:52

有一个应用程序,即 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!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文