纹理不适用于我的3D立方体directX

时间:2010-05-29 20:41:06

标签: c++ c visual-studio visual-studio-2008 directx

我正在尝试将纹理应用到我的3D立方体上,但它没有正确显示。我相信它可能会起作用,因为立方体都是棕色的,几乎与纹理相同。而我最初并没有将立方体变成棕色。这些是我为添加纹理所做的步骤

我首先声明了2个新的varibles

ID3D10EffectShaderResourceVariable* pTextureSR;
ID3D10ShaderResourceView* textureSRV;

我还在我的着色器.fx文件中添加了一个变量和一个结构

Texture2D tex2D;

SamplerState linearSampler
{
    Filter = MIN_MAG_MIP_LINEAR;
    AddressU = Wrap;
    AddressV = Wrap;
};
然后,我从.cpp文件中抓取本地硬盘中的图像。我相信这是成功的,我检查了所有varibles的错误,一切都有一个内存地址。此外,我之前提取资源,从未遇到过问题。

D3DX10CreateShaderResourceViewFromFile(mpD3DDevice,L"crate.jpg",NULL,NULL,&textureSRV,NULL);

我从我的fx文件中抓取了tex2d变量并放入我的资源变量

pTextureSR = modelObject.pEffect->GetVariableByName("tex2D")->AsShaderResource();

并将资源添加到varible

pTextureSR->SetResource(textureSRV);

我还将额外属性添加到我的顶点布局

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 , 24, D3D10_INPUT_PER_VERTEX_DATA, 0},
    {"TEXCOORD",0, DXGI_FORMAT_R32G32_FLOAT, 0 , 36, D3D10_INPUT_PER_VERTEX_DATA, 0}
};

以及我的结构

struct VertexPos
{
    D3DXVECTOR3 pos;
    D3DXVECTOR4 color;
    D3DXVECTOR3 normal;
    D3DXVECTOR2 texCoord;
};

然后我创建了一个新的像素着色器,为其添加纹理。以下是完整的代码

matrix Projection;
matrix WorldMatrix;
Texture2D tex2D;

float3 lightSource;
float4 lightColor = {0.5, 0.5, 0.5, 0.5};

// PS_INPUT - input variables to the pixel shader
// This struct is created and fill in by the 
// vertex shader
struct PS_INPUT
{
    float4 Pos : SV_POSITION;
    float4 Color : COLOR0;
    float4 Normal : NORMAL;
    float2 Tex : TEXCOORD;
};

SamplerState linearSampler
{
    Filter = MIN_MAG_MIP_LINEAR;
    AddressU = Wrap;
    AddressV = Wrap;
};


////////////////////////////////////////////////
// Vertex Shader - Main Function
///////////////////////////////////////////////
PS_INPUT VS(float4 Pos : POSITION, float4 Color : COLOR, float4 Normal : NORMAL, float2 Tex : TEXCOORD)
{
    PS_INPUT psInput;

    // Pass through both the position and the color
    psInput.Pos = mul( Pos, Projection );
    psInput.Normal = Normal;
    psInput.Tex = Tex;

    return psInput;
}

///////////////////////////////////////////////
// Pixel Shader
///////////////////////////////////////////////
float4 PS(PS_INPUT psInput) : SV_Target
{
    float4 finalColor = 0; 
    finalColor = saturate(dot(lightSource, psInput.Normal) * lightColor);

    return finalColor;
}

float4 textured( PS_INPUT psInput ) : SV_Target
{
    return tex2D.Sample( linearSampler, psInput.Tex );
}



// Define the technique
technique10 Render
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, VS() ) );
        SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, textured() ) );
    }
}

以下是我的CPU代码。它可能有点草率。但我只是在任何地方添加代码,因为我只是在试验和玩游戏。您应该在底部的createObject

中找到大部分纹理代码
#include "MyGame.h"
#include "OneColorCube.h"
/* This code sets a projection and shows a turning cube. What has been added is the project, rotation and
a rasterizer to change the rasterization of the cube. The issue that was going on was something with the effect file
which was causing the vertices not to be rendered correctly.*/
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;
ID3D10EffectMatrixVariable* pWorldMatrixVarible = NULL;
ID3D10EffectVectorVariable* pLightVarible = NULL;
ID3D10EffectShaderResourceVariable* pTextureSR;


