Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define zero {}
- #define func static
- #define global static
- #define null nullptr
- #define array_count(arr) (sizeof(arr) / sizeof(arr[0]))
- #define assert(cond) if(!(cond)) { on_failed_assert(__LINE__); }
- #define COBJMACROS
- #define WIN32_LEAN_AND_MEAN
- #include <Windows.h>
- #include <d3d11.h>
- #include <dxgi1_3.h>
- #include <d3dcompiler.h>
- #ifdef m_debug
- #include <dxgidebug.h>
- #endif // m_debug
- #include <stdint.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <math.h>
- typedef uint64_t u64;
- typedef double f64;
- #include "main.h"
- // vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv globals start vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
- global u64 g_cycle_frequency;
- global u64 g_start_cycles;
- global s_sarray<s_transform, 65536> g_transform_arr;
- // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ globals end ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- LRESULT window_proc(HWND window, UINT msg, WPARAM wparam, LPARAM lparam)
- {
- LRESULT result = 0;
- switch(msg) {
- case WM_CLOSE:
- case WM_DESTROY:
- {
- PostQuitMessage(0);
- } break;
- default: {
- result = DefWindowProc(window, msg, wparam, lparam);
- }
- }
- return result;
- }
- int main()
- {
- HRESULT hr = 0;
- char* class_name = "azenris_class";
- HINSTANCE instance = GetModuleHandle(null);
- ID3D11RenderTargetView* rtView = null;
- ID3D11DepthStencilView* dsView = null;
- ID3D11DeviceContext* context = null;
- IDXGISwapChain1* swap_chain = null;
- ID3D11Device* device = null;
- ID3D11InputLayout* layout;
- ID3D11Buffer* vbuffer0 = null;
- ID3D11Buffer* vbuffer1 = null;
- ID3D11VertexShader* vshader;
- ID3D11PixelShader* pshader;
- ID3D11RasterizerState* rasterizerState;
- ID3D11SamplerState* sampler;
- ID3D11BlendState* blendState;
- ID3D11DepthStencilState* depthState;
- ID3D11Buffer* ubuffer;
- WNDCLASSEX window_class = zero;
- window_class.cbSize = sizeof(window_class);
- window_class.lpfnWndProc = window_proc;
- window_class.hInstance = instance;
- window_class.lpszClassName = class_name;
- RegisterClassEx(&window_class);
- HWND window = CreateWindowEx(
- WS_EX_APPWINDOW | WS_EX_NOREDIRECTIONBITMAP, class_name, "D3D11", WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
- null, null, instance, null
- );
- // vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv d3d11 start vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
- {
- {
- int flags = 0;
- #ifdef m_debug
- flags |= D3D11_CREATE_DEVICE_DEBUG;
- #endif // m_debug
- D3D_FEATURE_LEVEL level_arr[] = {D3D_FEATURE_LEVEL_11_0};
- HRESULT result = D3D11CreateDevice(null, D3D_DRIVER_TYPE_HARDWARE, null,
- flags, level_arr,
- array_count(level_arr), D3D11_SDK_VERSION, &device, null, &context
- );
- }
- {
- #ifdef m_debug
- ID3D11InfoQueue* info = null;
- device->QueryInterface(__uuidof(ID3D11InfoQueue), (void**)&info);
- info->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_CORRUPTION, TRUE);
- info->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_ERROR, TRUE);
- info->Release();
- #endif // m_debug
- }
- {
- #ifdef m_debug
- IDXGIInfoQueue* dxgi_info;
- DXGIGetDebugInterface1(0, IID_IDXGIInfoQueue, (void**)&dxgi_info);
- dxgi_info->SetBreakOnSeverity(DXGI_DEBUG_ALL, DXGI_INFO_QUEUE_MESSAGE_SEVERITY_CORRUPTION, TRUE);
- dxgi_info->SetBreakOnSeverity(DXGI_DEBUG_ALL, DXGI_INFO_QUEUE_MESSAGE_SEVERITY_ERROR, TRUE);
- dxgi_info->Release();
- #endif // m_debug
- }
- {
- IDXGIDevice* dxgi_device = null;
- device->QueryInterface(IID_IDXGIDevice, (void**)&dxgi_device);
- IDXGIAdapter* dxgi_adapter;
- dxgi_device->GetAdapter(&dxgi_adapter);
- IDXGIFactory2* factory = null;
- dxgi_adapter->GetParent(IID_IDXGIFactory2, (void**)&factory);
- DXGI_SWAP_CHAIN_DESC1 desc = {
- // default 0 value for width & height means to get it from HWND automatically
- //.Width = 0,
- //.Height = 0,
- // or use DXGI_FORMAT_R8G8B8A8_UNORM_SRGB for storing sRGB
- .Format = DXGI_FORMAT_R8G8B8A8_UNORM,
- // FLIP presentation model does not allow MSAA framebuffer
- // if you want MSAA then you'll need to render offscreen and manually
- // resolve to non-MSAA framebuffer
- .SampleDesc = { 1, 0 },
- .BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT,
- .BufferCount = 2,
- // we don't want any automatic scaling of window content
- // this is supported only on FLIP presentation model
- .Scaling = DXGI_SCALING_NONE,
- // use more efficient FLIP presentation model
- // Windows 10 allows to use DXGI_SWAP_EFFECT_FLIP_DISCARD
- // for Windows 8 compatibility use DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL
- // for Windows 7 compatibility use DXGI_SWAP_EFFECT_DISCARD
- .SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD,
- };
- factory->CreateSwapChainForHwnd((IUnknown*)device, window, &desc, null, null, &swap_chain);
- // disable silly Alt+Enter changing monitor resolution to match window size
- factory->MakeWindowAssociation(window, DXGI_MWA_NO_ALT_ENTER);
- factory->Release();
- dxgi_adapter->Release();
- dxgi_device->Release();
- }
- {
- constexpr float c_size = 0.5f;
- s_vertex data0[] = {
- {{-c_size, c_size}, {0, 0}, {1, 1, 1}},
- {{c_size, c_size}, {1, 0}, {1, 1, 1}},
- {{c_size, -c_size}, {1, 1}, {1, 1, 1}},
- {{-c_size, c_size}, {0, 0}, {1, 1, 1}},
- {{c_size, -c_size}, {1, 1}, {1, 1, 1}},
- {{-c_size, -c_size}, {0, 1}, {1, 1, 1}},
- };
- D3D11_BUFFER_DESC desc = {
- .ByteWidth = sizeof(data0),
- .Usage = D3D11_USAGE_IMMUTABLE,
- .BindFlags = D3D11_BIND_VERTEX_BUFFER,
- };
- D3D11_SUBRESOURCE_DATA initial = {.pSysMem = data0};
- device->CreateBuffer(&desc, &initial, &vbuffer0);
- }
- {
- D3D11_BUFFER_DESC desc = {
- .ByteWidth = sizeof(g_transform_arr.element_arr),
- .Usage = D3D11_USAGE_DYNAMIC,
- .BindFlags = D3D11_BIND_VERTEX_BUFFER,
- .CPUAccessFlags = D3D11_CPU_ACCESS_WRITE,
- };
- device->CreateBuffer(&desc, null, &vbuffer1);
- assert(vbuffer1);
- }
- D3D11_INPUT_ELEMENT_DESC desc[] = {
- {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(s_vertex, pos), D3D11_INPUT_PER_VERTEX_DATA, 0 },
- {"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(s_vertex, uv), D3D11_INPUT_PER_VERTEX_DATA, 0 },
- {"COLOR", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, offsetof(s_vertex, color), D3D11_INPUT_PER_VERTEX_DATA, 0 },
- {"AZEN_POS", 0, DXGI_FORMAT_R32G32_FLOAT, 1, offsetof(s_transform, pos), D3D11_INPUT_PER_INSTANCE_DATA, 1 },
- {"AZEN_SIZE", 0, DXGI_FORMAT_R32G32_FLOAT, 1, offsetof(s_transform, size), D3D11_INPUT_PER_INSTANCE_DATA, 1 },
- };
- const char hlsl[] =
- "#line 194 \n\n" // actual line number in this file for nicer error messages
- " \n"
- "struct VS_INPUT \n"
- "{ \n"
- " float2 pos : POSITION; \n" // these names must match D3D11_INPUT_ELEMENT_DESC array
- " float2 uv : TEXCOORD; \n"
- " float3 color : COLOR; \n"
- " float2 pos2 : AZEN_POS; \n"
- " float2 size2 : AZEN_SIZE; \n"
- "}; \n"
- " \n"
- "struct PS_INPUT \n"
- "{ \n"
- " float4 pos : SV_POSITION; \n" // these names do not matter, except SV_... ones
- " float2 uv : TEXCOORD; \n"
- " float4 color : COLOR; \n"
- "}; \n"
- " \n"
- "cbuffer cbuffer0 : register(b0) \n" // b0 = constant buffer bound to slot 0
- "{ \n"
- " float4x4 u_transform; \n"
- "} \n"
- " \n"
- " \n"
- "PS_INPUT vs(VS_INPUT input) \n"
- "{ \n"
- " PS_INPUT output; \n"
- " output.pos = mul(u_transform, float4(input.pos * input.size2 + input.pos2, 0, 1)); \n"
- " output.uv = input.uv; \n"
- " output.color = float4(input.color, 1); \n"
- " return output; \n"
- "} \n"
- " \n"
- "float4 ps(PS_INPUT input) : SV_TARGET \n"
- "{ \n"
- " float4 color = float4(input.uv.x, input.uv.y, 0.0, 1.0); \n"
- " return input.color * color; \n"
- "} \n";
- ;
- UINT flags = D3DCOMPILE_PACK_MATRIX_COLUMN_MAJOR | D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_WARNINGS_ARE_ERRORS;
- #ifdef m_debug
- flags |= D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION;
- #endif // m_debug
- ID3DBlob* error;
- ID3DBlob* vblob;
- hr = D3DCompile(hlsl, sizeof(hlsl), null, null, null, "vs", "vs_5_0", flags, 0, &vblob, &error);
- if(FAILED(hr)) {
- const char* message = (char*)error->GetBufferPointer();
- printf("%s\n", message);
- assert(!"Failed to compile vertex shader!");
- }
- ID3DBlob* pblob;
- hr = D3DCompile(hlsl, sizeof(hlsl), null, null, null, "ps", "ps_5_0", flags, 0, &pblob, &error);
- if(FAILED(hr)) {
- const char* message = (char*)error->GetBufferPointer();
- printf("%s\n", message);
- assert(!"Failed to compile pixel shader!");
- }
- device->CreateVertexShader(vblob->GetBufferPointer(), vblob->GetBufferSize(), null, &vshader);
- device->CreatePixelShader(pblob->GetBufferPointer(), pblob->GetBufferSize(), null, &pshader);
- device->CreateInputLayout(desc, array_count(desc), vblob->GetBufferPointer(), vblob->GetBufferSize(), &layout);
- pblob->Release();
- vblob->Release();
- {
- D3D11_BUFFER_DESC desc =
- {
- // space for 4x4 float matrix (cbuffer0 from pixel shader)
- .ByteWidth = 4 * 4 * sizeof(float),
- .Usage = D3D11_USAGE_DYNAMIC,
- .BindFlags = D3D11_BIND_CONSTANT_BUFFER,
- .CPUAccessFlags = D3D11_CPU_ACCESS_WRITE,
- };
- device->CreateBuffer(&desc, NULL, &ubuffer);
- }
- {
- D3D11_SAMPLER_DESC desc = {
- .Filter = D3D11_FILTER_MIN_MAG_MIP_POINT,
- .AddressU = D3D11_TEXTURE_ADDRESS_WRAP,
- .AddressV = D3D11_TEXTURE_ADDRESS_WRAP,
- .AddressW = D3D11_TEXTURE_ADDRESS_WRAP,
- .MipLODBias = 0,
- .MaxAnisotropy = 1,
- .MinLOD = 0,
- .MaxLOD = D3D11_FLOAT32_MAX,
- };
- device->CreateSamplerState(&desc, &sampler);
- }
- {
- // enable alpha blending
- D3D11_BLEND_DESC desc = {
- .RenderTarget = {{
- .BlendEnable = TRUE,
- .SrcBlend = D3D11_BLEND_SRC_ALPHA,
- .DestBlend = D3D11_BLEND_INV_SRC_ALPHA,
- .BlendOp = D3D11_BLEND_OP_ADD,
- .SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA,
- .DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA,
- .BlendOpAlpha = D3D11_BLEND_OP_ADD,
- .RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL,
- }},
- };
- device->CreateBlendState(&desc, &blendState);
- }
- {
- // disable culling
- D3D11_RASTERIZER_DESC desc = {
- .FillMode = D3D11_FILL_SOLID,
- .CullMode = D3D11_CULL_NONE,
- .DepthClipEnable = TRUE,
- };
- device->CreateRasterizerState(&desc, &rasterizerState);
- }
- {
- // disable depth & stencil test
- D3D11_DEPTH_STENCIL_DESC desc =
- {
- .DepthEnable = FALSE,
- .DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL,
- .DepthFunc = D3D11_COMPARISON_LESS,
- .StencilEnable = FALSE,
- .StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK,
- .StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK,
- // .FrontFace = ...
- // .BackFace = ...
- };
- device->CreateDepthStencilState(&desc, &depthState);
- }
- }
- // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ d3d11 end ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- QueryPerformanceFrequency((LARGE_INTEGER*)&g_cycle_frequency);
- QueryPerformanceCounter((LARGE_INTEGER*)&g_start_cycles);
- DWORD curr_width = 0;
- DWORD curr_height = 0;
- MSG msg = zero;
- u64 before = get_cycles();
- while(true) {
- u64 after = get_cycles();
- u64 passed_cycles = after - before;
- f64 passed_seconds = passed_cycles / (f64)g_cycle_frequency;
- before = after;
- float delta = (float)passed_seconds;
- printf("FPS: %f\n", 1.0 / delta);
- while(PeekMessage(&msg, null, 0, 0, PM_REMOVE) > 0) {
- if(msg.message == WM_QUIT) {
- return 0;
- }
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- RECT rect;
- GetClientRect(window, &rect);
- UINT width = rect.right - rect.left;
- UINT height = rect.bottom - rect.top;
- if(rtView == NULL || width != curr_width || height != curr_height) {
- if(rtView) {
- // release old swap chain buffers
- context->ClearState();
- rtView->Release();
- dsView->Release();
- rtView = null;
- }
- // resize to new size for non-zero size
- if(width != 0 && height != 0) {
- hr = swap_chain->ResizeBuffers(0, width, height, DXGI_FORMAT_UNKNOWN, 0);
- if(FAILED(hr)) {
- printf("Failed to resize swap chain!");
- assert(false);
- }
- // create RenderTarget view for new backbuffer texture
- ID3D11Texture2D* backbuffer;
- swap_chain->GetBuffer(0, IID_ID3D11Texture2D, (void**)&backbuffer);
- device->CreateRenderTargetView((ID3D11Resource*)backbuffer, null, &rtView);
- backbuffer->Release();
- D3D11_TEXTURE2D_DESC depthDesc =
- {
- .Width = width,
- .Height = height,
- .MipLevels = 1,
- .ArraySize = 1,
- .Format = DXGI_FORMAT_D32_FLOAT, // or use DXGI_FORMAT_D32_FLOAT_S8X24_UINT if you need stencil
- .SampleDesc = { 1, 0 },
- .Usage = D3D11_USAGE_DEFAULT,
- .BindFlags = D3D11_BIND_DEPTH_STENCIL,
- };
- // create new depth stencil texture & DepthStencil view
- ID3D11Texture2D* depth;
- device->CreateTexture2D(&depthDesc, NULL, &depth);
- device->CreateDepthStencilView((ID3D11Resource*)depth, NULL, &dsView);
- depth->Release();
- }
- curr_width = width;
- curr_height = height;
- }
- if(rtView) {
- // output viewport covering all client area of window
- D3D11_VIEWPORT viewport = {
- .TopLeftX = 0,
- .TopLeftY = 0,
- .Width = (FLOAT)width,
- .Height = (FLOAT)height,
- .MinDepth = 0,
- .MaxDepth = 1,
- };
- // clear screen
- FLOAT color[] = { 0.392f, 0.584f, 0.929f, 1.f };
- context->ClearRenderTargetView(rtView, color);
- context->ClearDepthStencilView(dsView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.f, 0);
- POINT point;
- GetCursorPos(&point);
- ScreenToClient(window, &point);
- float x = point.x;
- float y = point.y;
- g_transform_arr.count = 0;
- srand(0);
- for(int i = 0; i < 65536; i += 1) {
- float x = rand() % width;
- float y = rand() % height;
- draw_rect_center(v2(x, y), 0, v2(8));
- }
- // draw_rect_center(v2(width, 0), 0, v2(128));
- // draw_rect_center(v2(width, height), 0, v2(128));
- // draw_rect_center(v2(0, height), 0, v2(128));
- {
- D3D11_MAPPED_SUBRESOURCE mapped = zero;
- context->Map(vbuffer1, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped);
- memcpy(mapped.pData, g_transform_arr.element_arr, sizeof(s_transform) * g_transform_arr.count);
- context->Unmap(vbuffer1, 0);
- }
- {
- float matrix[16] = {
- 2.0f/width,0,0,0,
- 0,-2.0f/height,0,0,
- 0,0,1,0,
- -1,1,0,1,
- };
- // float matrix[16] = {
- // 1,0,0,0,
- // 0,1,0,0,
- // 0,0,1,0,
- // 0,0,0,1,
- // };
- D3D11_MAPPED_SUBRESOURCE mapped;
- context->Map(ubuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped);
- memcpy(mapped.pData, matrix, sizeof(matrix));
- context->Unmap(ubuffer, 0);
- }
- // Input Assembler
- context->IASetInputLayout(layout);
- context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
- {
- UINT stride[] = {sizeof(s_vertex), sizeof(s_transform)};
- UINT offset[] = {0, 0};
- ID3D11Buffer* buffer[] = {vbuffer0, vbuffer1};
- context->IASetVertexBuffers(0, 2, buffer, stride, offset);
- }
- // Vertex Shader
- context->VSSetConstantBuffers(0, 1, &ubuffer);
- context->VSSetShader(vshader, NULL, 0);
- // Rasterizer Stage
- context->RSSetViewports(1, &viewport);
- context->RSSetState(rasterizerState);
- // Pixel Shader
- // context->PSSetSamplers(0, 1, &sampler);
- // context->PSSetShaderResources(0, 1, &textureView);
- context->PSSetShader(pshader, NULL, 0);
- // Output Merger
- context->OMSetBlendState(blendState, NULL, ~0U);
- context->OMSetDepthStencilState(depthState, 0);
- context->OMSetRenderTargets(1, &rtView, dsView);
- // draw 3 vertices
- context->DrawInstanced(6, g_transform_arr.count, 0, 0);
- }
- BOOL vsync = TRUE;
- hr = swap_chain->Present(vsync ? 1 : 0, 0);
- if(hr == DXGI_STATUS_OCCLUDED) {
- if(vsync) {
- Sleep(10);
- }
- }
- else if(FAILED(hr)) {
- printf("Failed to present swap chain! Device lost?\n");
- assert(false);
- }
- }
- }
- func void on_failed_assert(int line)
- {
- printf("FAILED ASSERT AT %i\n", line);
- MessageBox(null, "Failed assert", "ERROR", MB_OK);
- exit(1);
- }
- template <typename t0, typename t1>
- func s_v2 v2(t0 x, t1 y)
- {
- return {(float)x, (float)y};
- }
- template <typename t>
- func s_v2 v2(t v)
- {
- return {(float)v, (float)v};
- }
- func void draw_rect_center(s_v2 pos, float z, s_v2 size)
- {
- s_transform t = zero;
- t.pos = pos;
- t.size = size;
- g_transform_arr.add(t);
- }
- func u64 get_cycles()
- {
- u64 cycles;
- QueryPerformanceCounter((LARGE_INTEGER*)&cycles);
- return cycles;
- }
- func float get_seconds()
- {
- u64 cycles = get_cycles();
- f64 result = (cycles - g_start_cycles) / (f64)g_cycle_frequency;
- return (float)result;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement