I've recently started texturing 3d objects in DirectX11 using C++, although I've come across a very strange issue no one seems to no one whats wrong with it. I was hoping I could find some experienced programmers who could shine some light on this issue.
I'm trying to apply a simple texture to a cube
How it should look:
http://img849.imageshack.us/img849/2413/92196367.png
How it looks:
http://img26.imageshack.us/img26/3387/directx11textureglitch.png
As you can see it's kinda fuzzy? I'm not sure how to explain it, but I have no idea why it's happening...
Object.cpp
#include "Object.h"
Object::Object()
{
}
Object::~Object()
{
}
void Object::Render(ID3D11DeviceContext * pImmediateContext)
{
/* VARIABLES */
//Load Constant Buffer Struct
CBUFFER cBuffer;
//Setup HLSL lighting
cBuffer.LightVector = D3DXVECTOR4(1.0f, 1.0f, 1.0f, 0.0f);
cBuffer.LightColor = D3DXCOLOR(0.5f, 0.5f, 0.5f, 1.0f);
cBuffer.AmbientColor = D3DXCOLOR(0.2f, 0.2f, 0.2f, 1.0f);
//simple animation
static float Time = 0.0f;
Time += 0.0001f;
D3DXMatrixRotationY(&matRotate, Time);
/* SETUP MATRIX */
//Create the view matrix
D3DXMatrixLookAtLH(&matView,
&D3DXVECTOR3(0.0f, 3.0f, 5.0f), //Camera position
&D3DXVECTOR3(0.0f, 0.0f, 0.0f), //the look-at position
&D3DXVECTOR3(0.0f, 1.0f, 0.0f) //the up direction
);
//Create the projection matrix
D3DXMatrixPerspectiveFovLH(&matProjection,
(FLOAT)D3DXToRadian(45), //Field of View
(FLOAT)1280 / (FLOAT)720, //aspect ratio
1.0f, //near view-plane
100.0f); //far view-plane
cBuffer.Final = matRotate * matView * matProjection;
cBuffer.Rotation = matRotate;
//Setup the Sampler State
/*
static int i = 0; i++; if(i > 30000) i = 0;
if(i > 10000)
pImmediateContext->PSSetSamplers(0, 1, &g_pSamplerState[0]);
else if (i > 10000 && i < 20000)
pImmediateContext->PSSetSamplers(0, 1, &g_pSamplerState[1]);
else
pImmediateContext->PSSetSamplers(0, 1, &g_pSamplerState[2]);
*/
// select which vertex buffer to display
UINT stride = sizeof(VERTEX);
UINT offset = 0;
pImmediateContext->IASetVertexBuffers(0, 1, &g_pVertexBuffer, &stride, &offset);
pImmediateContext->IASetIndexBuffer(g_pIBuffer, DXGI_FORMAT_R32_UINT, 0);
// select which primtive type we are using
pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
//Load in Shaders
pImmediateContext->VSSetShader( g_pVertexShader, 0, 0 );
pImmediateContext->PSSetShader( g_pPixelShader, 0, 0 );
/* CUBE 1 */
//Create the rotation matrix, spin on the Y axis at 0.001f per frame
//D3DXMatrixRotationY(&matRotate, Time);
//Move the shape
//D3DXMatrixTranslation(&matTranslate, 5.0f, 2.0f, 0.0f);
//Create the final transform
//cBuffer.Final = matRotate * matTranslate * matView * matProjection;
//cBuffer.Rotation = matRotate;
//Draw
pImmediateContext->UpdateSubresource(g_pCBuffer, 0, 0, &cBuffer, 0, 0);
pImmediateContext->PSSetShaderResources(0, 1, &woodTexture); //add texture
pImmediateContext->DrawIndexed(36, 0, 0);
/* CUBE 2 */
/*
//Create the rotation matrix, spin on the Y axis at 0.001f per frame
//D3DXMatrixRotationX(&matRotate, Time);
//Move the shape
D3DXMatrixTranslation(&matTranslate, -5.0f, 2.0f, 0.0f);
//Create the final transform
cBuffer.Final = matRotate * matTranslate * matView * matProjection;
cBuffer.Rotation = matRotate;
//Draw
pImmediateContext->UpdateSubresource(g_pCBuffer, 0, 0, &cBuffer, 0, 0);
pImmediateContext->PSSetShaderResources(0, 1, &brickTexture); //add texture
pImmediateContext->DrawIndexed(36, 0, 0);
*/
}
void Object::InitGraphics(ID3D11Device * device, ID3D11DeviceContext * pImmediateContext)
{
//CUBE
VERTEX OurVertices[] =
{
{-1.0f, -1.0f, 1.0f, D3DXVECTOR3(0.0f, 0.0f, 1.0f), 0.0f, 0.0f}, // side 1
{1.0f, -1.0f, 1.0f, D3DXVECTOR3(0.0f, 0.0f, 1.0f), 0.0f, 1.0f},
{-1.0f, 1.0f, 1.0f, D3DXVECTOR3(0.0f, 0.0f, 1.0f), 1.0f, 0.0f},
{1.0f, 1.0f, 1.0f, D3DXVECTOR3(0.0f, 0.0f, 1.0f), 1.0f, 1.0f},
{-1.0f, -1.0f, -1.0f, D3DXVECTOR3(0.0f, 0.0f, -1.0f), 0.0f, 0.0f}, // side 2
{-1.0f, 1.0f, -1.0f, D3DXVECTOR3(0.0f, 0.0f, -1.0f), 0.0f, 1.0f},
{1.0f, -1.0f, -1.0f, D3DXVECTOR3(0.0f, 0.0f, -1.0f), 1.0f, 0.0f},
{1.0f, 1.0f, -1.0f, D3DXVECTOR3(0.0f, 0.0f, -1.0f), 1.0f, 1.0f},
{-1.0f, 1.0f, -1.0f, D3DXVECTOR3(0.0f, 1.0f, 0.0f), 0.0f, 0.0f}, // side 3
{-1.0f, 1.0f, 1.0f, D3DXVECTOR3(0.0f, 1.0f, 0.0f), 0.0f, 1.0f},
{1.0f, 1.0f, -1.0f, D3DXVECTOR3(0.0f, 1.0f, 0.0f), 1.0f, 0.0f},
{1.0f, 1.0f, 1.0f, D3DXVECTOR3(0.0f, 1.0f, 0.0f), 1.0f, 1.0f},
{-1.0f, -1.0f, -1.0f, D3DXVECTOR3(0.0f, -1.0f, 0.0f), 0.0f, 0.0f}, // side 4
{1.0f, -1.0f, -1.0f, D3DXVECTOR3(0.0f, -1.0f, 0.0f), 0.0f, 1.0f},
{-1.0f, -1.0f, 1.0f, D3DXVECTOR3(0.0f, -1.0f, 0.0f), 1.0f, 0.0f},
{1.0f, -1.0f, 1.0f, D3DXVECTOR3(0.0f, -1.0f, 0.0f), 1.0f, 1.0f},
{1.0f, -1.0f, -1.0f, D3DXVECTOR3(1.0f, 0.0f, 0.0f), 0.0f, 0.0f}, // side 5
{1.0f, 1.0f, -1.0f, D3DXVECTOR3(1.0f, 0.0f, 0.0f), 0.0f, 1.0f},
{1.0f, -1.0f, 1.0f, D3DXVECTOR3(1.0f, 0.0f, 0.0f), 1.0f, 0.0f},
{1.0f, 1.0f, 1.0f, D3DXVECTOR3(1.0f, 0.0f, 0.0f), 1.0f, 1.0f},
{-1.0f, -1.0f, -1.0f, D3DXVECTOR3(-1.0f, 0.0f, 0.0f), 0.0f, 0.0f}, // side 6
{-1.0f, -1.0f, 1.0f, D3DXVECTOR3(-1.0f, 0.0f, 0.0f), 0.0f, 1.0f},
{-1.0f, 1.0f, -1.0f, D3DXVECTOR3(-1.0f, 0.0f, 0.0f), 1.0f, 0.0f},
{-1.0f, 1.0f, 1.0f, D3DXVECTOR3(-1.0f, 0.0f, 0.0f), 1.0f, 1.0f},
};
// create the vertex buffer
D3D11_BUFFER_DESC bd;
ZeroMemory(&bd, sizeof(bd));
bd.Usage = D3D11_USAGE_DYNAMIC; // write access access by CPU and GPU
bd.ByteWidth = sizeof(VERTEX) * 24; // size is the VERTEX struct
bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; // use as a vertex buffer
bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; // allow CPU to write in buffer
device->CreateBuffer(&bd, NULL, &g_pVertexBuffer); // create the buffer
// copy the vertices into the buffer
D3D11_MAPPED_SUBRESOURCE ms;
pImmediateContext->Map(g_pVertexBuffer, NULL, D3D11_MAP_WRITE_DISCARD, NULL, &ms); // map the buffer
memcpy(ms.pData, OurVertices, sizeof(OurVertices)); // copy the data
pImmediateContext->Unmap(g_pVertexBuffer, NULL); // unmap the buffer
//Create the index buffer out of DWORD
DWORD OurIndices[] =
{
0, 1, 2, // side 1
2, 1, 3,
4, 5, 6, // side 2
6, 5, 7,
8, 9, 10, // side 3
10, 9, 11,
12, 13, 14, // side 4
14, 13, 15,
16, 17, 18, // side 5
18, 17, 19,
20, 21, 22, // side 6
22, 21, 23,
};
// create the index buffer
bd.Usage = D3D11_USAGE_DYNAMIC;
bd.ByteWidth = sizeof(DWORD) * 36;
bd.BindFlags = D3D11_BIND_INDEX_BUFFER;
bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
bd.MiscFlags = 0;
device->CreateBuffer(&bd, NULL, &g_pIBuffer);
pImmediateContext->Map(g_pIBuffer, NULL, D3D11_MAP_WRITE_DISCARD, NULL, &ms); // map the buffer
memcpy(ms.pData, OurIndices, sizeof(OurIndices)); // copy the data
pImmediateContext->Unmap(g_pIBuffer, NULL);
//Load wood texture
D3DX11CreateShaderResourceViewFromFile(device, //Direct3D Device
L"Wood.png", //Load wood.png
NULL, //no additional information
NULL, //no multithreading
&woodTexture, //Address of the shader-resource-view
NULL); //no multithreading
//Load brick texture
D3DX11CreateShaderResourceViewFromFile(device, //Direct3D Device
L"Bricks.png", //Load bricks.png
NULL, //no additional information
NULL, //no multithreading
&brickTexture, //Address of the shader-resource-view
NULL); //no multithreading
}
HRESULT Object::InitObject(ID3D11Device * device, ID3D11DeviceContext * pImmediateContext)
{
HRESULT hr = S_OK;
//------------------
// VERTEX SHADER
//------------------
// Compile the vertex shader
ID3D10Blob* pVSBlob = NULL;
hr = D3DX11CompileFromFile(L"Shader.fx", 0, 0, "VShader", "vs_5_0", 0, 0, 0, &pVSBlob, 0, 0);
//Error Handling
if( FAILED( hr ) )
{
MessageBox( NULL,
L"The FX file cannot be compiled. Please run this executable from the directory that contains the FX file.", L"Error", MB_OK );
return hr;
}
// Create the vertex shader
hr = device->CreateVertexShader( pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), NULL, &g_pVertexShader );
if( FAILED( hr ) )
{
pVSBlob->Release();
return hr;
}
//------------------
// PIXEL SHADER
//------------------
// Compile the pixel shader
ID3D10Blob* pPSBlob = NULL;
D3DX11CompileFromFile(L"Shader.fx", 0, 0, "PShader", "ps_5_0", 0, 0, 0, &pPSBlob, 0, 0);
//Error handling
if( FAILED( hr ) )
{
MessageBox( NULL,
L"The FX file cannot be compiled. Please run this executable from the directory that contains the FX file.", L"Error", MB_OK );
return hr;
}
// Create the pixel shader
hr = device->CreatePixelShader( pPSBlob->GetBufferPointer(), pPSBlob->GetBufferSize(), NULL, &g_pPixelShader );
pPSBlob->Release();
if( FAILED( hr ) )
return hr;
//------------------
// LOAD SHADERS
//------------------
//Allows the Shader to return a struct of values
D3D11_INPUT_ELEMENT_DESC layout[] =
{
{"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, //Allows Pixel shader to take in positions
{"NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0}, //Allows Pixel shader to take in normals
{"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0}, //Allows pixel shader to take in textures
};
UINT numElements = ARRAYSIZE( layout ); //Count number of elements in array
// Create the input layout
hr = device->CreateInputLayout( layout, numElements, pVSBlob->GetBufferPointer(),
pVSBlob->GetBufferSize(), &g_pVertexLayout );
pVSBlob->Release();
if( FAILED( hr ) )
return hr;
// Set the input layout
pImmediateContext->IASetInputLayout( g_pVertexLayout );
//------------------
// CONSTANT BUFFER
//------------------
D3D11_BUFFER_DESC bd;
ZeroMemory( &bd, sizeof(bd) );
bd.Usage = D3D11_USAGE_DEFAULT;
bd.ByteWidth = 176;
bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
//Create Constant Buffer
device->CreateBuffer(&bd, NULL, &g_pCBuffer);
//Setup Constant Buffer
pImmediateContext->VSSetConstantBuffers(0, 1, &g_pCBuffer);
return hr;
}
void Object::InitStates(ID3D11Device * device)
{
//Rasiterzer
D3D11_RASTERIZER_DESC rd;
rd.FillMode = D3D11_FILL_SOLID;
rd.CullMode = D3D11_CULL_BACK;
rd.FrontCounterClockwise = FALSE;
rd.DepthClipEnable = TRUE;
rd.ScissorEnable = FALSE;
rd.AntialiasedLineEnable = FALSE;
rd.MultisampleEnable = FALSE;
rd.DepthBias = 0;
rd.DepthBiasClamp = 0.0f;
rd.SlopeScaledDepthBias = 0.0f;
device->CreateRasterizerState(&rd, &g_pRSDefault);
//Sampler
D3D11_SAMPLER_DESC sd;
sd.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
sd.MaxAnisotropy = 16;
sd.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
sd.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
sd.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
sd.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
sd.BorderColor[0] = 0.0f;
sd.BorderColor[1] = 0.0f;
sd.BorderColor[2] = 0.0f;
sd.BorderColor[3] = 0.0f;
sd.MinLOD = 0.0f;
sd.MaxLOD = D3D11_FLOAT32_MAX;
sd.MipLODBias = 0.0f;
device->CreateSamplerState(&sd, &g_pSamplerState[0]);
sd.Filter = D3D11_FILTER_ANISOTROPIC;
device->CreateSamplerState(&sd, &g_pSamplerState[1]);
sd.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
sd.MinLOD = 5.0f;
device->CreateSamplerState(&sd, &g_pSamplerState[2]);
}
void Object::CleanupObject()
{
//Close and release all existing COM Objects
if( g_pVertexBuffer ) g_pVertexBuffer->Release();
if( g_pVertexLayout ) g_pVertexLayout->Release();
if( g_pVertexShader ) g_pVertexShader->Release();
if( g_pPixelShader ) g_pPixelShader->Release();
if( g_pCBuffer ) g_pCBuffer->Release();
if( g_pIBuffer ) g_pIBuffer->Release();
if( woodTexture ) woodTexture->Release();
if( brickTexture ) brickTexture->Release();
}
shader.fx
//Created by Tim Lawton 2012
//--------------------------------------------------------------------------------------
// Vertex Shader
//--------------------------------------------------------------------------------------
//Constant Buffer
cbuffer ConstantBuffer
{
float4x4 final; //4x4 matrix which holds the final value
float4x4 rotation; //rotation matrix
float4 lightvec; //Light's Vector
float4 lightcol; //light's colour
float4 ambientcol; //Ambient light's colour
}
Texture2D Texture;
SamplerState ss;
//Struct to return two values
struct VOut
{
float4 color : COLOR;
float2 texcoord : TEXCOORD;
float4 position : SV_POSITION;
};
VOut VShader(float4 position : POSITION, float4 normal : NORMAL, float2 texcoord : TEXCOORD)
{
VOut output;
output.position = mul(final, position);
// set the ambient light
output.color = ambientcol;
// calculate the diffuse light and add it to the ambient light
float4 norm = normalize(mul(rotation, normal));
float diffusebrightness = saturate(dot(norm, lightvec));
output.color += lightcol * diffusebrightness;
//Set texture coordinates
output.texcoord = texcoord;
return output;
}
//--------------------------------------------------------------------------------------
// Pixel Shader
//--------------------------------------------------------------------------------------
float4 PShader(float4 color : COLOR, float2 texcoord : TEXCOORD) : SV_TARGET
{
return color * Texture.Sample(ss, texcoord);
}
Any help would be greatly appreciated