Skip to content

Instantly share code, notes, and snippets.

@d7samurai
Last active July 2, 2018 14:34
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 d7samurai/c93e8aac22ef3ec77fea03be0ce86f51 to your computer and use it in GitHub Desktop.
Save d7samurai/c93e8aac22ef3ec77fea03be0ce86f51 to your computer and use it in GitHub Desktop.
#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);
}
struct vertex
{
float4 pos : SV_POSITION;
float4 col : COL;
};
float4 main(vertex input) : SV_TARGET
{
return input.col;
}
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