纹理不适用于我的 3d Cube directX

Posted

技术标签:

【中文标题】纹理不适用于我的 3d Cube directX【英文标题】:Texture will not apply to my 3d Cube directX 【发布时间】:2010-05-29 20:41:06 【问题描述】:

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

我首先声明了 2 个新变量

ID3D10EffectShaderResourceVariable* pTextureSR;
ID3D10ShaderResourceView* textureSRV;

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

Texture2D tex2D;

SamplerState linearSampler

    Filter = MIN_MAG_MIP_LINEAR;
    AddressU = Wrap;
    AddressV = Wrap;
;

然后,我从 .cpp 文件中的本地硬盘驱动器中抓取了图像。我相信这是成功的,我检查了所有变量是否有错误,一切都有一个内存地址。另外,我之前提取过资源,从来没有遇到过问题。

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

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

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

并将资源添加到变量中

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 还是什么。位置是正确的。我的 crate.jpg 与我的 effect.fx 文件位于同一位置。我以同样的方式加载了我的效果文件。 “效果.fx”

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

【问题讨论】:

好吧,没关系,我在 MSDN 中读到,pHResult 值通常返回 NULL。所以我像这样添加它... pHResult = D3DX10CreateShaderResourceViewFromFile(mpD3DDevice,L"crate.bmp",NULL,NULL,&textureSRV,NULL);它返回为 S_OK。我对这个问题一无所知。 这是一个相当冗长的问题……嗯……更可能是一连串的思路结束于一条废弃的线路。下次减少它以获得一些兴趣。 【参考方案1】:

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

【讨论】:

以上是关于纹理不适用于我的 3d Cube directX的主要内容,如果未能解决你的问题,请参考以下文章

纹理不适用于我在 C++ 和 OpenGL 中的立方体

SpriteKit animateWithTextures 不适用于纹理图集

Opengl Array Texture,适用于原始数据,但不适用于图像数据

Unity3D - 将在 iOS 设备上剪辑纹理的着色器

Unity 3D对象显示有透明度的纹理(图像或视频) ---- 靠谱可用

(转)D3D11游戏编程学习笔记二十一:Cube Mapping及其应用之一:天空盒的实现