Skip to content

Instantly share code, notes, and snippets.

@lexmart
Created January 3, 2020 15:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lexmart/c8f2874d9ef024fec13b15739bccf5c7 to your computer and use it in GitHub Desktop.
Save lexmart/c8f2874d9ef024fec13b15739bccf5c7 to your computer and use it in GitHub Desktop.
#define assert(expr) if(!(expr)) { *((int *)0) = 0; }
#define invalidCodePath assert(false);
#define arrlen(arr) (sizeof(arr)/sizeof((arr)[0]))
#include "matrix.cpp"
#include <windows.h>
#include <d3d11.h>
#include <dxgi.h>
#include <stdint.h>
#include <d3dcompiler.h>
#pragma comment(lib, "d3dcompiler")
#pragma comment(lib, "D3D11")
#pragma comment(lib, "DXGI")
struct Dx11State
{
IDXGISwapChain *swapChain;
ID3D11Device *device;
ID3D11DeviceContext *deviceContext;
ID3D11RenderTargetView *renderTargetView;
};
struct Dx11VertexShader
{
ID3DBlob *buffer;
ID3D11VertexShader *shader;
};
struct Dx11PixelShader
{
ID3DBlob *buffer;
ID3D11PixelShader *shader;
};
struct Dx11VertexBuffer
{
};
LRESULT CALLBACK win32EventHandler(HWND hwnd,UINT uMsg, WPARAM wParam, LPARAM lParam)
{
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
HWND win32OpenWindow(HINSTANCE inst, int width, int height)
{
HWND result = 0;
WNDCLASSEX wndClass = {};
wndClass.cbSize = sizeof(WNDCLASSEX);
wndClass.style = 0;
wndClass.lpfnWndProc = win32EventHandler;
wndClass.hInstance = inst;
wndClass.lpszClassName = "anim test";
if (RegisterClassEx(&wndClass))
{
result = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW, wndClass.lpszClassName, "anim test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, width, height, 0, 0, inst, 0);
}
return result;
}
Dx11State dxxInit(int width, int height, HWND window)
{
D3D_FEATURE_LEVEL featureLevels[] =
{
D3D_FEATURE_LEVEL_11_1,
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0,
D3D_FEATURE_LEVEL_9_3,
D3D_FEATURE_LEVEL_9_2,
D3D_FEATURE_LEVEL_9_1
};
DXGI_SWAP_CHAIN_DESC swapChainDesc = {};
swapChainDesc.BufferDesc.Width = width;
swapChainDesc.BufferDesc.Height = height;
swapChainDesc.BufferDesc.RefreshRate.Numerator = 60;
swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_CENTERED;
swapChainDesc.SampleDesc.Count = 1;
swapChainDesc.SampleDesc.Quality = 0;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.BufferCount = 2;
swapChainDesc.OutputWindow = window;
swapChainDesc.Windowed = TRUE;
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
Dx11State dx11 = {};
HRESULT result = D3D11CreateDeviceAndSwapChain(0, D3D_DRIVER_TYPE_HARDWARE, 0, D3D11_CREATE_DEVICE_BGRA_SUPPORT | D3D11_CREATE_DEVICE_DEBUG, featureLevels, 7, D3D11_SDK_VERSION,
&swapChainDesc, &dx11.swapChain, &dx11.device, 0, &dx11.deviceContext);
assert(!FAILED(result));
// create render target
ID3D11Texture2D *backBuffer = 0;
dx11.swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void **)& backBuffer);
dx11.device->CreateRenderTargetView(backBuffer, 0, &dx11.renderTargetView);
// viewport settings
D3D11_VIEWPORT viewport = {};
viewport.Width = (float)width;
viewport.Height = (float)height;
viewport.MinDepth = 0.0f;
viewport.MaxDepth = 1.0f;
viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
dx11.deviceContext->RSSetViewports(1, &viewport);
// rasterizer settings
ID3D11RasterizerState *rasterizer;
D3D11_RASTERIZER_DESC rasterizerDesc;
rasterizerDesc.FillMode = D3D11_FILL_SOLID;
rasterizerDesc.CullMode = D3D11_CULL_FRONT;
rasterizerDesc.FrontCounterClockwise = false;
rasterizerDesc.DepthBias = false;
rasterizerDesc.DepthBiasClamp = 0;
rasterizerDesc.SlopeScaledDepthBias = 0;
rasterizerDesc.DepthClipEnable = true;
rasterizerDesc.ScissorEnable = false;
rasterizerDesc.MultisampleEnable = false;
rasterizerDesc.AntialiasedLineEnable = false;
dx11.device->CreateRasterizerState(&rasterizerDesc, &rasterizer);
dx11.deviceContext->RSSetState(rasterizer);
return dx11;
}
Dx11VertexShader createVertexShader(Dx11State dx11, char *src, int srcBytes)
{
Dx11VertexShader vs = {};
ID3DBlob *vsErrorBuffer = 0;
HRESULT result = D3DCompile(src, srcBytes, "vs", 0, 0, "main", "vs_5_0", (1 << 0) | (1 << 11), 0, &vs.buffer, &vsErrorBuffer);
if (vsErrorBuffer != 0)
{
OutputDebugString((char *)vsErrorBuffer->GetBufferPointer());
invalidCodePath;
}
assert(!FAILED(result));
result = dx11.device->CreateVertexShader(vs.buffer->GetBufferPointer(), vs.buffer->GetBufferSize(), 0, &vs.shader);
assert(!FAILED(result));
return vs;
}
Dx11PixelShader createPixelShader(Dx11State dx11, char *src, int srcBytes)
{
Dx11PixelShader ps = {};
ID3DBlob *psErrorBuffer = 0;
HRESULT result = D3DCompile(src, srcBytes, "ps", 0, 0, "main", "ps_5_0", (1 << 0) | (1 << 11), 0, &ps.buffer, &psErrorBuffer);
if (psErrorBuffer != 0)
{
OutputDebugString((char *)psErrorBuffer->GetBufferPointer());
invalidCodePath;
}
assert(!FAILED(result));
result = dx11.device->CreatePixelShader(ps.buffer->GetBufferPointer(), ps.buffer->GetBufferSize(), 0, &ps.shader);
assert(!FAILED(result));
return ps;
}
ID3D11Buffer *createVertexBuffer(Dx11State dx11, float data[], int bytes)
{
D3D11_BUFFER_DESC bufferDesc = {};
bufferDesc.Usage = D3D11_USAGE_DEFAULT;
bufferDesc.ByteWidth = bytes;
bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bufferDesc.CPUAccessFlags = 0;
bufferDesc.MiscFlags = 0;
D3D11_SUBRESOURCE_DATA bufferResource = {};
bufferResource.pSysMem = data;
ID3D11Buffer *vertexBuffer = 0;
HRESULT result = dx11.device->CreateBuffer(&bufferDesc, &bufferResource, &vertexBuffer);
assert(!FAILED(result));
return vertexBuffer;
}
ID3D11InputLayout *createInputLayout(Dx11State dx11, D3D11_INPUT_ELEMENT_DESC *inputLayoutData, int n, Dx11VertexShader vs)
{
ID3D11InputLayout *layout = 0;
HRESULT result = dx11.device->CreateInputLayout(inputLayoutData, n, (void *)vs.buffer->GetBufferPointer(), vs.buffer->GetBufferSize(), &layout);
assert(!FAILED(result));
return layout;
}
char vertexShaderCode[] = R"STR(
struct VertexShaderInput
{
float3 pos : POSITION;
float3 color : COLOR;
};
struct VertexShaderOuput
{
float4 pos : SV_POSITION;
float3 color : COLOR;
};
VertexShaderOuput main(VertexShaderInput input)
{
VertexShaderOuput output;
output.pos = float4(input.pos, 1.0f);
output.color = input.color;
return output;
}
)STR";
char pixelShaderCode[] = R"STR(
struct PixelShaderInput
{
float4 pos : SV_POSITION;
float3 color : COLOR;
};
float3 main(PixelShaderInput input) : SV_TARGET
{
return input.color;
};
)STR";
int WinMain(HINSTANCE inst, HINSTANCE prevInst, char *cmdLine, int cmdShow)
{
testMatrixMath();
int width = 800;
int height = 600;
HWND window = win32OpenWindow(inst, width, height);
if(window)
{
Dx11State dx11 = dxxInit(width, height, window);
Dx11VertexShader vs = createVertexShader(dx11, vertexShaderCode, sizeof(vertexShaderCode));
Dx11PixelShader ps = createPixelShader(dx11, pixelShaderCode, sizeof(pixelShaderCode));
// create vertex buffer
float triangle[] =
{
0.0f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f
};
uint32_t vertexBufferStride = 24;
ID3D11Buffer *triangleVertexBuffer = createVertexBuffer(dx11, triangle, sizeof(triangle));
// create vertex buffer laoyout
D3D11_INPUT_ELEMENT_DESC inputLayoutData[] =
{
{"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}
};
ID3D11InputLayout *inputLayout = createInputLayout(dx11, inputLayoutData, arrlen(inputLayoutData), vs);
float clearColor[] = { 0.0f, 0.0f, 0.0f, 0.0f };
while (1)
{
dx11.deviceContext->OMSetRenderTargets(1, &dx11.renderTargetView, 0);
// clear the back buffer
//clearColor[0] -= 1.0f / 300.0f;
dx11.deviceContext->ClearRenderTargetView(dx11.renderTargetView, clearColor);
// setup IA
uint32_t zero = 0;
dx11.deviceContext->IASetVertexBuffers(0, 1, &triangleVertexBuffer, &vertexBufferStride, &zero);
dx11.deviceContext->IASetInputLayout(inputLayout);
dx11.deviceContext->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
// setup VS
dx11.deviceContext->VSSetShader(vs.shader, 0, 0);
// setup PS
//deviceContext->RSSetState(rasterizer);
dx11.deviceContext->PSSetShader(ps.shader, 0, 0);
dx11.deviceContext->Draw(3, 0);
dx11.swapChain->Present(1, 0);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment