纹理不适用于我的 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的主要内容,如果未能解决你的问题,请参考以下文章
SpriteKit animateWithTextures 不适用于纹理图集
Opengl Array Texture,适用于原始数据,但不适用于图像数据