Related
I have a problem with my tesellation shader. It renders when i don't use Hull Shader or Domain Shader. Just plain vertex and pixel shader works fine. Here is my VS and PS shaders:
VOut VShader(float4 position : POSITION, float4 color : COLOR)
{
VOut output;
output.position = mul(world, position);
output.color = color;
return output;
}
float4 PShader(float4 position : SV_POSITION, float4 color : COLOR) : SV_TARGET
{
return color;
}
I am using Orthographic Projection to map out pixels to their original positions. Here is the problematic shader. Which inputs float3 vertices and float4 colors.
cbuffer cbPerFrame : register(b0) {
matrix world; };
struct VS_CONTROL_POINT_INPUT {
float3 vPosition : POSITION; };
struct VS_CONTROL_POINT_OUTPUT {
float3 vPosition : POSITION; };
struct HS_CONSTANT_DATA_OUTPUT {
float Edges[3] : SV_TessFactor;
float Inside : SV_InsideTessFactor; };
struct HS_OUTPUT {
float3 vPosition : POSITION; };
HS_CONSTANT_DATA_OUTPUT ConstantHS(InputPatch<VS_CONTROL_POINT_OUTPUT, 3> ip,uint PatchID : SV_PrimitiveID) {
HS_CONSTANT_DATA_OUTPUT Output;
Output.Edges[0] = Output.Edges[1] = Output.Edges[2] = 4;
Output.Inside = 4;
return Output; }
[domain("tri")]
[partitioning("integer")]
[outputtopology("triangle_cw")]
[outputcontrolpoints(3)]
[patchconstantfunc("ConstantHS")]
HS_OUTPUT HShader(InputPatch<VS_CONTROL_POINT_OUTPUT, 3> p, uint i : SV_OutputControlPointID, uint PatchID : SV_PrimitiveID)
{
HS_OUTPUT Output;
Output.vPosition = p[i].vPosition;
return Output;
}
struct DS_OUTPUT {
float4 vPosition : SV_POSITION; };
[domain("tri")]
DS_OUTPUT DShader(HS_CONSTANT_DATA_OUTPUT input, float3 UVW : SV_DomainLocation, const OutputPatch<HS_OUTPUT, 3> quad) {
DS_OUTPUT Output;
float3 finalPos = UVW.x * quad[0].vPosition + UVW.y * quad[1].vPosition + UVW.z * quad[2].vPosition;
Output.vPosition = mul(world,float4(finalPos, 1));
return Output; }
VS_CONTROL_POINT_OUTPUT VShader(VS_CONTROL_POINT_INPUT Input) {
VS_CONTROL_POINT_OUTPUT Output;
Output.vPosition = Input.vPosition;
return Output; }
float4 PShader(DS_OUTPUT Input) : SV_TARGET {
return float4(1, 0, 0, 1); }
My shader init. code:
D3DCompileFromFile(L"shader.hlsl", NULL, NULL, "VShader", "vs_5_0", 0, 0, &VS, &ERR);
D3DCompileFromFile(L"shader.hlsl", NULL, NULL, "PShader", "ps_5_0", 0, 0, &PS, &ERR);
D3DCompileFromFile(L"shader.hlsl", NULL, NULL, "HShader", "hs_5_0", 0, 0, &HS, &ERR);
D3DCompileFromFile(L"shader.hlsl", NULL, NULL, "DShader", "ds_5_0", 0, 0, &DS, &ERR);
dev->CreateVertexShader(VS->GetBufferPointer(), VS->GetBufferSize(), NULL, &pVS);
dev->CreatePixelShader(PS->GetBufferPointer(), PS->GetBufferSize(), NULL, &pPS);
dev->CreateHullShader(HS->GetBufferPointer(), HS->GetBufferSize(), NULL, &pHS);
dev->CreateDomainShader(DS->GetBufferPointer(), DS->GetBufferSize(), NULL, &pDS);
devcon->VSSetShader(pVS, 0, 0);
devcon->HSSetShader(pHS, 0, 0);
devcon->DSSetShader(pDS, 0, 0);
devcon->PSSetShader(pPS, 0, 0);
Input descriptor:
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},
};
dev->CreateInputLayout(ied, 2, VS->GetBufferPointer(), VS->GetBufferSize(), &pLayout);
devcon->IASetInputLayout(pLayout);
Rasterizer:
D3D11_RASTERIZER_DESC RasterDesc = {};
RasterDesc.FillMode = D3D11_FILL_SOLID;
RasterDesc.CullMode = D3D11_CULL_NONE;
RasterDesc.DepthClipEnable = TRUE;
ID3D11RasterizerState* WireFrame=NULL;
dev->CreateRasterizerState(&RasterDesc, &WireFrame);
devcon->RSSetState(WireFrame);
Input Vertices:
OurVertices = (VERTEX*)malloc(PointCount * sizeof(VERTEX));
for (int i = 0; i < PointCount; i++)
{
OurVertices[i] = { RandOm() * i,RandOm() * i ,RandOm() ,{abs(RandOm()),abs(RandOm()),abs(RandOm()),1.0f} };
}
CBuffer:
ID3D11Buffer* g_pConstantBuffer11 = NULL;
cbuff.world = XMMatrixOrthographicOffCenterLH(SceneY - (ViewPortWidth / 2) * SceneZoom, SceneY + (ViewPortWidth / 2) * SceneZoom,
SceneX - (ViewPortHeight / 2) * SceneZoom, SceneX + (ViewPortHeight / 2) * SceneZoom,-10000.0f, 10000.0f);
D3D11_BUFFER_DESC cbDesc;
cbDesc.ByteWidth = sizeof(CBUFFER);
cbDesc.Usage = D3D11_USAGE_DYNAMIC;
cbDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
cbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
cbDesc.MiscFlags = 0;
cbDesc.StructureByteStride = 0;
D3D11_SUBRESOURCE_DATA InitData;
InitData.pSysMem = &cbuff;
InitData.SysMemPitch = 0;
InitData.SysMemSlicePitch = 0;
dev->CreateBuffer(&cbDesc, &InitData,&g_pConstantBuffer11);
devcon->VSSetConstantBuffers(0, 1, &g_pConstantBuffer11);
On Render:
devcon->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST);
All possible exceptions are handled in this code. Just for clean code, they are removed. And there are no warnings or exceptions on Init and Render stage.
I can't even debug it because nothing being drawn to output. Also, is there any way to see output values from shaders?
cbuffer cbPerFrame : register(b0)
{
matrix world;
};
Is not used by the vertex shader anymore, but by the domain shader, however, it does not seem you are attaching it, so you should have :
devcon->VSSetConstantBuffers(0, 1, &g_pConstantBuffer11); //Vertex
devcon->DSSetConstantBuffers(0, 1, &g_pConstantBuffer11); //Domain
(Please note that you don't normally need to bind to vertex anymore if you use tesselation only).
Otherwise the pipeline will read a zero matrix.
I am trying to make a simple d3d11 program to rotate a cube.
But ultimately the cube doesnt seem to appear.
Only the screen is being cleared to blue but the cube doesnot show up.
I have been using this as my source: https://learn.microsoft.com/en-us/windows/win32/direct3dgetstarted/getting-started-with-a-directx-game
The structure of my project is a
MainClass.cpp, MainClass.h (Handles window initializtion)
DeviceResources.cpp, DeviceResources.h (The Device Resources include device, context, etc.)
Renderer.cpp, Renderer.h (The renderer loads geometry and shaders. Most probably this is where i am going wrong)
Here is my Renderer.h :
#pragma once
#include <memory>
#include <Windows.h>
#include <DirectXMath.h>
#include "DeviceResources.h"
class Renderer
{
public:
Renderer(std::shared_ptr<DeviceResources> deviceResources);
~Renderer();
void CreateDeviceDependentResources();
void CreateWindowSizeDependentResources();
void Update();
void Render();
private:
HRESULT CreateShaders();
HRESULT CreateCube();
void CreateViewAndPerspective();
bool m_done = false;
std::shared_ptr<DeviceResources> m_deviceResources;
typedef struct _constantBufferStruct {
DirectX::XMFLOAT4X4 world;
DirectX::XMFLOAT4X4 view;
DirectX::XMFLOAT4X4 projection;
} ConstantBufferStruct;
static_assert((sizeof(ConstantBufferStruct) % 16) == 0, "Constant Buffer size must be 16-byte aligned");
typedef struct _vertexPositionColor {
DirectX::XMFLOAT3 pos;
DirectX::XMFLOAT3 color;
} VertexPositionColor;
typedef struct _vertexPositionColorTangent {
DirectX::XMFLOAT3 pos;
DirectX::XMFLOAT3 color;
DirectX::XMFLOAT3 tangent;
} VertexPositionColorTangent;
ConstantBufferStruct m_constantBufferData;
unsigned int m_indexCount;
unsigned int m_frameCount;
Microsoft::WRL::ComPtr<ID3D11Buffer> m_pVertexBuffer;
Microsoft::WRL::ComPtr<ID3D11Buffer> m_pIndexBuffer;
Microsoft::WRL::ComPtr<ID3D11VertexShader> m_pVertexShader;
Microsoft::WRL::ComPtr<ID3D11PixelShader> m_pPixelShader;
Microsoft::WRL::ComPtr<ID3D11InputLayout> m_pInputLayout;
Microsoft::WRL::ComPtr<ID3D11InputLayout> m_pInputLayoutExtended;
Microsoft::WRL::ComPtr<ID3D11Buffer> m_pConstantBuffer;
};
And here is my Renderer.cpp code :
#include "Renderer.h"
#include <fstream>
#include <ppltasks.h>
#include <stdexcept>
Renderer::Renderer(std::shared_ptr<DeviceResources> deviceResources) :
m_deviceResources(deviceResources),
m_frameCount(0)
{
m_frameCount = 0;
}
Renderer::~Renderer() {}
void Renderer::CreateDeviceDependentResources() {
auto CreateShaderTask = Concurrency::create_task([this]() {CreateShaders();
m_done = true;
});
auto CreateCubeTask = CreateShaderTask.then([this]() {CreateCube(); });
}
void Renderer::CreateWindowSizeDependentResources() {
CreateViewAndPerspective();
}
HRESULT Renderer::CreateShaders() {
HRESULT hr = S_OK;
ID3D11Device* device = m_deviceResources->GetDevice();
FILE* vShader, * pShader;
BYTE* bytes;
size_t destSize = 4096;
size_t bytesRead = 0;
bytes = new BYTE[destSize];
fopen_s(&vShader, "cubeVertexShader.cso", "rb");
bytesRead = fread_s(bytes, destSize, 1, 4096, vShader);
hr = device->CreateVertexShader(
bytes,
bytesRead,
nullptr,
&m_pVertexShader
);
D3D11_INPUT_ELEMENT_DESC iaDesc[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT,
0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "COLOR", 0, DXGI_FORMAT_R32G32B32_FLOAT,
0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
};
hr = device->CreateInputLayout(iaDesc,ARRAYSIZE(iaDesc), bytes, bytesRead, &m_pInputLayout);
delete bytes;
bytes = new BYTE[destSize];
bytesRead = 0;
fopen_s(&pShader, "cubePixelShader.cso", "rb");
bytesRead = fread_s(bytes, destSize, 1, 4096, pShader);
hr = device->CreatePixelShader(bytes, bytesRead, nullptr, &m_pPixelShader);
CD3D11_BUFFER_DESC cbDesc(sizeof(ConstantBufferStruct), D3D11_BIND_CONSTANT_BUFFER );
hr = device->CreateBuffer(&cbDesc, nullptr, &m_pConstantBuffer);
if (FAILED(hr))
throw std::exception("Failed to Create Constant Buffer");
fclose(vShader);
fclose(pShader);
return hr;
}
HRESULT Renderer::CreateCube() {
HRESULT hr = S_OK;
ID3D11Device* device = m_deviceResources->GetDevice();
VertexPositionColor CubeVertices[] =
{
{DirectX::XMFLOAT3(-0.5f,-0.5f,-0.5f), DirectX::XMFLOAT3(0, 0, 0),},
{DirectX::XMFLOAT3(-0.5f,-0.5f, 0.5f), DirectX::XMFLOAT3(0, 0, 1),},
{DirectX::XMFLOAT3(-0.5f, 0.5f,-0.5f), DirectX::XMFLOAT3(0, 1, 0),},
{DirectX::XMFLOAT3(-0.5f, 0.5f, 0.5f), DirectX::XMFLOAT3(0, 1, 1),},
{DirectX::XMFLOAT3(0.5f,-0.5f,-0.5f), DirectX::XMFLOAT3(1, 0, 0),},
{DirectX::XMFLOAT3(0.5f,-0.5f, 0.5f), DirectX::XMFLOAT3(1, 0, 1),},
{DirectX::XMFLOAT3(0.5f, 0.5f,-0.5f), DirectX::XMFLOAT3(1, 1, 0),},
{DirectX::XMFLOAT3(0.5f, 0.5f, 0.5f), DirectX::XMFLOAT3(1, 1, 1),},
};
unsigned short CubeIndices[] =
{
0,2,1, // -x
1,2,3,
4,5,6, // +x
5,7,6,
0,1,5, // -y
0,5,4,
2,6,7, // +y
2,7,3,
0,4,6, // -z
0,6,2,
1,3,7, // +z
1,7,5,
};
m_indexCount = ARRAYSIZE(CubeIndices);
CD3D11_BUFFER_DESC vbDesc(sizeof(CubeVertices), D3D11_BIND_VERTEX_BUFFER);
D3D11_SUBRESOURCE_DATA vData;
ZeroMemory(&vData, sizeof(D3D11_SUBRESOURCE_DATA));
vData.pSysMem = CubeVertices;
vData.SysMemPitch = 0;
vData.SysMemSlicePitch = 0;
hr = device->CreateBuffer(&vbDesc, &vData, &m_pVertexBuffer);
CD3D11_BUFFER_DESC ibDesc(sizeof(CubeIndices), D3D11_BIND_INDEX_BUFFER);
D3D11_SUBRESOURCE_DATA iData;
ZeroMemory(&iData, sizeof(D3D11_SUBRESOURCE_DATA));
iData.pSysMem = CubeIndices;
iData.SysMemPitch = 0;
iData.SysMemSlicePitch = 0;
hr = device->CreateBuffer(&ibDesc, &iData, &m_pIndexBuffer);
return hr;
}
void Renderer::CreateViewAndPerspective() {
// Use DirectXMath to create view and perspective matrices.
DirectX::XMVECTOR eye = DirectX::XMVectorSet(0.0f, 0.7f, 1.5f, 0.f);
DirectX::XMVECTOR at = DirectX::XMVectorSet(0.0f, -0.1f, 0.0f, 0.f);
DirectX::XMVECTOR up = DirectX::XMVectorSet(0.0f, 1.0f, 0.0f, 0.f);
DirectX::XMStoreFloat4x4(
&m_constantBufferData.view,
DirectX::XMMatrixTranspose(
DirectX::XMMatrixLookAtRH(
eye,
at,
up
)
)
);
float aspectRatio = m_deviceResources->GetAspectRatio();
DirectX::XMStoreFloat4x4(
&m_constantBufferData.projection,
DirectX::XMMatrixTranspose(
DirectX::XMMatrixPerspectiveFovRH(
DirectX::XMConvertToRadians(70),
aspectRatio,
0.01f,
100.0f
)
)
);
}
void Renderer::Update() {
DirectX::XMStoreFloat4x4(
&m_constantBufferData.world,
DirectX::XMMatrixTranspose(
DirectX::XMMatrixRotationY(
DirectX::XMConvertToRadians(
(float)m_frameCount++
)
)
)
);
if (m_frameCount == MAXUINT) m_frameCount = 0;
}
void Renderer::Render() {
while (!m_done) {
}
ID3D11DeviceContext* context = m_deviceResources->GetDeviceContext();
ID3D11RenderTargetView* renderTarget = m_deviceResources->GetRenderTarget();
ID3D11DepthStencilView* depthStencil = m_deviceResources->GetDepthStencil();
context->UpdateSubresource(m_pConstantBuffer.Get(), 0, nullptr, &m_constantBufferData, 0, 0);
const float blue[4] = { 0.2f, 0.3f, 0.8f, 1.0f};
context->ClearRenderTargetView(renderTarget, blue);
context->ClearDepthStencilView(depthStencil, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
context->OMSetRenderTargets(1, &renderTarget, depthStencil);
UINT stride = sizeof(VertexPositionColor);
UINT offset = 0;
context->IASetVertexBuffers(
0,
1,
m_pVertexBuffer.GetAddressOf(),
&stride,
&offset
);
context->IASetIndexBuffer(m_pIndexBuffer.Get(), DXGI_FORMAT_R16_UINT, 0);
context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
context->IASetInputLayout(m_pInputLayout.Get());
context->VSSetShader(m_pVertexShader.Get(), nullptr, 0);
context->VSSetConstantBuffers(0, 1, m_pConstantBuffer.GetAddressOf());
context->PSSetShader(m_pPixelShader.Get(), nullptr, 0);
//context->DrawIndexed(m_indexCount, 0, 0);
context->Draw(3, 0);
}
For more reference here are the shaders:-
Vertex Shader
cbuffer ModelViewProjectionBuffer : register(b0)
{
matrix model;
matrix view;
matrix projection;
};
float4 main(float3 Position:POSITION, float3 Color:COLOR) : SV_POSITION// main is the default function name
{
float4 pos = float4(Position, 1.0f);
// Transform the position from object space to homogeneous projection space
pos = mul(pos, model);
pos = mul(pos, view);
pos = mul(pos, projection);
return pos;
}
Pixel Shader:
float4 main(float4 position:SV_POSITION) : SV_TARGET
{
return float4(0.9f, 0.4f, 0.2f, 1.0f);
}
Image of the output
Please help me analyze where i am going wrong.
Moreover, i am using visual studio 2019.
Edit: Some were asking a for a complete reproduction so here is the visual studio solution
https://drive.google.com/file/d/1jt6fQgbRElpc9AYpbhYOyp-HCQL3WmEF/view?usp=sharing
You're doing invalid memory accesses when reading the vertex and pixel buffers.
Also, on my computer, both shaders have a dozen of kbytes whilst the memory buffer you're reading them to has only 4096 bytes.
To fix your problem, increase the size of the memory buffer you're using to read the shader bytecode from disk and don't forget to update the elementcount in fread_s().
e.g.,
Renderer.cpp # 35
size_t destSize = 1024 * 1024; // CHANGE THE SIZE OF YOUR MEMORY BUFFER HERE
size_t bytesRead = 0;
bytes = new BYTE[destSize];
fopen_s(&vShader, "cubeVertexShader.cso", "rb");
bytesRead = fread_s(bytes, destSize * sizeof(BYTE), sizeof(BYTE), destSize, vShader);
hr = device->CreateVertexShader(
bytes,
bytesRead,
nullptr,
&m_pVertexShader
);
Do the same where you're reading the pixel shader.
PRO TIP: Pay attention to the debug output and you'll see important messages from d3d debug layer, like the one telling you that both shaders failed to be created :)
I am developing a game engine using the Rastertek tutorials.
My problem is that the terrain texture isn't loading properly.
Pixel Shader:
Texture2D shaderTexture;
SamplerState SampleType;
cbuffer LightBuffer
{
float4 ambientColor;
float4 diffuseColor;
float3 lightDirection;
float padding;
};
//////////////
// TYPEDEFS //
//////////////
struct PixelInputType
{
float4 position : SV_POSITION;
float2 tex : TEXCOORD0;
float3 normal : NORMAL;
};
////////////////////////////////////////////////////////////////////////////////
// Pixel Shader
////////////////////////////////////////////////////////////////////////////////
float4 TerrainPixelShader(PixelInputType input) : SV_TARGET
{
float4 textureColor;
float3 lightDir;
float lightIntensity;
float4 color;
// Sample the pixel color from the texture using the sampler at this texture coordinate location.
textureColor = shaderTexture.Sample(SampleType, input.tex);
// Set the default output color to the ambient light value for all pixels.
color = ambientColor;
// Invert the light direction for calculations.
lightDir = -lightDirection;
// Calculate the amount of light on this pixel.
lightIntensity = saturate(dot(input.normal, lightDir));
if(lightIntensity > 0.0f)
{
// Determine the final diffuse color based on the diffuse color and the amount of light intensity.
color += (diffuseColor * lightIntensity);
}
// Saturate the final light color.
color = saturate(color);
// Multiply the texture pixel and the final light color to get the result.
color = color * textureColor;
Vertex Shader:
cbuffer MatrixBuffer
{
matrix worldMatrix;
matrix viewMatrix;
matrix projectionMatrix;
};
//////////////
// TYPEDEFS //
//////////////
struct VertexInputType
{
float4 position : POSITION;
float2 tex : TEXCOORD0;
float3 normal : NORMAL;
};
struct PixelInputType
{
float4 position : SV_POSITION;
float2 tex : TEXCOORD0;
float3 normal : NORMAL;
};
////////////////////////////////////////////////////////////////////////////////
// Vertex Shader
////////////////////////////////////////////////////////////////////////////////
PixelInputType TerrainVertexShader(VertexInputType input)
{
PixelInputType output;
// Change the position vector to be 4 units for proper matrix calculations.
input.position.w = 1.0f;
// Calculate the position of the vertex against the world, view, and projection matrices.
output.position = mul(input.position, worldMatrix);
output.position = mul(output.position, viewMatrix);
output.position = mul(output.position, projectionMatrix);
// Store the texture coordinates for the pixel shader.
output.tex = input.tex;
// Calculate the normal vector against the world matrix only.
output.normal = mul(input.normal, (float3x3)worldMatrix);
// Normalize the normal vector.
output.normal = normalize(output.normal);
return output;
}
Terrain Shader Class:
bool TerrainShaderClass::SetShaderParameters(ID3D11DeviceContext* deviceContext, D3DXMATRIX world, D3DXMATRIX view,
D3DXMATRIX projection, D3DXVECTOR4 ambientColor, D3DXVECTOR4 diffuseColor, D3DXVECTOR3 lightDirection,
ID3D11ShaderResourceView* texture)
{
HRESULT result;
D3D11_MAPPED_SUBRESOURCE mappedResource;
unsigned int bufferNumber;
MatrixBufferType* matrixData;
LightBufferType* lightData;
D3DXMatrixTranspose(&world, &world);
D3DXMatrixTranspose(&view, &view);
D3DXMatrixTranspose(&projection, &projection);
result = deviceContext->Map(m_matrixBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
if (FAILED(result))
{
return false;
}
matrixData = (MatrixBufferType*)mappedResource.pData;
matrixData->world = world;
matrixData->view = view;
matrixData->projection = projection;
deviceContext->Unmap(m_matrixBuffer, 0);
bufferNumber = 0;
deviceContext->VSSetConstantBuffers(bufferNumber, 1, &m_matrixBuffer);
deviceContext->Map(m_lightBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
lightData = (LightBufferType*)mappedResource.pData;
lightData->ambientColor = ambientColor;
lightData->diffuseColor = diffuseColor;
lightData->lightDirection = lightDirection;
lightData->padding = 0.0f;
deviceContext->Unmap(m_lightBuffer, 0);
bufferNumber = 0;
deviceContext->PSSetConstantBuffers(bufferNumber, 1, &m_lightBuffer);
deviceContext->PSSetShaderResources(0, 1, &texture);
return true;
}
void TerrainShaderClass::OutputShaderErrorMessage(ID3D10Blob* errorMessage, HWND hwnd, LPCSTR shaderFileName)
{
char* compileErrors = (char*)(errorMessage->GetBufferPointer());
unsigned long bufferSize = errorMessage->GetBufferSize();
ofstream fout;
fout.open("shader-error.txt");
for (unsigned long i = 0; i < bufferSize; i++)
{
fout << compileErrors[i];
}
fout.close();
errorMessage->Release();
errorMessage = nullptr;
MessageBox(hwnd, "Error compiling shader. Check shader-error.txt for message.", shaderFileName, MB_OK);
}
void TerrainShaderClass::RenderShader(ID3D11DeviceContext* deviceContext, int indexCount)
{
deviceContext->IASetInputLayout(m_layout);
deviceContext->VSSetShader(m_vertexShader, NULL, 0);
deviceContext->PSSetShader(m_pixelShader, NULL, 0);
deviceContext->PSSetSamplers(0, 1, &m_samplerState);
deviceContext->DrawIndexed(indexCount, 0, 0);
}
bool TerrainShaderClass::InitializeShader(ID3D11Device* device, HWND hwnd, LPCSTR vsFileName, LPCSTR psFileName)
{
HRESULT result;
ID3D10Blob* errorMessage = nullptr;
ID3D10Blob* vertexShaderBuffer = nullptr;
ID3D10Blob* pixelShaderBuffer = nullptr;
D3D11_INPUT_ELEMENT_DESC polygonLayout[3];
unsigned int numElements;
D3D11_SAMPLER_DESC samplerDesc;
D3D11_BUFFER_DESC matrixBufferDesc;
D3D11_BUFFER_DESC lightBufferDesc;
result = D3DX11CompileFromFile(vsFileName, NULL, NULL, "TerrainVertexShader", "vs_5_0", D3D10_SHADER_ENABLE_STRICTNESS,
0, NULL, &vertexShaderBuffer, &errorMessage, NULL);
if (FAILED(result))
{
if (errorMessage)
{
OutputShaderErrorMessage(errorMessage, hwnd, vsFileName);
}
else
{
MessageBox(hwnd, "Missing Shader File", vsFileName, MB_OK);
}
return false;
}
result = D3DX11CompileFromFile(psFileName, NULL, NULL, "TerrainPixelShader", "ps_5_0", D3D10_SHADER_ENABLE_STRICTNESS,
0, NULL, &pixelShaderBuffer, &errorMessage, NULL);
if (FAILED(result))
{
if (errorMessage)
{
OutputShaderErrorMessage(errorMessage, hwnd, psFileName);
}
else
{
MessageBox(hwnd, "Missing Shader File", psFileName, MB_OK);
}
return false;
}
result = device->CreateVertexShader(vertexShaderBuffer->GetBufferPointer(), vertexShaderBuffer->GetBufferSize(), NULL, &m_vertexShader);
if (FAILED(result))
{
return false;
}
result = device->CreatePixelShader(pixelShaderBuffer->GetBufferPointer(), pixelShaderBuffer->GetBufferSize(), NULL, &m_pixelShader);
if (FAILED(result))
{
return false;
}
polygonLayout[0].SemanticName = "POSITION";
polygonLayout[0].SemanticIndex = 0;
polygonLayout[0].Format = DXGI_FORMAT_R32G32B32_FLOAT;
polygonLayout[0].InputSlot = 0;
polygonLayout[0].AlignedByteOffset = 0;
polygonLayout[0].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
polygonLayout[0].InstanceDataStepRate = 0;
polygonLayout[1].SemanticName = "TEXCOORD";
polygonLayout[1].SemanticIndex = 0;
polygonLayout[1].Format = DXGI_FORMAT_R32G32_FLOAT;
polygonLayout[1].InputSlot = 0;
polygonLayout[1].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
polygonLayout[1].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
polygonLayout[1].InstanceDataStepRate = 0;
polygonLayout[2].SemanticName = "NORMAL";
polygonLayout[2].SemanticIndex = 0;
polygonLayout[2].Format = DXGI_FORMAT_R32G32B32_FLOAT;
polygonLayout[2].InputSlot = 0;
polygonLayout[2].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
polygonLayout[2].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
polygonLayout[2].InstanceDataStepRate = 0;
numElements = sizeof(polygonLayout) / sizeof(polygonLayout[0]);
result = device->CreateInputLayout(polygonLayout, numElements, vertexShaderBuffer->GetBufferPointer(), vertexShaderBuffer->GetBufferSize(), &m_layout);
if (FAILED(result))
{
return false;
}
vertexShaderBuffer->Release();
vertexShaderBuffer = nullptr;
pixelShaderBuffer->Release();
pixelShaderBuffer = nullptr;
samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
samplerDesc.MipLODBias = 0.0f;
samplerDesc.MaxAnisotropy = 1;
samplerDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
samplerDesc.BorderColor[0] = 0;
samplerDesc.BorderColor[1] = 0;
samplerDesc.BorderColor[2] = 0;
samplerDesc.BorderColor[3] = 0;
samplerDesc.MinLOD = 0;
samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
result = device->CreateSamplerState(&samplerDesc, &m_samplerState);
if (FAILED(result))
{
return false;
}
matrixBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
matrixBufferDesc.ByteWidth = sizeof(MatrixBufferType);
matrixBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
matrixBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
matrixBufferDesc.MiscFlags = 0;
matrixBufferDesc.StructureByteStride = 0;
result = device->CreateBuffer(&matrixBufferDesc, NULL, &m_matrixBuffer);
if (FAILED(result))
{
return false;
}
//ByteWidth must be a multiple of 16 if using D3D11_BIND_CONSTANT_BUFFER or CreateBuffer will fail.
lightBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
lightBufferDesc.ByteWidth = sizeof(LightBufferType);
lightBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
lightBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
lightBufferDesc.MiscFlags = 0;
lightBufferDesc.StructureByteStride = 0;
device->CreateBuffer(&lightBufferDesc, NULL, &m_lightBuffer);
if (FAILED(result))
{
return false;
}
return true;
}
The texture is supposed to look like displayed on the link, but instead looks like really weird (can't seem to be able to take a screen shot, will add if possible).
I tried looking into other questions here, but none solved the issue.
I am still fairly new to DX11, so any help is much appreciated.
Edit: Here is a screenshot (left side: supposed, right side: my game)
Im looking at your screenshot, and your not only is your texture not rendering correctly, but your normals aren't either otherwise you would have a diffuse at least shading it properly. I would summise, that although your stride is correct, what you are pulling out of the buffer for UV and Normal is not aligned properly. My first thoughts.
I have been trying to add a particle system to my Directx11 graphics demo, and so i have been using the 'Introduction to 3d Game Programming with directx 11' book.
Because of this am attempting to use a HLSL StreamOut technique to update the particle system and a separate technique to render the particles.
Below is the HLSL code for the particle system, i have tried adjusting the acceleration and velocity in the off chance the speed was sending the particles off the screen, however this had no effect.
cbuffer cbPerFrame
{
float3 gEyePosW;
float3 gEmitPosW;
float3 gEmitDirW;
float gGameTime;
float gTimeStep;
float4x4 gViewProj;
};
cbuffer cbFixed
{
// Net constant acceleration used to accerlate the particles.
float3 gAccelW = {0.0f, 0.2f, 0.0f};
// Texture coordinates for billbording are always the same - we use a qquad in this effect :)
float2 gTexC[4] =
{
float2(0.0f, 1.0f),
float2(0.0f, 0.0f),
float2(1.0f, 1.0f),
float2(1.0f, 0.0f)
};
};
// Nonnumeric values cannot be added to a cbuffer.
Texture2DArray gTextureMapArray;
// Random texture used to generate random numbers in shaders.
Texture1D gRandomTexture;
SamplerState samLinear
{
Filter = MIN_MAG_MIP_LINEAR;
AddressU = WRAP;
AddressV = WRAP;
};
DepthStencilState DisableDepth
{
DepthEnable = FALSE;
DepthWriteMask = ZERO;
};
DepthStencilState NoDepthWrites
{
DepthEnable = TRUE;
DepthWriteMask = ZERO;
};
BlendState AdditiveBlending
{
AlphaToCoverageEnable = FALSE;
BlendEnable[0] = TRUE;
SrcBlend = SRC_ALPHA;
DestBlend = ONE;
BlendOp = ADD;
SrcBlendAlpha = ZERO;
DestBlendAlpha = ZERO;
BlendOpAlpha = ADD;
RenderTargetWriteMask[0] = 0x0F;
};
///////////////////////////////////////////////////////////////
// Helper functions
//
///////////////////////////////////////////////////////////////
float3 RandUnitVec3(float offset)
{
// Use game time plus offset to sample random texture.
float u = (gGameTime + offset);
// coordinates in [-1,1]
float3 v = gRandomTexture.SampleLevel(samLinear, u, 0).xyz;
// project onto unit sphere (Normalize)
return normalize(v);
}
///////////////////////////////////////////////////////////////
// Stream Out Technique
//
///////////////////////////////////////////////////////////////
#define PT_EMITTER 0
#define PT_FLARE 1
struct Particle
{
float3 InitPosW : POSITION;
float3 InitVelW : VELOCITY;
float2 SizeW : SIZE;
float Age : AGE;
uint Type : Type;
};
Particle StreamOutVS(Particle vin)
{
return vin;
}
// The stream-out GS is just responsible for emitting
// new particles and destroying old particles. The logic
// programed here will generally vary from particle system
// to particle system, as the destroy/spawn rules will be
// different.
[maxvertexcount(2)]
void StreamOutGS(point Particle gin[1],
inout PointStream<Particle> ptStream)
{
gin[0].Age += gTimeStep;
// if particle is emitter particle
if (gin[0].Type == PT_EMITTER)
{
// If it's time to emit new particle
if (gin[0].Age > 0.005f)
{
float3 vRandom = RandUnitVec3(0.0f);
vRandom.x *= 0.5f;
vRandom.z *= 0.5f;
Particle p;
p.InitPosW = gEmitPosW.xyz;
p.InitVelW = 0.5f*vRandom;
p.SizeW = float2(3.0f, 3.0f);
p.Age = 0.0f;
p.Type = PT_FLARE;
ptStream.Append(p);
// reset the time to emit
gin[0].Age = 0.0f;
}
// always keep emitters
ptStream.Append(gin[0]);
}
else
{
// Set conditions to keep a particle - in this case age limit
if (gin[0].Age <= 1.0f)
{
ptStream.Append(gin[0]);
}
}
}
GeometryShader gsStreamOut = ConstructGSWithSO(
CompileShader( gs_5_0, StreamOutGS() ),
"POSITION.xyz; VELOCITY.xyz; SIZE.xyz; AGE.x; TYPE.x" );
technique11 StreamOutTech
{
pass P0
{
SetVertexShader( CompileShader( vs_5_0, StreamOutVS() ) );
SetGeometryShader( gsStreamOut );
// disable pixel shader for stream-out only
SetPixelShader(NULL);
// we must also disable the depth buffer for stream-out only
SetDepthStencilState( DisableDepth, 0 );
}
}
///////////////////////////////////////////////////////////////
// Draw Technique
//
///////////////////////////////////////////////////////////////
struct VertexIn
{
float3 Pos : POSITION;
float2 SizeW : SIZE;
};
struct VertexOut
{
float3 PosW : POSITION;
float2 SizeW : SIZE;
float4 Colour : COLOR;
uint Type : TYPE;
};
VertexOut DrawVS(Particle vin)
{
VertexOut vout;
float t = vin.Age;
// constant Acceleration equation
vout.PosW = 0.5f*t*t*gAccelW + t*vin.InitVelW + vin.InitPosW;
// fade colour with time
float opacity = 1.0f - smoothstep(0.0f, 1.0f, t/1.0f);
vout.Colour = float4(1.0f, 1.0f, 1.0f, opacity);
vout.SizeW = vin.SizeW;
vout.Type = vin.Type;
return vout;
}
struct GeoOut
{
float4 PosH : SV_POSITION;
float4 Colour : COLOR;
float2 Tex : TEXCOORD;
};
// Expand each 'Point' into a quad (4 verticies)
[maxvertexcount(4)]
void DrawGS(point VertexOut gin[1],
inout TriangleStream<GeoOut> triStream)
{
// Do not draw Emiter particles in this system
if (gin[0].Type != PT_EMITTER)
{
//
// Compute world matrix so that billboard faces the camera.
//
float3 look = normalize(gEyePosW.xyz - gin[0].PosW);
float3 right = normalize(cross(float3(0,1,0), look));
float3 up = cross(look, right);
//
// Compute triangle strip vertices (quad) in world space.
//
float halfWidth = 0.5f*gin[0].SizeW.x;
float halfHeight = 0.5f*gin[0].SizeW.y;
float4 v[4];
v[0] = float4(gin[0].PosW + halfWidth*right - halfHeight*up, 1.0f);
v[1] = float4(gin[0].PosW + halfWidth*right + halfHeight*up, 1.0f);
v[2] = float4(gin[0].PosW - halfWidth*right - halfHeight*up, 1.0f);
v[3] = float4(gin[0].PosW - halfWidth*right + halfHeight*up, 1.0f);
//
// Transform quad vertices to world space and output
// them as a triangle strip.
//
GeoOut gout;
[unroll]
for(int i = 0; i < 4; ++i)
{
gout.PosH = mul(v[i], gViewProj);
gout.Tex = gTexC[i];
gout.Colour = gin[0].Colour;
triStream.Append(gout);
}
}
}
float DrawPS(GeoOut pin) : SV_TARGET
{
return gTextureMapArray.Sample(samLinear, float3(pin.Tex, 0)) * pin.Colour;
}
technique11 DrawTech
{
pass P0
{
SetVertexShader( CompileShader( vs_5_0, DrawVS() ) );
SetGeometryShader( CompileShader( gs_5_0, DrawGS() ) );
SetPixelShader( CompileShader( ps_5_0, DrawPS() ) );
SetBlendState(AdditiveBlending, float4(0.0f, 0.0f, 0.0f, 0.0f), 0xffffffff);
SetDepthStencilState( NoDepthWrites, 0 );
}
}
Below is the code for building the VB.
void ParticleSystem::BuildVB(ID3D11Device* device)
{
/////////////////////////////////////////////////////////
// Create the buffer to start the particle system.
/////////////////////////////////////////////////////////
D3D11_BUFFER_DESC vbd;
vbd.Usage = D3D11_USAGE_DEFAULT;
vbd.ByteWidth = sizeof(Vertex::Particle) * 1;
vbd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vbd.CPUAccessFlags = 0;
vbd.MiscFlags = 0;
vbd.StructureByteStride = 0;
// The initial particle emitter has type 0 and age 0. The rest
// of the particle attributes do not apply to an emitter.
Vertex::Particle p;
ZeroMemory(&p, sizeof(Vertex::Particle));
p.Age = 0.0f;
p.Type = 0;
D3D11_SUBRESOURCE_DATA vinitData;
vinitData.pSysMem = &p;
HR(device->CreateBuffer(&vbd, &vinitData, &mInitVB));
//////////////////////////////////////////////////////////////
// Create the buffers which swap back and forth for stream-out and drawing.
//////////////////////////////////////////////////////////////
vbd.ByteWidth = sizeof(Vertex::Particle) * mMaxParticles;
vbd.BindFlags = D3D11_BIND_VERTEX_BUFFER | D3D11_BIND_STREAM_OUTPUT;
HR(device->CreateBuffer(&vbd, 0, &mDrawVB));
HR(device->CreateBuffer(&vbd, 0, &mStreamOutVB));
}
And now the Draw cpp code.
void ParticleSystem::Draw(ID3D11DeviceContext* dc, const XMMATRIX& viewProj)
{
//
// Set constants.
//
mFX->SetViewProj(viewProj);
mFX->SetGameTime(mGameTime);
mFX->SetTimeStep(mTimeStep);
mFX->SetEyePosW(mEyePosW);
mFX->SetEmitPosW(mEmitPosW);
mFX->SetEmitDirW(mEmitDirW);
mFX->SetTexArray(mTextureArraySRV);
mFX->SetRandomTex(mRandomTextureSRV);
//
// Set IA stage.
//
dc->IASetInputLayout(InputLayouts::Particle);
dc->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);
UINT stride = sizeof(Vertex::Particle);
UINT offset = 0;
// On the first pass, use the initialization VB. Otherwise, use
// the VB that contains the current particle list.
if( mFirstRun )
dc->IASetVertexBuffers(0, 1, &mInitVB, &stride, &offset);
else
dc->IASetVertexBuffers(0, 1, &mDrawVB, &stride, &offset);
//
// Draw the current particle list using stream-out only to update them.
// The updated vertices are streamed-out to the target VB.
//
dc->SOSetTargets(1, &mStreamOutVB, &offset);
D3DX11_TECHNIQUE_DESC techDesc;
mFX->StreamOutTech->GetDesc( &techDesc );
for(UINT p = 0; p < techDesc.Passes; ++p)
{
mFX->StreamOutTech->GetPassByIndex( p )->Apply(0, dc);
if(mFirstRun)
{
dc->Draw(1, 0);
mFirstRun = false;
}
else
{
dc->DrawAuto();
}
}
// done streaming-out--unbind the vertex buffer
ID3D11Buffer* bufferArray[1] = {0};
dc->SOSetTargets(1, bufferArray, &offset);
// ping-pong the vertex buffers
std::swap(mDrawVB, mStreamOutVB);
//
// Draw the updated particle system we just streamed-out.
//
dc->IASetVertexBuffers(0, 1, &mDrawVB, &stride, &offset);
mFX->DrawTech->GetDesc( &techDesc );
for(UINT p = 0; p < techDesc.Passes; ++p)
{
mFX->DrawTech->GetPassByIndex( p )->Apply(0, dc);
dc->DrawAuto();
}
}
I had thought that perhaps either a blend state or Depth state in use by some of the other objects in my scene may be causing the issue, (perhaps i have misunderstood something I have set earlier). I tried removing all other render code leaving just the draw code above, but with no results.
To my mind, I can only think of a few possible causes for the issue i am having, but so far i am unable to find a solution.
The scale of the system is wrong for my scene. eg. the particles are drawing but are moving off the screen to fast to be seen.
As mentioned above i have tried removing the acceleration and velocity of the particles in the HLSL code, in order to see stationary particles. This had no effect.
Blend state/Depth stencil state is incorrect. Eg. As mentioned above.
The Emitter particle is, for some reason, not being produced/placed correctly. causing no 'drawable' particles to be produced in turn.
As most of this code is in the .fx file, I am unable to step through to check the emitter particles. I think this is the more likely issue, but i have been wrong before.
Any help on this would be greatly appreciated, I am well and truly stuck on this.
Below I have added additional snippets of code which may be of use.
E.G. Input layout.
const D3D11_INPUT_ELEMENT_DESC InputLayoutDesc::Particle[5] =
{
{"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
{"VELOCITY", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0},
{"SIZE", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0},
{"AGE", 0, DXGI_FORMAT_R32_FLOAT, 0, 32, D3D11_INPUT_PER_VERTEX_DATA, 0},
{"TYPE", 0, DXGI_FORMAT_R32_UINT, 0, 36, D3D11_INPUT_PER_VERTEX_DATA, 0},
};
And particle system INIT
mFire.Init(md3dDevice, AppEffects::FireFX, mFlareTextureSRV, mRandomTextureSRV, 500);
mFire.SetEmitPos(XMFLOAT3(1.0f, 0.5f, 0.0f));
void ParticleSystem::Init(ID3D11Device* device, ParticleEffect* fx,
ID3D11ShaderResourceView* textureArraySRV,
ID3D11ShaderResourceView* randomTextureSRV,
UINT maxParticles)
{
mMaxParticles = maxParticles;
mFX = fx;
mTextureArraySRV = textureArraySRV;
mRandomTextureSRV = randomTextureSRV;
BuildVB(device);
}
If i have missed any section of the code you would need to see, let me know.
Thanks in advance.
Sorry about this stupid question all. Turns out it was a stupid mistake in the pixel shader. I had set the pixel shader as a float instead of float4.
I'm just starting out in DirectX 11, and I've run into a problem. I'm loading an extremely simple shader in an HSDL file:
struct VOut{
float4 position : SV_POSITION;
float4 color : COLOR;
};
VOut VS_Main( float4 pos : POSITION, float4 color : COLOR )
{
VOut output;
output.position = pos;
output.color = color;
return output;
}
float4 PS_Main( float4 pos : SV_POSITION, float4 color : COLOR ) : SV_TARGET
{
return color;
}
Using the following code (that DOES NOT trigger the if(FAILED(result) statement):
bool PathfindingDemoBase::CompileD3DShader(char* filePath, char* entry, char* shaderModel, ID3DBlob** buffer){
DWORD shaderFlags = D3DCOMPILE_ENABLE_STRICTNESS;
#if defined(DEBUG) || defined(_DEBUG)
shaderFlags |= D3DCOMPILE_DEBUG;
#endif
ID3DBlob* errorBuffer = 0;
HRESULT result;
result = D3DX11CompileFromFile(filePath, 0, 0, entry, shaderModel,
0, 0, 0, buffer, &errorBuffer, 0);
if(FAILED(result)){
if(errorBuffer != 0){
OutputDebugStringA((char*)errorBuffer->GetBufferPointer());
errorBuffer->Release();
}
return false;
}
if(errorBuffer != 0){
errorBuffer->Release();
}
return true;
}
But what does happen is in the LoadContent function, the commented line (//<---) triggers an "E_INVALIDARG" result (in d3dResult), but the vsBuffer-> calls aren't returning null :/
bool AStarDemo::LoadContent(){
ID3D10Blob* vsBuffer = 0;
bool compileResult = CompileD3DShader("ReturnColor.hlsl", "VS_Main", "vs_5_0", &vsBuffer);
if(compileResult == false){
MessageBox(0, "Error loading vertex shader!", "Compile Error", MB_OK);
return false;
}
HRESULT d3dResult;
d3dResult = d3dDevice->CreateVertexShader(vsBuffer->GetBufferPointer(),
vsBuffer->GetBufferSize(), 0, &returnColorVS);
//actually set the vertex shader
d3dContext->VSSetShader(returnColorVS, 0, 0);
if(FAILED(d3dResult)){
if(vsBuffer){
vsBuffer->Release();
}
return false;
}
D3D11_INPUT_ELEMENT_DESC solidColorLayout[] ={
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }
};
unsigned int totalLayoutElements = ARRAYSIZE(solidColorLayout);
d3dResult = d3dDevice->CreateInputLayout(solidColorLayout, totalLayoutElements,
vsBuffer->GetBufferPointer(), vsBuffer->GetBufferSize(), &inputLayout);
vsBuffer->Release();
if(FAILED(d3dResult)){
return false;
}
ID3D10Blob* psBuffer = 0;
compileResult = CompileD3DShader("ReturnColor.hlsl", "PS_Main", "ps_5_0", &psBuffer);
//actually set the pixel shader
d3dContext->PSSetShader(returnColorPS, 0, 0);
if(compileResult == false){
MessageBox(0, "Error loading pixel shader!", "Compile Error", MB_OK);
return false;
}
d3dResult = d3dDevice->CreatePixelShader(psBuffer->GetBufferPointer(),
psBuffer->GetBufferSize(), 0, &returnColorPS);
psBuffer->Release();
if(FAILED(d3dResult)){
return false;
}
Vertex vertices[4 * TOTAL_NUMBER_GRID_SQUARES];
gridSquares = new GridSquare[TOTAL_NUMBER_GRID_SQUARES];
//for each grid square
for(int i = 0; i < TOTAL_NUMBER_GRID_SQUARES; i++){
XMFLOAT4 color = ((i%2) == 0) ? GREEN : RED;
//create a grid square object
GridSquare gs;
gs.TopLeft = Vertex( XMFLOAT3(0.5f * i, 0.5f * i, Z_LEVEL),
color);
gs.TopRight = Vertex( XMFLOAT3( 0.5f * i, -0.5f * i, Z_LEVEL),
color);
gs.BottomRight = Vertex( XMFLOAT3(-0.5f * i, -0.5f * i, Z_LEVEL),
color);
gs.BottomLeft = Vertex( XMFLOAT3(-0.5f * i, 0.5f * i, Z_LEVEL),
color);
gs.type = ((i%2) == 0) ? prey : hunter;
gridSquares[i] = gs;
vertices[4*i] = gs.TopLeft;
vertices[(4*i)+1] = gs.TopRight;
vertices[(4*i)+2] = gs.BottomRight;
vertices[(4*i)+3] = gs.BottomLeft;
}
D3D11_BUFFER_DESC vertexDesc;
ZeroMemory(&vertexDesc, sizeof(vertexDesc));
vertexDesc.Usage = D3D11_USAGE_DYNAMIC;
vertexDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vertexDesc.ByteWidth = 4 * TOTAL_NUMBER_GRID_SQUARES * sizeof(Vertex);
vertexDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
D3D11_SUBRESOURCE_DATA resourceData;
ZeroMemory(&resourceData, sizeof(resourceData));
resourceData.pSysMem = vertices;
d3dResult = d3dDevice->CreateBuffer(&vertexDesc, &resourceData, &vertexBuffer);
if(FAILED(d3dResult)){
return false;
}
return true;
}
Any advice would be greatly appreciated! :)
Found the answer after digging around a bit- apparently there are some problems with using "ps_5_0" and "vs_5_0", even though my machine runs DirectX 11