bool MyGame::InitDirect3D()
{
    if(!DX3dApp::InitDirect3D())
    {
        return false;
    }

    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(0.0f, 10.0f, -20.0f), new D3DXVECTOR3(0.0f, 0.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);


    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 rotationAngleY = 15.0f;
    static float rotationAngleX = 0.0f;

    static D3DXMATRIX rotationXMatrix;
    static D3DXMATRIX rotationYMatrix;

    D3DXMatrixIdentity(&rotationXMatrix);
    D3DXMatrixIdentity(&rotationYMatrix);

    // create the rotation matrix using the rotation angle
    D3DXMatrixRotationY(&rotationYMatrix, rotationAngleY);
    D3DXMatrixRotationX(&rotationXMatrix, rotationAngleX);


    rotationAngleY += (float)D3DX_PI * 0.0008f;
    rotationAngleX += (float)D3DX_PI * 0.0005f;

    WorldMatrix = rotationYMatrix * rotationXMatrix;

    // Set the input layout
    mpD3DDevice->IASetInputLayout(modelObject.pVertexLayout);
    pWorldMatrixVarible->SetMatrix((float*)&WorldMatrix);

    // Set vertex buffer
    UINT stride = sizeof(VertexPos);
    UINT offset = 0;
    mpD3DDevice->IASetVertexBuffers(0, 1, &modelObject.pVertexBuffer, &stride, &offset);

    // Set primitive topology
    mpD3DDevice->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
    //ViewMatrix._43 += 0.005f;

    // 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->Draw(36,0);
    }
}

//Render actually incapsulates Gamedraw, so you can call data before you actually clear the buffer or after you 
//present data
void MyGame::Render()
{
    DX3dApp::Render();
}

