Created
January 3, 2020 15:38
-
-
Save lexmart/c8f2874d9ef024fec13b15739bccf5c7 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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