i have tried to write a class that handles my sprites but i can´t make it work and i ´m not sure why...
i will give you my code:
the class header:
#include <D3D11.h>
#include <D3DX11.h>
#include <xnamath.h>
#include <d3dcompiler.h>
#include "Globals.h"
#ifndef _GameSprite_H
#define _GameSprite_H
struct MySpriteVertex
{
XMFLOAT3 pos;
XMFLOAT2 tex0;
};
class GameSprite
{
public:
GameSprite(char* texturePath, char* shaderPath, float startX, float startY, float sizeX, float sizeY);
~GameSprite();
void Initialize();
void SetUpVertices();
void DetermineValues();
bool LoadTexture();
bool CreateBuffers();
bool ActivateAlphaBlending();
void SetView(XMMATRIX &View);
void CalculateWorld();
void SetProj(XMMATRIX &Proj);
void SetPosition(float X, float Y);
void SetRotation(float rotation);
void SetScale(float X, float Y);
void Update();
void DrawSprite();
MySpriteVertex spriteVertices[6];
float startX;
float startY;
float sizeX;
float sizeY;
float scaleX;
float scaleY;
float rotation;
float spriteWidth;
float spriteHeight;
char* texturePath;
char* shaderPath;
ID3D11Buffer* spriteVertexBuffer;
ID3D11ShaderResourceView* spriteMap;
ID3D11SamplerState* spriteSampler;
ID3D11InputLayout* spriteInputLayout;
ID3DBlob* spriteErrorBuffer;
ID3DBlob* spriteVSBuffer;
ID3DBlob* spritePSBuffer;
ID3D11VertexShader* spriteVertexShader;
ID3D11PixelShader* spritePixelShader;
ID3D11Buffer* mwvpCB;
XMMATRIX* spriteView;
XMMATRIX* spriteProj;
XMMATRIX* spriteWorld;
ID3D11BlendState *originalBS;
float originalBlendColor[4];
UINT originalSampleMask;
ID3D11BlendState *newBS;
bool ResetOriginalBlendState();
};
#endif
the .cpp file:
#include "GameSprite.h"
GameSprite::GameSprite(char* texturePath, char* shaderPath, float startX, float startY, float sizeX, float sizeY)
{
this->texturePath = texturePath;
this->shaderPath = shaderPath;
this->startX = startX;
this->startY = startY;
this->sizeX = sizeX;
this->sizeY = sizeY;
this->rotation = 0;
this->scaleX = 1.0f;
this->scaleY = 1.0f;
this->spriteWorld = &XMMatrixIdentity();
this->spriteView = &XMMatrixIdentity();
this->spriteProj = &XMMatrixIdentity();
Initialize();
}
GameSprite::~GameSprite()
{
}
void GameSprite::Initialize()
{
LoadTexture();
DetermineValues();
SetUpVertices();
CreateBuffers();
}
void GameSprite::SetUpVertices()
{
/*
vertices[0].pos = XMFLOAT3(spriteWidth/2, spriteHeight/2, 1.0f);
vertices[0].tex0 = XMFLOAT2( 1.0f, 1.0f);
vertices[1].pos = XMFLOAT3(spriteWidth/2, -spriteHeight/2, 1.0f);
vertices[1].tex0 = XMFLOAT2( 1.0f, 0.0f);
vertices[2].pos = XMFLOAT3(-spriteWidth/2, -spriteHeight/2, 1.0f);
vertices[2].tex0 = XMFLOAT2( 0.0f, 0.0f);
vertices[3].pos = XMFLOAT3(-spriteWidth/2, -spriteHeight/2, 1.0f);
vertices[3].tex0 = XMFLOAT2( 0.0f, 0.0f);
vertices[4].pos = XMFLOAT3(-spriteWidth/2, spriteHeight/2, 1.0f);
vertices[4].tex0 = XMFLOAT2( 0.0f, 1.0f);
vertices[5].pos = XMFLOAT3(spriteWidth/2, spriteHeight/2, 1.0f);
vertices[5].tex0 = XMFLOAT2(1.0f, 1.0f);
*/
vertices[0].pos = XMFLOAT3(1.0f, 1.0f, 1.0f);
vertices[0].tex0 = XMFLOAT2( 1.0f, 1.0f);
vertices[1].pos = XMFLOAT3(1.0f, -1.0f, 1.0f);
vertices[1].tex0 = XMFLOAT2( 1.0f, 0.0f);
vertices[2].pos = XMFLOAT3(-1.0f, -1.0f, 1.0f);
vertices[2].tex0 = XMFLOAT2( 0.0f, 0.0f);
vertices[3].pos = XMFLOAT3(-1.0f, -1.0f, 1.0f);
vertices[3].tex0 = XMFLOAT2( 0.0f, 0.0f);
vertices[4].pos = XMFLOAT3(-1.0f, 1.0f, 1.0f);
vertices[4].tex0 = XMFLOAT2( 0.0f, 1.0f);
vertices[5].pos = XMFLOAT3(1.0f, 1.0f, 1.0f);
vertices[5].tex0 = XMFLOAT2(1.0f, 1.0f);
}
void GameSprite::DetermineValues()
{
float spriteWidth = sizeX;
float spriteHeight = sizeY;
SetPosition(startX, startY);
SetRotation(0.0f);
}
bool GameSprite::LoadTexture()
{
HRESULT result = D3DX11CreateShaderResourceViewFromFileA(Device, texturePath, 0, 0, &spriteMap, 0);
if(FAILED(result))
{
MessageBoxA(NULL, "Failed to load the texture image!", "Error", MB_OK);
return false;
}
D3D11_SAMPLER_DESC colorMapDesc;
ZeroMemory( &colorMapDesc, sizeof(colorMapDesc));
colorMapDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
colorMapDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
colorMapDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
colorMapDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
colorMapDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
colorMapDesc.MaxLOD = D3D11_FLOAT32_MAX;
result = Device->CreateSamplerState(&colorMapDesc, &spriteSampler);
if(FAILED(result))
{
MessageBoxA(NULL, "Failed to create color map sampler state!", "Error", MB_OK);
return false;
}
return false;
}
bool GameSprite::CreateBuffers()
{
D3D11_BUFFER_DESC vertexDesc;
ZeroMemory(&vertexDesc, sizeof(vertexDesc));
vertexDesc.Usage = D3D11_USAGE_DEFAULT;
vertexDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vertexDesc.ByteWidth = sizeof(MySpriteVertex) * ARRAYSIZE(spriteVertices);
D3D11_SUBRESOURCE_DATA resourceData;
ZeroMemory( &resourceData, sizeof(resourceData));
resourceData.pSysMem = spriteVertices;
HRESULT hresult = Device->CreateBuffer(&vertexDesc, &resourceData, &spriteVertexBuffer);
if(FAILED(hresult))
{
MessageBoxA(NULL, "Failed to create vertex buffer!", "Error", MB_OK);
return true;
}
D3D11_BUFFER_DESC constDesc;
ZeroMemory( &constDesc, sizeof(constDesc));
constDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
constDesc.ByteWidth = sizeof(XMMATRIX);
constDesc.Usage = D3D11_USAGE_DEFAULT;
hresult = Device->CreateBuffer(&constDesc, 0, &mwvpCB);
if( FAILED(hresult))
{
MessageBoxA(NULL, "Failed to create Constant Buffer", "Error", MB_OK);
return false;
}
spriteErrorBuffer = 0;
hresult = D3DX11CompileFromFileA(shaderPath, 0, 0, "VS_Main", "vs_4_0", D3DCOMPILE_ENABLE_STRICTNESS, 0, 0, &spriteVSBuffer, &spriteErrorBuffer, 0);
if(FAILED(hresult))
{
MessageBoxA(NULL, "Error Loading Vertex Shader", "Error", MB_OK);
}
hresult = Device->CreateVertexShader(spriteVSBuffer->GetBufferPointer(), spriteVSBuffer->GetBufferSize(), 0, &spriteVertexShader);
if(FAILED(hresult))
{
MessageBoxA(NULL, "Error Creating Vertex Shader", "Error", MB_OK);
}
D3D11_INPUT_ELEMENT_DESC vertexLayout[] =
{
{"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
{"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0}
};
hresult = Device->CreateInputLayout(vertexLayout, ARRAYSIZE(vertexLayout), spriteVSBuffer->GetBufferPointer(), spriteVSBuffer->GetBufferSize(), &spriteInputLayout);
if(FAILED(hresult))
{
MessageBoxA(NULL, "Error Creating Input Layout", "Error", MB_OK);
}
hresult = D3DX11CompileFromFileA(shaderPath, 0, 0, "PS_Main", "ps_4_0", D3DCOMPILE_ENABLE_STRICTNESS, 0, 0, &spritePSBuffer, &spriteErrorBuffer, 0);
if(FAILED(hresult))
{
MessageBoxA(NULL, "Error Loading Pixel Shader", "Error", MB_OK);
}
hresult = Device->CreatePixelShader(spritePSBuffer->GetBufferPointer(), spritePSBuffer->GetBufferSize(), 0, &spritePixelShader);
if(FAILED(hresult))
{
MessageBoxA(NULL, "Error Creating Pixel Shader", "Error", MB_OK);
}
return true;
}
void GameSprite::SetView(XMMATRIX &View)
{
this->spriteView = &View;
}
void GameSprite::SetProj(XMMATRIX &Proj)
{
this->spriteProj = &Proj;
}
void GameSprite::CalculateWorld()
{
XMMATRIX translation = XMMatrixTranslation(startX, startY, 0.0f);
XMMATRIX rotationZ = XMMatrixRotationZ(rotation);
XMMATRIX scaleMatrix = XMMatrixScaling(scaleX, scaleY, 1.0f);
*spriteWorld = translation * rotationZ * scaleMatrix;
}
bool GameSprite::ActivateAlphaBlending()
{
originalBlendColor[0] = 0;
originalBlendColor[1] = 0;
originalBlendColor[2] = 0;
originalBlendColor[3] = 0;
originalSampleMask = 0;
originalBS = NULL;
d3dContext->OMGetBlendState(&originalBS, originalBlendColor, &originalSampleMask);
D3D11_BLEND_DESC blendStateDesc;
ZeroMemory(&blendStateDesc, sizeof(D3D11_BLEND_DESC));
blendStateDesc.AlphaToCoverageEnable = FALSE;
blendStateDesc.IndependentBlendEnable = FALSE;
blendStateDesc.RenderTarget[0].BlendEnable = TRUE;
blendStateDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
blendStateDesc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
blendStateDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
blendStateDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ZERO;
blendStateDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
blendStateDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
blendStateDesc.RenderTarget[0].RenderTargetWriteMask = 0x0F;
if(FAILED(Device->CreateBlendState(&blendStateDesc, &newBS)))
{
MessageBoxA(NULL, "Error Could not Adjust Blend State", "Error", MB_OK);
return false;
}
d3dContext->OMSetBlendState(newBS, NULL, 0xFFFFFF);
return true;
}
bool GameSprite::ResetOriginalBlendState()
{
d3dContext->OMSetBlendState(originalBS, originalBlendColor, originalSampleMask);
return true;
}
void GameSprite::SetPosition(float X, float Y)
{
this->startX = X;
this->startY = Y;
}
void GameSprite::SetRotation(float rotation)
{
this->rotation = rotation;
}
void GameSprite::SetScale(float X, float Y)
{
this->scaleX = X;
this->scaleY = Y;
}
void GameSprite::Update()
{
CalculateWorld();
}
void GameSprite::DrawSprite()
{
ActivateAlphaBlending();
unsigned int stride = sizeof(MySpriteVertex);
unsigned int offset = 0;
d3dContext->IASetInputLayout(spriteInputLayout);
d3dContext->IASetVertexBuffers(0, 1, &spriteVertexBuffer, &stride, &offset);
d3dContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
XMMATRIX mwvp = XMMatrixMultiply(*spriteView, *spriteProj);
mwvp = XMMatrixMultiply(mwvp, *spriteWorld);
mwvp = XMMatrixTranspose(mwvp);
d3dContext->UpdateSubresource(mwvpCB, 0, 0, &mwvp, 0, 0);
d3dContext->VSSetConstantBuffers(0, 1, &mwvpCB);
d3dContext->PSSetShaderResources( 0, 1, &spriteMap);
d3dContext->PSSetSamplers(0, 1, &spriteSampler);
d3dContext->VSSetShader(spriteVertexShader, 0, 0);
d3dContext->PSSetShader(spritePixelShader, 0, 0);
d3dContext->Draw(ARRAYSIZE(spriteVertices), 0);
ResetOriginalBlendState();
}
and here is the shader i use:
Texture2D
colorMap : register(t0);
SamplerState
colorSampler : register(s0);
cbuffer
cbChangesEveryFrame : register( b0 )
{
matrix mwvp;
};
struct
VS_Input
{
float4 pos : POSITION;
float2 tex0 : TEXCOORD0;
};
struct
PS_Input
{
float4 pos : SV_POSITION;
float2 tex0 : TEXCOORD0;
};
PS_Input VS_Main(VS_Input vertex)
{
vertex.pos.w = 1.0f;
PS_Input vsOut = (PS_Input)0;
vsOut.pos = mul(vertex.pos, mwvp);
vsOut.tex0 = vertex.tex0;
return vsOut;
}
float4
PS_Main(PS_Input frag) : SV_TARGET
{
float4 color = colorMap.Sample(colorSampler, frag.tex0);
return color;
}
this is how i set the projection and the view, in my main routines initialisation:
View = XMMatrixIdentity();
Projection = XMMatrixOrthographicOffCenterLH(0.0f, width, 0.0f, height, 0.1f, 100.0f);
sprite1 = new GameSprite("Resources\\spriteTest.bmp", "Resources\\SpriteShader.fx", 0.0f, 0.0f, 40, 40);
sprite1->SetView(View);
sprite1->SetProj(Projection);
sprite1->CalculateWorld();
the world matrix is re-calculated with every update call.
Am i doing something wrong with the Matrices?
i can´t figure out why it doesn´t work....
and sorry if its a silly error, it´s a bit hard to learn this by yourself
edit: sry for the formation... i don´t know where that comes from
edit2: ok i had the bb codes turned off... i fixed it now