bool MyGame::CreateObject()
{

    //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 , 24, D3D10_INPUT_PER_VERTEX_DATA, 0},
        {"TEXCOORD",0, DXGI_FORMAT_R32G32_FLOAT, 0 , 36, D3D10_INPUT_PER_VERTEX_DATA, 0}
    };

    UINT numElements = (sizeof(layout)/sizeof(layout[0]));
    modelObject.numVertices = sizeof(vertices)/sizeof(VertexPos);

    for(int i = 0; i < modelObject.numVertices; i += 3)
    {
        D3DXVECTOR3 out;

        D3DXVECTOR3 v1 = vertices[0 + i].pos;
        D3DXVECTOR3 v2 = vertices[1 + i].pos;
        D3DXVECTOR3 v3 = vertices[2 + i].pos;

        D3DXVECTOR3 u = v2 - v1;
        D3DXVECTOR3 v = v3 - v1;

        D3DXVec3Cross(&out, &u, &v);
        D3DXVec3Normalize(&out, &out);

        vertices[0 + i].normal = out;
        vertices[1 + i].normal = out;
        vertices[2 + i].normal = out;
    }

    //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;

    /*
    //Create indices
    DWORD indices[] =
    {
        0,1,3,
        1,2,3
    };

    ModelObject.numIndices = sizeof(indices)/sizeof(DWORD);

    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();
    pWorldMatrixVarible = modelObject.pEffect->GetVariableByName("WorldMatrix")->AsMatrix();
    pTextureSR = modelObject.pEffect->GetVariableByName("tex2D")->AsShaderResource();

    ID3D10ShaderResourceView* textureSRV;
    D3DX10CreateShaderResourceViewFromFile(mpD3DDevice,L"crate.jpg",NULL,NULL,&textureSRV,NULL);

    pLightVarible = modelObject.pEffect->GetVariableByName("lightSource")->AsVector();
    //Dont sweat the technique. Get it!
    LPCSTR effectTechniqueName = "Render";

    D3DXVECTOR3 vLight(1.0f, 1.0f, 1.0f);
    pLightVarible->SetFloatVector(vLight);

    modelObject.pTechnique = modelObject.pEffect->GetTechniqueByName(effectTechniqueName);
    if(modelObject.pTechnique == NULL)
        return false;

    pTextureSR->SetResource(textureSRV);


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

这是我的立方体坐标。我实际上只在一侧添加了坐标。这是正面的。要仔细检查我在所有方向上翻转立方体只是为了确保我不会意外地将文本放在不正确的一面

//Create vectors and put in vertices

    // Create vertex buffer
    VertexPos vertices[] =
    {
        // BACK SIDES
        { D3DXVECTOR3(-5.0f,  5.0f, 5.0f), D3DXVECTOR4(1.0f,0.0f,0.0f,0.0f), D3DXVECTOR2(0.0,0.0)},
        { D3DXVECTOR3(-5.0f, -5.0f, 5.0f), D3DXVECTOR4(1.0f,0.0f,0.0f,0.0f), D3DXVECTOR2(1.0,0.0)},
        { D3DXVECTOR3(5.0f,  5.0f, 5.0f), D3DXVECTOR4(1.0f,0.0f,0.0f,0.0f),  D3DXVECTOR2(0.0,1.0)},

        { D3DXVECTOR3(5.0f,  5.0f, 5.0f), D3DXVECTOR4(1.0f,0.0f,0.0f,0.0f), D3DXVECTOR2(0.0,0.0)},
        { D3DXVECTOR3(-5.0f, -5.0f, 5.0f), D3DXVECTOR4(1.0f,0.0f,0.0f,0.0f), D3DXVECTOR2(0.0,0.0)},
        { D3DXVECTOR3(5.0f,  -5.0f, 5.0f), D3DXVECTOR4(1.0f,0.0f,0.0f,0.0f), D3DXVECTOR2(0.0,0.0)},

        // 2 FRONT SIDE
        { D3DXVECTOR3(-5.0f,  5.0f, -5.0f), D3DXVECTOR4(0.0f,1.0f,0.0f,0.0f), D3DXVECTOR2(0.0,0.0)},
        { D3DXVECTOR3(5.0f,  5.0f, -5.0f), D3DXVECTOR4(0.0f,1.0f,0.0f,0.0f),  D3DXVECTOR2(2.0,0.0)},
        { D3DXVECTOR3(-5.0f, -5.0f, -5.0f), D3DXVECTOR4(0.0f,1.0f,0.0f,0.0f), D3DXVECTOR2(0.0,2.0)},

        { D3DXVECTOR3(-5.0f, -5.0f, -5.0f), D3DXVECTOR4(0.0f,1.0f,0.0f,0.0f), D3DXVECTOR2(0.0,2.0)},
        { D3DXVECTOR3(5.0f,  5.0f, -5.0f), D3DXVECTOR4(0.0f,1.0f,0.0f,0.0f) , D3DXVECTOR2(2.0,0.0)},
        { D3DXVECTOR3(5.0f,  -5.0f, -5.0f), D3DXVECTOR4(0.0f,1.0f,0.0f,0.0f), D3DXVECTOR2(2.0,2.0)},

        // 3
        { D3DXVECTOR3(-5.0f, 5.0f,  5.0f), D3DXVECTOR4(0.0f,0.0f,1.0f,0.0f), D3DXVECTOR2(0.0,0.0)},
        { D3DXVECTOR3(5.0f, 5.0f,  5.0f),  D3DXVECTOR4(0.0f,0.0f,1.0f,0.0f), D3DXVECTOR2(0.0,0.0)},
        { D3DXVECTOR3(-5.0f, 5.0f, -5.0f), D3DXVECTOR4(0.0f,0.0f,1.0f,0.0f), D3DXVECTOR2(0.0,0.0)},

        { D3DXVECTOR3(-5.0f, 5.0f, -5.0f), D3DXVECTOR4(0.0f,0.0f,1.0f,0.0f), D3DXVECTOR2(0.0,0.0)},
        { D3DXVECTOR3(5.0f, 5.0f, 5.0f), D3DXVECTOR4(0.0f,0.0f,1.0f,0.0f), D3DXVECTOR2(0.0,0.0)},
        { D3DXVECTOR3(5.0f, 5.0f, -5.0f),  D3DXVECTOR4(0.0f,0.0f,1.0f,0.0f), D3DXVECTOR2(0.0,0.0)},

        // 4
        { D3DXVECTOR3(-5.0f, -5.0f,  5.0f), D3DXVECTOR4(1.0f,0.5f,0.0f,0.0f), D3DXVECTOR2(0.0,0.0)},
        { D3DXVECTOR3(-5.0f, -5.0f, -5.0f), D3DXVECTOR4(1.0f,0.5f,0.0f,0.0f), D3DXVECTOR2(0.0,0.0)},
        { D3DXVECTOR3(5.0f, -5.0f,  5.0f),  D3DXVECTOR4(1.0f,0.5f,0.0f,0.0f), D3DXVECTOR2(0.0,0.0)},

        { D3DXVECTOR3(5.0f, -5.0f,  5.0f),  D3DXVECTOR4(1.0f,0.5f,0.0f,0.0f), D3DXVECTOR2(0.0,0.0)},
        { D3DXVECTOR3(-5.0f, -5.0f, -5.0f), D3DXVECTOR4(1.0f,0.5f,0.0f,0.0f), D3DXVECTOR2(0.0,0.0)},
        { D3DXVECTOR3(5.0f, -5.0f, -5.0f),  D3DXVECTOR4(1.0f,0.5f,0.0f,0.0f), D3DXVECTOR2(0.0,0.0)},

        // 5
        { D3DXVECTOR3(5.0f,  5.0f, -5.0f), D3DXVECTOR4(0.0f,1.0f,0.5f,0.0f), D3DXVECTOR2(0.0,0.0)},
        { D3DXVECTOR3(5.0f,  5.0f,  5.0f), D3DXVECTOR4(0.0f,1.0f,0.5f,0.0f), D3DXVECTOR2(0.0,0.0)},
        { D3DXVECTOR3(5.0f, -5.0f, -5.0f), D3DXVECTOR4(0.0f,1.0f,0.5f,0.0f), D3DXVECTOR2(0.0,0.0)},

        { D3DXVECTOR3(5.0f, -5.0f, -5.0f), D3DXVECTOR4(0.0f,1.0f,0.5f,0.0f), D3DXVECTOR2(0.0,0.0)},
        { D3DXVECTOR3(5.0f,  5.0f,  5.0f), D3DXVECTOR4(0.0f,1.0f,0.5f,0.0f), D3DXVECTOR2(0.0,0.0)},
        { D3DXVECTOR3(5.0f, -5.0f,  5.0f), D3DXVECTOR4(0.0f,1.0f,0.5f,0.0f), D3DXVECTOR2(0.0,0.0)},

        // 6
        {D3DXVECTOR3(-5.0f,  5.0f, -5.0f), D3DXVECTOR4(0.5f,0.0f,1.0f,0.0f), D3DXVECTOR2(0.0,0.0)},
        {D3DXVECTOR3(-5.0f, -5.0f, -5.0f), D3DXVECTOR4(0.5f,0.0f,1.0f,0.0f), D3DXVECTOR2(0.0,0.0)},
        {D3DXVECTOR3(-5.0f,  5.0f,  5.0f), D3DXVECTOR4(0.5f,0.0f,1.0f,0.0f), D3DXVECTOR2(0.0,0.0)},

        {D3DXVECTOR3(-5.0f,  5.0f,  5.0f), D3DXVECTOR4(0.5f,0.0f,1.0f,0.0f), D3DXVECTOR2(0.0,0.0)},
        {D3DXVECTOR3(-5.0f, -5.0f, -5.0f), D3DXVECTOR4(0.5f,0.0f,1.0f,0.0f), D3DXVECTOR2(0.0,0.0)},
        {D3DXVECTOR3(-5.0f, -5.0f,  5.0f), D3DXVECTOR4(0.5f,0.0f,1.0f,0.0f), D3DXVECTOR2(0.0,0.0)},
    };

好的,所以我在下面的代码中添加了一个HRESULT

HRESULT *pHResult = NULL;

D3DX10CreateShaderResourceViewFromFile(mpD3DDevice,L"crate.jpg",NULL,NULL,&textureSRV,pHResult);

我检查了结果但没有返回任何内容。 pHResult 0x00000的地址无法评估表达式。不确定它是否因为它没有正确加载crate.jpg或者是什么。位置是正确的。我在与effect.fx文件相同的位置放了crate.jpg。我以同样的方式加载了我的效果文件。 “effect.fx”

如果有人可以查看我的顶点并确保我的UV坐标是正确的。那太好了。我对此持怀疑态度。

1 个答案:

答案 0 :(得分:1)

好吧,我明白了。在我的顶点布局描述中,我的偏移是关闭的。当它应该是16时,我将颜色增加12,因为rgba。无论如何,我纠正了它,现在纹理出现但不正确。我将发布另一个问题。