-
-
Save d7samurai/c93e8aac22ef3ec77fea03be0ce86f51 to your computer and use it in GitHub Desktop.
This file contains 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
#pragma comment(lib, "d3d11") | |
#include <windows.h> | |
#include <d3d11_1.h> | |
/////////////////////////////////////////////////////////////////////////////////////////////////// | |
#define TITLE "d7's quick'n'dirty d3d11 framework" | |
/////////////////////////////////////////////////////////////////////////////////////////////////// | |
struct Constants | |
{ | |
float ViewportWidth, ViewportHeight; | |
}; | |
struct Vertex | |
{ | |
float X, Y; | |
unsigned int Color; | |
}; | |
/////////////////////////////////////////////////////////////////////////////////////////////////// | |
HWND Window; | |
IDXGISwapChain1* SwapChain; | |
ID3D11Device1* Device; | |
ID3D11DeviceContext1* DeviceContext; | |
ID3D11RenderTargetView* RenderTargetView; | |
ID3D11VertexShader* VertexShader; | |
ID3D11PixelShader* PixelShader; | |
ID3D11RasterizerState1* RasterizerState; | |
ID3D11BlendState1* BlendState; | |
ID3D11Buffer* ConstantBuffer; | |
ID3D11Buffer* VertexBuffer; | |
ID3D11ShaderResourceView* VertexBufferView; | |
Vertex VertexArray[1024]; | |
int VertexCount; | |
UINT ViewportWidth; | |
UINT ViewportHeight; | |
/////////////////////////////////////////////////////////////////////////////////////////////////// | |
void LoadFile(char* filename, void** buffer, int* size); | |
/////////////////////////////////////////////////////////////////////////////////////////////////// | |
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) | |
{ | |
switch (uMsg) | |
{ | |
case WM_SIZE: | |
{ | |
ViewportWidth = LOWORD(lParam); | |
ViewportHeight = HIWORD(lParam); | |
/////////////////////////////////////////////////////////////////////////////////// | |
D3D11_MAPPED_SUBRESOURCE mappedSubresource; | |
DeviceContext->Map(ConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedSubresource); | |
Constants* constants = reinterpret_cast<Constants*>(mappedSubresource.pData); | |
constants->ViewportWidth = static_cast<float>(ViewportWidth); | |
constants->ViewportHeight = static_cast<float>(ViewportHeight); | |
DeviceContext->Unmap(ConstantBuffer, 0); | |
/////////////////////////////////////////////////////////////////////////////////// | |
RenderTargetView->Release(); | |
SwapChain->ResizeBuffers(0, 0, 0, DXGI_FORMAT_UNKNOWN, 0); | |
ID3D11Texture2D* renderTarget; | |
SwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast<void**>(&renderTarget)); | |
Device->CreateRenderTargetView(renderTarget, nullptr, &RenderTargetView); | |
renderTarget->Release(); | |
} | |
return 0; | |
case WM_DESTROY: | |
PostQuitMessage(0); | |
return 0; | |
} | |
return DefWindowProc(hWnd, uMsg, wParam, lParam); | |
} | |
/////////////////////////////////////////////////////////////////////////////////////////////////// | |
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) | |
{ | |
WNDCLASSEX wndClassEx = { sizeof(wndClassEx) }; | |
wndClassEx.lpfnWndProc = WndProc; | |
wndClassEx.lpszClassName = TITLE; | |
RegisterClassEx(&wndClassEx); | |
Window = CreateWindowEx(0, TITLE, TITLE, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, nullptr, nullptr, nullptr, nullptr); | |
/////////////////////////////////////////////////////////////////////////////////////////////// | |
D3D_FEATURE_LEVEL featureLevel; | |
D3D_FEATURE_LEVEL featureLevels[] = | |
{ | |
D3D_FEATURE_LEVEL_11_0, | |
D3D_FEATURE_LEVEL_10_1, | |
D3D_FEATURE_LEVEL_10_0, | |
}; | |
ID3D11Device* device; | |
ID3D11DeviceContext* deviceContext; | |
D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, D3D11_CREATE_DEVICE_BGRA_SUPPORT, featureLevels, _ARRAYSIZE(featureLevels), D3D11_SDK_VERSION, &device, &featureLevel, &deviceContext); | |
device->QueryInterface(__uuidof(ID3D11Device1), reinterpret_cast<void**>(&Device)); | |
deviceContext->QueryInterface(__uuidof(ID3D11DeviceContext1), reinterpret_cast<void**>(&DeviceContext)); | |
/////////////////////////////////////////////////////////////////////////////////////////////// | |
IDXGIDevice1* dxgiDevice; | |
Device->QueryInterface(__uuidof(IDXGIDevice1), reinterpret_cast<void**>(&dxgiDevice)); | |
IDXGIAdapter* dxgiAdapter; | |
IDXGIFactory2* dxgiFactory; | |
dxgiDevice->GetAdapter(&dxgiAdapter); | |
dxgiAdapter->GetParent(__uuidof(IDXGIFactory2), reinterpret_cast<void**>(&dxgiFactory)); | |
DXGI_SWAP_CHAIN_DESC1 swapChainDesc; | |
swapChainDesc.Width = 0; // use window width | |
swapChainDesc.Height = 0; // use window height | |
swapChainDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; | |
swapChainDesc.Stereo = FALSE; | |
swapChainDesc.SampleDesc.Count = 1; | |
swapChainDesc.SampleDesc.Quality = 0; | |
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; | |
swapChainDesc.BufferCount = 2; | |
swapChainDesc.Scaling = DXGI_SCALING_STRETCH; | |
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; | |
swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED; | |
swapChainDesc.Flags = 0; | |
dxgiFactory->CreateSwapChainForHwnd(Device, Window, &swapChainDesc, nullptr, nullptr, &SwapChain); | |
/////////////////////////////////////////////////////////////////////////////////////////////// | |
D3D11_RENDER_TARGET_VIEW_DESC renderTargetViewDesc = {}; // only need this if rendertargetview format differs from swapchain format | |
renderTargetViewDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM_SRGB; | |
renderTargetViewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; | |
ID3D11Texture2D* backbuffer; | |
SwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast<void**>(&backbuffer)); | |
Device->CreateRenderTargetView(backbuffer, &renderTargetViewDesc, &RenderTargetView); | |
backbuffer->Release(); | |
/////////////////////////////////////////////////////////////////////////////////////////////// | |
void* buffer[2]; | |
int size [2]; | |
LoadFile("vs.cso", &buffer[0], &size[0]); | |
LoadFile("ps.cso", &buffer[1], &size[1]); | |
Device->CreateVertexShader(buffer[0], size[0], nullptr, &VertexShader); | |
Device->CreatePixelShader (buffer[1], size[1], nullptr, &PixelShader); | |
free(buffer[0]); | |
free(buffer[1]); | |
/////////////////////////////////////////////////////////////////////////////////////////////// | |
D3D11_BUFFER_DESC constantBufferDesc; | |
constantBufferDesc.ByteWidth = static_cast<UINT>(sizeof(Constants) + 15) & 0xfffffff0; // quantize to 16 bytes | |
constantBufferDesc.Usage = D3D11_USAGE_DYNAMIC; | |
constantBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; | |
constantBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; | |
constantBufferDesc.MiscFlags = 0; | |
constantBufferDesc.StructureByteStride = 0; | |
Device->CreateBuffer(&constantBufferDesc, nullptr, &ConstantBuffer); | |
/////////////////////////////////////////////////////////////////////////////////////////////// | |
D3D11_BUFFER_DESC vertexBufferDesc; | |
vertexBufferDesc.ByteWidth = static_cast<UINT>(sizeof(VertexArray)); | |
vertexBufferDesc.Usage = D3D11_USAGE_DYNAMIC; | |
vertexBufferDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; | |
vertexBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; | |
vertexBufferDesc.MiscFlags = 0; | |
vertexBufferDesc.StructureByteStride = 0; | |
Device->CreateBuffer(&vertexBufferDesc, nullptr, &VertexBuffer); | |
D3D11_SHADER_RESOURCE_VIEW_DESC vertexBufferViewDesc = {}; | |
vertexBufferViewDesc.Format = DXGI_FORMAT_R32G32B32_FLOAT; | |
vertexBufferViewDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; | |
vertexBufferViewDesc.Buffer.FirstElement = 0; | |
vertexBufferViewDesc.Buffer.NumElements = _ARRAYSIZE(VertexArray); | |
Device->CreateShaderResourceView(VertexBuffer, &vertexBufferViewDesc, &VertexBufferView); | |
/////////////////////////////////////////////////////////////////////////////////////////////// | |
D3D11_RASTERIZER_DESC1 rasterizerDesc; | |
rasterizerDesc.FillMode = D3D11_FILL_SOLID; | |
rasterizerDesc.CullMode = D3D11_CULL_NONE; | |
rasterizerDesc.FrontCounterClockwise = FALSE; | |
rasterizerDesc.DepthBias = 0; | |
rasterizerDesc.DepthBiasClamp = 0.0f; | |
rasterizerDesc.SlopeScaledDepthBias = 0.0f; | |
rasterizerDesc.DepthClipEnable = FALSE; | |
rasterizerDesc.ScissorEnable = FALSE; | |
rasterizerDesc.MultisampleEnable = FALSE; | |
rasterizerDesc.AntialiasedLineEnable = FALSE; | |
rasterizerDesc.ForcedSampleCount = 0; | |
Device->CreateRasterizerState1(&rasterizerDesc, &RasterizerState); | |
/////////////////////////////////////////////////////////////////////////////////////////////// | |
D3D11_BLEND_DESC1 blendDescription; | |
blendDescription.AlphaToCoverageEnable = FALSE; | |
blendDescription.IndependentBlendEnable = FALSE; | |
blendDescription.RenderTarget[0].BlendEnable = TRUE; | |
blendDescription.RenderTarget[0].LogicOpEnable = FALSE; | |
blendDescription.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; | |
blendDescription.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; | |
blendDescription.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; | |
blendDescription.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; | |
blendDescription.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; | |
blendDescription.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; | |
blendDescription.RenderTarget[0].LogicOp = D3D11_LOGIC_OP_NOOP; | |
blendDescription.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; | |
Device->CreateBlendState1(&blendDescription, &BlendState); | |
/////////////////////////////////////////////////////////////////////////////////////////////// | |
int frame = 0; | |
while (true) | |
{ | |
MSG msg; | |
while (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) | |
{ | |
if (msg.message == WM_QUIT) | |
{ | |
return 0; | |
} | |
DispatchMessage(&msg); | |
} | |
/////////////////////////////////////////////////////////////////////////////////////////// | |
float centerX = static_cast<float>(ViewportWidth) / 2.0f; | |
float centerY = static_cast<float>(ViewportHeight) / 2.0f; | |
VertexCount = 0; | |
VertexArray[VertexCount++] = { centerX - 250.0f, centerY - 0.0f, 0xffff0000 }; | |
VertexArray[VertexCount++] = { centerX + 125.0f, centerY - 216.5f, 0xff00ff00 }; | |
VertexArray[VertexCount++] = { centerX + 125.0f, centerY + 216.5f, 0xff0000ff }; | |
/////////////////////////////////////////////////////////////////////////////////////////// | |
D3D11_MAPPED_SUBRESOURCE mappedSubresource; | |
DeviceContext->Map(VertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedSubresource); | |
memcpy(mappedSubresource.pData, VertexArray, VertexCount * sizeof(Vertex)); | |
DeviceContext->Unmap(VertexBuffer, 0); | |
/////////////////////////////////////////////////////////////////////////////////////////// | |
FLOAT color[] = { 0.1f, 0.1f, 0.1f, 1.0f }; | |
DeviceContext->ClearRenderTargetView(RenderTargetView, color); | |
/////////////////////////////////////////////////////////////////////////////////////////////// | |
D3D11_VIEWPORT viewport = { 0.0f, 0.0f, static_cast<float>(ViewportWidth), static_cast<float>(ViewportHeight), 0.0f, 1.0f }; | |
/////////////////////////////////////////////////////////////////////////////////////////////// | |
DeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); | |
DeviceContext->VSSetShader(VertexShader, nullptr, 0); | |
DeviceContext->VSSetConstantBuffers(0, 1, &ConstantBuffer); | |
DeviceContext->VSSetShaderResources(0, 1, &VertexBufferView); | |
DeviceContext->RSSetViewports(1, &viewport); | |
DeviceContext->RSSetState(RasterizerState); | |
DeviceContext->PSSetShader(PixelShader, nullptr, 0); | |
DeviceContext->OMSetBlendState(BlendState, nullptr, 0xffffffff); | |
DeviceContext->OMSetRenderTargets(1, &RenderTargetView, nullptr); | |
/////////////////////////////////////////////////////////////////////////////////////////// | |
DeviceContext->Draw(VertexCount, 0); | |
/////////////////////////////////////////////////////////////////////////////////////////// | |
DXGI_PRESENT_PARAMETERS presentParameters = {}; | |
SwapChain->Present1(1, 0, &presentParameters); | |
/////////////////////////////////////////////////////////////////////////////////////////// | |
if (!frame++) | |
{ | |
ShowWindow(Window, SW_SHOW); | |
} | |
} | |
} | |
/////////////////////////////////////////////////////////////////////////////////////////////////// | |
void LoadFile(char* filename, void** buffer, int* size) | |
{ | |
HANDLE fileHandle = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); | |
LARGE_INTEGER fileSize; | |
GetFileSizeEx(fileHandle, &fileSize); | |
*size = static_cast<int>(fileSize.QuadPart); | |
*buffer = malloc(*size); | |
DWORD bytesRead; | |
ReadFile(fileHandle, *buffer, *size, &bytesRead, nullptr); | |
CloseHandle(fileHandle); | |
} |
This file contains 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
struct vertex | |
{ | |
float4 pos : SV_POSITION; | |
float4 col : COL; | |
}; | |
float4 main(vertex input) : SV_TARGET | |
{ | |
return input.col; | |
} |
This file contains 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
cbuffer constants : register(b0) | |
{ | |
float2 viewport_size; | |
} | |
Buffer<float3> verts : register(t0); | |
struct vertex | |
{ | |
float4 pos : SV_POSITION; | |
float4 col : COL; | |
}; | |
vertex main(uint vertex_id : SV_VERTEXID) | |
{ | |
float3 vert = verts[vertex_id]; | |
vertex output; | |
output.pos = float4(vert.xy * float2(2.0f, -2.0f) / viewport_size - float2(1.0f, -1.0f), 0.0f, 1.0f); | |
output.col = float4(asuint(vert.z) >> uint4(16, 8, 0, 24) & 0xff) / 255.0f; | |
return output; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment