#pragma once
#ifndef JDX_SPRITE_TEST_H
#define JDX_SPRITE_TEST_H
//DX Includes
#include <DirectXMath.h>
using namespace DirectX;
class SpriteTest{
public:
void Draw();
private:
struct ShaderParameters { XMMATRIX worldMatrix; };
struct VERTEX { XMFLOAT3 Position; XMFLOAT4 Color; };
...
...
};
#endif
#include "SpriteTest.h"
using namespace DirectX;
void SpriteTest::Initialize(){
// load and compile the two shaders
ID3D10Blob *VS = NULL, *PS = NULL;
m_pRenderManager->CompileShader("Shaders/SpriteBatchVS.hlsl","main","vs_5_0",&VS);
m_pRenderManager->CompileShader("Shaders/SpriteBatchPS.hlsl","main","ps_5_0",&PS);
// encapsulate both shaders into shader objects
m_pDevice->CreateVertexShader(VS->GetBufferPointer(), VS->GetBufferSize(), NULL, &m_pVertexShader);
m_pDevice->CreatePixelShader(PS->GetBufferPointer(), PS->GetBufferSize(), NULL, &m_pPixelShader);
// set the shader objects
m_pDeviceContext->VSSetShader(m_pVertexShader, 0, 0);
m_pDeviceContext->PSSetShader(m_pPixelShader, 0, 0);
// create the input layout object
D3D11_INPUT_ELEMENT_DESC ied[] =
{
{"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
{"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0},
};
m_pDevice->CreateInputLayout(ied, 2, VS->GetBufferPointer(), VS->GetBufferSize(), &m_pInputLayout);
m_pDeviceContext->IASetInputLayout(m_pInputLayout);
// __________ Init Vertex Buffer
// create a triangle using the VERTEX struct
/*
1__3
|\ |
| \|
0--2
struct VERTEX { XMFLOAT3 Position; XMFLOAT4 Color; };
*/
VERTEX QuadVertices[] =
{
{ XMFLOAT3(-1.0f, -1.0f, 0.0f), XMFLOAT4(1.0f, 0.0f, 0.0f, 1.0f)},
{ XMFLOAT3(-1.0f, 1.0f, 0.0f), XMFLOAT4(0.0f, 1.0f, 0.0f, 1.0f)},
{ XMFLOAT3( 1.0f, -1.0f, 0.0f), XMFLOAT4(0.0f, 0.0f, 1.0f, 1.0f)},
{ XMFLOAT3 (1.0f, 1.0f, 0.0f), XMFLOAT4(1.0f, 1.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) * 4; // size is the VERTEX struct * 4
bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; // use as a vertex buffer
bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; // allow CPU to write in buffer
m_pDevice->CreateBuffer(&bd, NULL, &m_pVertexBuffer); // create the buffer
// copy the vertices into the buffer
D3D11_MAPPED_SUBRESOURCE ms;
m_pDeviceContext->Map(m_pVertexBuffer, NULL, D3D11_MAP_WRITE_DISCARD, NULL, &ms); // map the buffer
memcpy(ms.pData, QuadVertices, sizeof(QuadVertices)); // copy the data
m_pDeviceContext->Unmap(m_pVertexBuffer, NULL); // unmap the buffer
// __________ Init Index Buffer
WORD indices[] =
{
0,1,2,
2,1,3,
};
D3D11_BUFFER_DESC indexDesc;
ZeroMemory( &indexDesc, sizeof( indexDesc ) );
indexDesc.Usage = D3D11_USAGE_DEFAULT;
indexDesc.ByteWidth = sizeof( WORD ) * 6;
indexDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
indexDesc.CPUAccessFlags = 0;
D3D11_SUBRESOURCE_DATA indexData;
ZeroMemory( &indexData, sizeof( indexData ) );
indexData.pSysMem = indices;
m_pDevice->CreateBuffer( &indexDesc, &indexData, &m_pIndexBuffer );
// __________ Init Constant Buffer
D3D11_BUFFER_DESC constDesc;
ZeroMemory( &constDesc, sizeof( constDesc ) );
constDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
constDesc.ByteWidth = sizeof( XMMATRIX );
constDesc.Usage = D3D11_USAGE_DEFAULT;
m_pDevice->CreateBuffer( &constDesc, 0, &m_pCostantBuffer );
}
void SpriteTest::Draw(){
// select which vertex buffer to display
UINT stride = sizeof(VERTEX);
UINT offset = 0;
m_pDeviceContext->IASetVertexBuffers(0, 1, &m_pVertexBuffer, &stride, &offset);
// select which primtive type we are using
m_pDeviceContext->IASetIndexBuffer( m_pIndexBuffer, DXGI_FORMAT_R16_UINT, 0 );
m_pDeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
XMMATRIX view = XMMatrixIdentity();
//XMMATRIX projection = XMMatrixOrthographicLH( 1024, 768, 0.0f, 100.0f );
XMMATRIX projection = XMMatrixOrthographicOffCenterLH( 0.0f,(float)m_pRenderManager->GetWidth(),0.0f,(float) m_pRenderManager->GetHeight(), 0.0f, 100.0f );
XMMATRIX worldMatrix = XMMatrixMultiply( view, projection );
ShaderParameters shaderParameters;
// __________ Sprite World Coordinates
float spriteWidth = 32.0f,
spriteHeight = 32.0f,
spritePosX = 0.0f,
spritePosY = 0.0f;
XMMATRIX l_translation = XMMatrixTranslation(spritePosX, spritePosY, 0.0f );
XMMATRIX l_rotationZ = XMMatrixRotationZ( 0.0f );
XMMATRIX l_scale = XMMatrixScaling( 1.0f * spriteWidth,1.0f * spriteHeight, 1.0f );
XMMATRIX l_spriteWVP = l_translation * l_rotationZ * l_scale;
// __________ Prepare World Coordinates to send to the shader
XMMATRIX l_worldMatrix = XMMatrixMultiply( l_spriteWVP, worldMatrix );
l_worldMatrix = XMMatrixTranspose( l_worldMatrix );
shaderParameters.worldMatrix = l_worldMatrix;
m_pDeviceContext->UpdateSubresource( m_pCostantBuffer, 0, NULL, &shaderParameters, 0, 0 );
m_pDeviceContext->VSSetConstantBuffers( 0, 1, &m_pCostantBuffer );
m_pDeviceContext->DrawIndexed( 6, 0, 0 );
}
cbuffer cbParameters : register( b0 ) {
float4x4 worldMatrix;
};
struct VOut
{
float4 position : SV_POSITION;
float4 color : COLOR;
};
VOut main(float4 position : POSITION, float4 color : COLOR)
{
VOut output;
output.position = mul(position,worldMatrix);
output.color = color;
return output;
}
float4 main(float4 position : SV_POSITION, float4 color : COLOR) : SV_TARGET
{
return color;
}