From 51d112fb7d7c33e72fd1226d82adfa7234fa96e3 Mon Sep 17 00:00:00 2001 From: chyyran Date: Thu, 26 Jan 2023 23:47:27 -0500 Subject: [PATCH] examples: add another d3d11 c++ example --- .../librashader-capi-tests/README.md | 7 + .../dx11-example-2/code.cpp | 488 ++++++++++++++++++ .../dx11-example-2/dx11-example-2.vcxproj | 147 ++++++ .../dx11-example-2.vcxproj.filters | 33 ++ .../dx11-example-2.vcxproj.user | 4 + .../dx11-example-2/shaders.hlsl | 115 +++++ .../dx11-example/main.cpp | 4 + .../librashader-capi-tests.sln | 10 + 8 files changed, 808 insertions(+) create mode 100644 test/capi-tests/librashader-capi-tests/README.md create mode 100644 test/capi-tests/librashader-capi-tests/dx11-example-2/code.cpp create mode 100644 test/capi-tests/librashader-capi-tests/dx11-example-2/dx11-example-2.vcxproj create mode 100644 test/capi-tests/librashader-capi-tests/dx11-example-2/dx11-example-2.vcxproj.filters create mode 100644 test/capi-tests/librashader-capi-tests/dx11-example-2/dx11-example-2.vcxproj.user create mode 100644 test/capi-tests/librashader-capi-tests/dx11-example-2/shaders.hlsl diff --git a/test/capi-tests/librashader-capi-tests/README.md b/test/capi-tests/librashader-capi-tests/README.md new file mode 100644 index 0000000..68b1740 --- /dev/null +++ b/test/capi-tests/librashader-capi-tests/README.md @@ -0,0 +1,7 @@ +# C API examples and testing playground + +These examples are merely illustrations of how to use `librashader_ld.h`. The actual "rendering" parts of it should not be taken as "good" or well optimized code. + +* `librashader-capi-tests` This is my playground to test the soundness of bindings. +* `dx11-example` This is a basic D3D11 example. +* `dx11-example-2` This is a more advanced D3D11 example based off [Minimal D3D11 pt3](https://gist.github.com/d7samurai/abab8a580d0298cb2f34a44eec41d39d) to show integration with a more complex renderer. \ No newline at end of file diff --git a/test/capi-tests/librashader-capi-tests/dx11-example-2/code.cpp b/test/capi-tests/librashader-capi-tests/dx11-example-2/code.cpp new file mode 100644 index 0000000..55cf9f1 --- /dev/null +++ b/test/capi-tests/librashader-capi-tests/dx11-example-2/code.cpp @@ -0,0 +1,488 @@ +// Adapted from https://gist.github.com/d7samurai/abab8a580d0298cb2f34a44eec41d39d +// +// This example shows how librashader can be integrated into a more advanced renderer. +// +// Whereas the first example freed and recreated a texture every frame, this uses a persistent texture for better performance. +#pragma comment(lib, "user32") +#pragma comment(lib, "d3d11") +#pragma comment(lib, "d3dcompiler") + +/////////////////////////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#define LIBRA_RUNTIME_D3D11 +#include "../../../../include/librashader_ld.h" + +/////////////////////////////////////////////////////////////////////////////////////////////////// + +#define TITLE "Minimal D3D11 pt3 by d7samurai" + +/////////////////////////////////////////////////////////////////////////////////////////////////// + +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, + LPSTR lpCmdLine, int nShowCmd) { + WNDCLASSA wndClass = {0, DefWindowProcA, 0, 0, 0, 0, 0, 0, 0, TITLE}; + + RegisterClassA(&wndClass); + + HWND window = + CreateWindowExA(0, TITLE, TITLE, WS_POPUP | WS_MAXIMIZE | WS_VISIBLE, 0, + 0, 0, 0, nullptr, nullptr, nullptr, nullptr); + + /////////////////////////////////////////////////////////////////////////////////////////////// + + D3D_FEATURE_LEVEL featureLevels[] = {D3D_FEATURE_LEVEL_11_0}; + + ID3D11Device* baseDevice; + ID3D11DeviceContext* baseDeviceContext; + + D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, + D3D11_CREATE_DEVICE_BGRA_SUPPORT, featureLevels, + ARRAYSIZE(featureLevels), D3D11_SDK_VERSION, &baseDevice, + nullptr, &baseDeviceContext); + + /////////////////////////////////////////////////////////////////////////////////////////////// + + ID3D11Device1* device; + + baseDevice->QueryInterface(__uuidof(ID3D11Device1), + reinterpret_cast(&device)); + + ID3D11DeviceContext1* deviceContext; + + baseDeviceContext->QueryInterface(__uuidof(ID3D11DeviceContext1), + reinterpret_cast(&deviceContext)); + + /////////////////////////////////////////////////////////////////////////////////////////////// + + auto libra = librashader_load_instance(); + libra_shader_preset_t preset; + auto error = libra.preset_create( + "../../../slang-shaders/border/gameboy-player/" + "gameboy-player-crt-royale.slangp", + &preset); + + libra_d3d11_filter_chain_t filter_chain; + + libra.d3d11_filter_chain_create(&preset, NULL, device, &filter_chain); + /////////////////////////////////////////////////////////////////////////////////////////////// + IDXGIDevice1* dxgiDevice; + + device->QueryInterface(__uuidof(IDXGIDevice1), + reinterpret_cast(&dxgiDevice)); + + IDXGIAdapter* dxgiAdapter; + + dxgiDevice->GetAdapter(&dxgiAdapter); + + IDXGIFactory2* dxgiFactory; + + dxgiAdapter->GetParent(__uuidof(IDXGIFactory2), + reinterpret_cast(&dxgiFactory)); + + /////////////////////////////////////////////////////////////////////////////////////////////// + + DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {}; + swapChainDesc.Width = 0; // use window width + swapChainDesc.Height = 0; // use window height + swapChainDesc.Format = + DXGI_FORMAT_B8G8R8A8_UNORM; // can't specify _SRGB here when using + // DXGI_SWAP_EFFECT_FLIP_* ... + swapChainDesc.Stereo = FALSE; + swapChainDesc.SampleDesc.Count = 1; + swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + swapChainDesc.BufferCount = 2; + swapChainDesc.Scaling = DXGI_SCALING_STRETCH; + swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; + swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED; + + IDXGISwapChain1* swapChain; + + dxgiFactory->CreateSwapChainForHwnd(device, window, &swapChainDesc, nullptr, + nullptr, &swapChain); + + /////////////////////////////////////////////////////////////////////////////////////////////// + + ID3D11Texture2D* framebufferTexture; + ID3D11Texture2D* framebufferCopy; + + swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), + reinterpret_cast(&framebufferTexture)); + + D3D11_TEXTURE2D_DESC framebufferTextureDesc; + framebufferTexture->GetDesc(&framebufferTextureDesc); + framebufferTextureDesc.BindFlags = + D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; + framebufferTextureDesc.CPUAccessFlags = + D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_READ; + + device->CreateTexture2D(&framebufferTextureDesc, nullptr, + &framebufferCopy); + + D3D11_RENDER_TARGET_VIEW_DESC framebufferDesc = {}; + framebufferDesc.Format = + DXGI_FORMAT_B8G8R8A8_UNORM_SRGB; // ... so do this to get _SRGB + // swapchain + framebufferDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; + + ID3D11RenderTargetView* framebufferRTV; + + device->CreateRenderTargetView(framebufferTexture, &framebufferDesc, + &framebufferRTV); + + + + ID3D11ShaderResourceView* framebufferCopySRV; + device->CreateShaderResourceView(framebufferCopy, 0, &framebufferCopySRV); + /////////////////////////////////////////////////////////////////////////////////////////////// + + D3D11_TEXTURE2D_DESC framebufferDepthDesc; + + framebufferTexture->GetDesc( + &framebufferDepthDesc); // copy from framebuffer properties + + framebufferDepthDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; + framebufferDepthDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; + + ID3D11Texture2D* framebufferDepthTexture; + + device->CreateTexture2D(&framebufferDepthDesc, nullptr, + &framebufferDepthTexture); + + ID3D11DepthStencilView* framebufferDSV; + + device->CreateDepthStencilView(framebufferDepthTexture, nullptr, + &framebufferDSV); + + /////////////////////////////////////////////////////////////////////////////////////////////// + + D3D11_TEXTURE2D_DESC shadowmapDepthDesc = {}; + shadowmapDepthDesc.Width = 2048; + shadowmapDepthDesc.Height = 2048; + shadowmapDepthDesc.MipLevels = 1; + shadowmapDepthDesc.ArraySize = 1; + shadowmapDepthDesc.Format = DXGI_FORMAT_R32_TYPELESS; + shadowmapDepthDesc.SampleDesc.Count = 1; + shadowmapDepthDesc.Usage = D3D11_USAGE_DEFAULT; + shadowmapDepthDesc.BindFlags = + D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE; + + ID3D11Texture2D* shadowmapDepthTexture; + + device->CreateTexture2D(&shadowmapDepthDesc, nullptr, + &shadowmapDepthTexture); + + D3D11_DEPTH_STENCIL_VIEW_DESC shadowmapDSVdesc = {}; + shadowmapDSVdesc.Format = DXGI_FORMAT_D32_FLOAT; + shadowmapDSVdesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; + + ID3D11DepthStencilView* shadowmapDSV; + + device->CreateDepthStencilView(shadowmapDepthTexture, &shadowmapDSVdesc, + &shadowmapDSV); + + D3D11_SHADER_RESOURCE_VIEW_DESC shadowmapSRVdesc = {}; + shadowmapSRVdesc.Format = DXGI_FORMAT_R32_FLOAT; + shadowmapSRVdesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + shadowmapSRVdesc.Texture2D.MipLevels = 1; + + ID3D11ShaderResourceView* shadowmapSRV; + + device->CreateShaderResourceView(shadowmapDepthTexture, &shadowmapSRVdesc, + &shadowmapSRV); + + /////////////////////////////////////////////////////////////////////////////////////////////// + + struct float4 { + float x, y, z, w; + }; + + struct Constants { + float4 CameraProjection[4]; + float4 LightProjection[4]; + float4 LightRotation; + float4 ModelRotation; + float4 ModelTranslation; + float4 ShadowmapSize; + }; + + D3D11_BUFFER_DESC constantBufferDesc = {}; + constantBufferDesc.ByteWidth = + sizeof(Constants) + 0xf & + 0xfffffff0; // ensure constant buffer size is multiple of 16 bytes + constantBufferDesc.Usage = D3D11_USAGE_DYNAMIC; + constantBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + constantBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + + ID3D11Buffer* constantBuffer; + + device->CreateBuffer(&constantBufferDesc, nullptr, &constantBuffer); + + /////////////////////////////////////////////////////////////////////////////////////////////// + + float vertexData[] = { + -1, 1, -1, 0, 0, 1, 1, -1, 9.5f, + 0, -0.58f, 0.58f, -1, 2, 2, 0.58f, 0.58f, -1, + 7.5f, 2, -0.58f, 0.58f, -1, 0, 0, 0.58f, 0.58f, + -1, 0, 0, -0.58f, 0.58f, -0.58f, 0, 0, 0.58f, + 0.58f, -0.58f, 0, 0}; // pos.x, pos.y, pos.z, tex.u, tex.v, ... + + D3D11_BUFFER_DESC vertexBufferDesc = {}; + vertexBufferDesc.ByteWidth = sizeof(vertexData); + vertexBufferDesc.Usage = D3D11_USAGE_IMMUTABLE; + vertexBufferDesc.BindFlags = + D3D11_BIND_SHADER_RESOURCE; // using regular shader resource as + // vertex buffer for manual vertex fetch + vertexBufferDesc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED; + vertexBufferDesc.StructureByteStride = + 5 * + sizeof( + float); // 5 floats per vertex (float3 position, float2 texcoord) + + D3D11_SUBRESOURCE_DATA vertexBufferData = {vertexData}; + + ID3D11Buffer* vertexBuffer; + + device->CreateBuffer(&vertexBufferDesc, &vertexBufferData, &vertexBuffer); + + D3D11_SHADER_RESOURCE_VIEW_DESC vertexBufferSRVdesc = {}; + vertexBufferSRVdesc.Format = DXGI_FORMAT_UNKNOWN; + vertexBufferSRVdesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; + vertexBufferSRVdesc.Buffer.NumElements = + vertexBufferDesc.ByteWidth / vertexBufferDesc.StructureByteStride; + + ID3D11ShaderResourceView* vertexBufferSRV; + + device->CreateShaderResourceView(vertexBuffer, &vertexBufferSRVdesc, + &vertexBufferSRV); + + /////////////////////////////////////////////////////////////////////////////////////////////// + + D3D11_DEPTH_STENCIL_DESC depthStencilDesc = {}; + depthStencilDesc.DepthEnable = TRUE; + depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; + depthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS; + + ID3D11DepthStencilState* depthStencilState; + + device->CreateDepthStencilState(&depthStencilDesc, &depthStencilState); + + /////////////////////////////////////////////////////////////////////////////////////////////// + + D3D11_RASTERIZER_DESC1 rasterizerDesc = {}; + rasterizerDesc.FillMode = D3D11_FILL_SOLID; + rasterizerDesc.CullMode = D3D11_CULL_BACK; + + ID3D11RasterizerState1* cullBackRS; + + device->CreateRasterizerState1(&rasterizerDesc, &cullBackRS); + + rasterizerDesc.CullMode = D3D11_CULL_FRONT; + + ID3D11RasterizerState1* cullFrontRS; + + device->CreateRasterizerState1(&rasterizerDesc, &cullFrontRS); + + /////////////////////////////////////////////////////////////////////////////////////////////// + + ID3DBlob* framebufferVSBlob; + + D3DCompileFromFile(L"shaders.hlsl", nullptr, nullptr, "framebuffer_vs", + "vs_5_0", 0, 0, &framebufferVSBlob, nullptr); + + ID3D11VertexShader* framebufferVS; + + device->CreateVertexShader(framebufferVSBlob->GetBufferPointer(), + framebufferVSBlob->GetBufferSize(), nullptr, + &framebufferVS); + + /////////////////////////////////////////////////////////////////////////////////////////////// + + ID3DBlob* framebufferPSBlob; + + D3DCompileFromFile(L"shaders.hlsl", nullptr, nullptr, "framebuffer_ps", + "ps_5_0", 0, 0, &framebufferPSBlob, nullptr); + + ID3D11PixelShader* framebufferPS; + + device->CreatePixelShader(framebufferPSBlob->GetBufferPointer(), + framebufferPSBlob->GetBufferSize(), nullptr, + &framebufferPS); + + ///////////////////////////////////////////////////////////////////////////////////////////// + + ID3DBlob* shadowmapVSBlob; + + D3DCompileFromFile(L"shaders.hlsl", nullptr, nullptr, "shadowmap_vs", + "vs_5_0", 0, 0, &shadowmapVSBlob, nullptr); + + ID3D11VertexShader* shadowmapVS; + + device->CreateVertexShader(shadowmapVSBlob->GetBufferPointer(), + shadowmapVSBlob->GetBufferSize(), nullptr, + &shadowmapVS); + + /////////////////////////////////////////////////////////////////////////////////////////////// + + FLOAT framebufferClear[4] = {0.025f, 0.025f, 0.025f, 1}; + + D3D11_VIEWPORT framebufferVP = { + 0, + 0, + static_cast(framebufferDepthDesc.Width), + static_cast(framebufferDepthDesc.Height), + 0, + 1}; + D3D11_VIEWPORT shadowmapVP = {0, + 0, + static_cast(shadowmapDepthDesc.Width), + static_cast(shadowmapDepthDesc.Height), + 0, + 1}; + + ID3D11ShaderResourceView* nullSRV = + nullptr; // null srv used for unbinding resources + + /////////////////////////////////////////////////////////////////////////////////////////////// + + Constants constants = {2.0f / (framebufferVP.Width / framebufferVP.Height), + 0, + 0, + 0, + 0, + 2, + 0, + 0, + 0, + 0, + 1.125f, + 1, + 0, + 0, + -1.125f, + 0, // camera projection matrix (perspective) + 0.5f, + 0, + 0, + 0, + 0, + 0.5f, + 0, + 0, + 0, + 0, + 0.125f, + 0, + 0, + 0, + -0.125f, + 1}; // light projection matrix (orthographic) + + constants.LightRotation = {0.8f, 0.6f, 0.0f}; + constants.ModelRotation = {0.0f, 0.0f, 0.0f}; + constants.ModelTranslation = {0.0f, 0.0f, 4.0f}; + + constants.ShadowmapSize = {shadowmapVP.Width, shadowmapVP.Height}; + + /////////////////////////////////////////////////////////////////////////////////////////////// + + size_t frameCount = 0; + while (true) { + MSG msg; + + while (PeekMessageA(&msg, nullptr, 0, 0, PM_REMOVE)) { + if (msg.message == WM_KEYDOWN) return 0; + DispatchMessageA(&msg); + } + + /////////////////////////////////////////////////////////////////////////////////////////// + + constants.ModelRotation.x += 0.001f; + constants.ModelRotation.y += 0.005f; + constants.ModelRotation.z += 0.003f; + + /////////////////////////////////////////////////////////////////////////////////////////// + + D3D11_MAPPED_SUBRESOURCE mappedSubresource; + + deviceContext->Map(constantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, + &mappedSubresource); + + *reinterpret_cast(mappedSubresource.pData) = constants; + + deviceContext->Unmap(constantBuffer, 0); + + /////////////////////////////////////////////////////////////////////////////////////////// + + deviceContext->ClearDepthStencilView(shadowmapDSV, D3D11_CLEAR_DEPTH, + 1.0f, 0); + + deviceContext->OMSetRenderTargets( + 0, nullptr, shadowmapDSV); // null rendertarget for depth only + deviceContext->OMSetDepthStencilState(depthStencilState, 0); + + deviceContext->IASetPrimitiveTopology( + D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); // using triangle strip + // this time + + deviceContext->VSSetConstantBuffers(0, 1, &constantBuffer); + deviceContext->VSSetShaderResources(0, 1, &vertexBufferSRV); + deviceContext->VSSetShader(shadowmapVS, nullptr, 0); + + deviceContext->RSSetViewports(1, &shadowmapVP); + deviceContext->RSSetState(cullFrontRS); + + deviceContext->PSSetShader(nullptr, nullptr, + 0); // null pixelshader for depth only + + /////////////////////////////////////////////////////////////////////////////////////////// + + deviceContext->DrawInstanced(8, 24, 0, + 0); // render shadowmap (light pov) + + /////////////////////////////////////////////////////////////////////////////////////////// + + deviceContext->ClearRenderTargetView(framebufferRTV, framebufferClear); + deviceContext->ClearDepthStencilView(framebufferDSV, D3D11_CLEAR_DEPTH, + 1.0f, 0); + + deviceContext->OMSetRenderTargets(1, &framebufferRTV, framebufferDSV); + + deviceContext->VSSetShader(framebufferVS, nullptr, 0); + + deviceContext->RSSetViewports(1, &framebufferVP); + deviceContext->RSSetState(cullBackRS); + + deviceContext->PSSetShaderResources(1, 1, &shadowmapSRV); + deviceContext->PSSetShader(framebufferPS, nullptr, 0); + + /////////////////////////////////////////////////////////////////////////////////////////// + + deviceContext->DrawInstanced(8, 24, 0, + 0); // render framebuffer (camera pov) + + /////////////////////////////////////////////////////////////////////////////////////////// + + deviceContext->PSSetShaderResources( + 1, 1, + &nullSRV); // release shadowmap as srv to avoid srv/dsv conflict + + /////////////////////////////////////////////////////////////////////////////////////////// + + deviceContext->CopyResource(framebufferCopy, framebufferTexture); + + libra_source_image_d3d11_t input = {framebufferCopySRV, framebufferVP.Height, + framebufferVP.Width}; + + libra_viewport_t vp = {0, 0, framebufferVP.Height, framebufferVP.Width}; + + libra.d3d11_filter_chain_frame(&filter_chain, frameCount, input, vp, + framebufferRTV, NULL, NULL); + + //////////////////////////////////////////////////////////////////////// + swapChain->Present(1, 0); + frameCount += 1; + } +} \ No newline at end of file diff --git a/test/capi-tests/librashader-capi-tests/dx11-example-2/dx11-example-2.vcxproj b/test/capi-tests/librashader-capi-tests/dx11-example-2/dx11-example-2.vcxproj new file mode 100644 index 0000000..1daba3f --- /dev/null +++ b/test/capi-tests/librashader-capi-tests/dx11-example-2/dx11-example-2.vcxproj @@ -0,0 +1,147 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {d67d8561-4d02-430e-8bf7-3715f2456410} + dx11example2 + 10.0 + + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + stdcpp20 + + + Windows + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + stdcpp20 + + + Windows + true + true + true + + + + + + + + true + true + + + + + + + + + + \ No newline at end of file diff --git a/test/capi-tests/librashader-capi-tests/dx11-example-2/dx11-example-2.vcxproj.filters b/test/capi-tests/librashader-capi-tests/dx11-example-2/dx11-example-2.vcxproj.filters new file mode 100644 index 0000000..d116003 --- /dev/null +++ b/test/capi-tests/librashader-capi-tests/dx11-example-2/dx11-example-2.vcxproj.filters @@ -0,0 +1,33 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + + + + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/test/capi-tests/librashader-capi-tests/dx11-example-2/dx11-example-2.vcxproj.user b/test/capi-tests/librashader-capi-tests/dx11-example-2/dx11-example-2.vcxproj.user new file mode 100644 index 0000000..88a5509 --- /dev/null +++ b/test/capi-tests/librashader-capi-tests/dx11-example-2/dx11-example-2.vcxproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/test/capi-tests/librashader-capi-tests/dx11-example-2/shaders.hlsl b/test/capi-tests/librashader-capi-tests/dx11-example-2/shaders.hlsl new file mode 100644 index 0000000..813fdc9 --- /dev/null +++ b/test/capi-tests/librashader-capi-tests/dx11-example-2/shaders.hlsl @@ -0,0 +1,115 @@ +cbuffer constants : register(b0) { + row_major float4x4 cameraprojection; + row_major float4x4 lightprojection; + float3 lightrotation; + float3 modelrotation; + float4 modeltranslation; + + float2 shadowmapsize; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// + +struct input { + float3 position; + float2 texcoord; +}; + +struct output { + float4 position : SV_POSITION; + float4 lightpos : LPS; + float2 texcoord : TEX; + nointerpolation float4 color : COL; +}; + +/////////////////////////////////////////////////////////////////////////////////////////////////// + +StructuredBuffer vertexbuffer : register(t0); +Texture2D shadowmap : register(t1); + +/////////////////////////////////////////////////////////////////////////////////////////////////// + +float3 get_rotation(uint i) { + return float3(max(0, float(i / 4) * 2 - 7), i / 4 % 5, i % 4) * + 1.5708f; // generate XYZ rotation from instance id +} + +float4x4 get_rotation_matrix(float3 r) { + float4x4 x = {1, 0, 0, 0, 0, cos(r.x), -sin(r.x), 0, + 0, sin(r.x), cos(r.x), 0, 0, 0, 0, 1}; + float4x4 y = {cos(r.y), 0, sin(r.y), 0, 0, 1, 0, 0, + -sin(r.y), 0, cos(r.y), 0, 0, 0, 0, 1}; + float4x4 z = {cos(r.z), -sin(r.z), 0, 0, sin(r.z), cos(r.z), 0, 0, + 0, 0, 1, 0, 0, 0, 0, 1}; + + return mul(mul(z, y), x); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// + +output framebuffer_vs(uint vertexid + : SV_VERTEXID, uint instanceid + : SV_INSTANCEID) { + input myinput = vertexbuffer[vertexid]; // manual vertex fetch + + static float4 normal[2] = {{0, 0, -1, 0}, {0, -1, 0, 0}}; + static float3 color[6] = { + {0.973f, 0.480f, 0.002f}, {0.897f, 0.163f, 0.011f}, + {0.612f, 0.000f, 0.069f}, {0.127f, 0.116f, 0.408f}, + {0.000f, 0.254f, 0.637f}, {0.001f, 0.447f, 0.067f}}; + + float4x4 modeltransform = mul(get_rotation_matrix(get_rotation(instanceid)), + get_rotation_matrix(modelrotation)); + float4x4 lighttransform = + mul(modeltransform, get_rotation_matrix(lightrotation)); + + float light = clamp( + dot(mul(normal[vertexid / 4], lighttransform), normal[0]), 0.0f, 1.0f); + + output myoutput; + + myoutput.position = mul( + mul(float4(myinput.position, 1.0f), modeltransform) + modeltranslation, + cameraprojection); + myoutput.lightpos = mul( + mul(float4(myinput.position, 1.0f), lighttransform) + modeltranslation, + lightprojection); + myoutput.texcoord = myinput.texcoord; + myoutput.color = float4(color[instanceid / 4], light); + + myoutput.lightpos.xy = + (myoutput.lightpos.xy * float2(0.5f, -0.5f) + 0.5f) * shadowmapsize; + + return myoutput; +} + +float4 framebuffer_ps(output myinput) : SV_TARGET { + float3 color = + myinput.color.rgb * + ((uint(myinput.texcoord.x * 2) ^ uint(myinput.texcoord.y * 2)) & 1 + ? 0.25f + : 1.0f); // procedural checkerboard pattern + float light = myinput.color.a; + + if (light > 0.0f && shadowmap[myinput.lightpos.xy] < myinput.lightpos.z) + light *= 0.2; + + return float4(color * (light * 0.8f + 0.2f), 1); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// + +float4 shadowmap_vs(uint vertexid + : SV_VERTEXID, uint instanceid + : SV_INSTANCEID) + : SV_POSITION { + float4x4 modeltransform = mul(get_rotation_matrix(get_rotation(instanceid)), + get_rotation_matrix(modelrotation)); + float4x4 lighttransform = + mul(modeltransform, get_rotation_matrix(lightrotation)); + + return mul( + mul(float4(vertexbuffer[vertexid].position, 1.0f), lighttransform) + + modeltranslation, + lightprojection); +} \ No newline at end of file diff --git a/test/capi-tests/librashader-capi-tests/dx11-example/main.cpp b/test/capi-tests/librashader-capi-tests/dx11-example/main.cpp index 882e22e..7aff0ba 100644 --- a/test/capi-tests/librashader-capi-tests/dx11-example/main.cpp +++ b/test/capi-tests/librashader-capi-tests/dx11-example/main.cpp @@ -1,4 +1,8 @@ // based off https://github.com/kevinmoran/BeginnerDirect3D11/tree/master/02.%20Drawing%20a%20Triangle +// +// This example should not be taken as "good" code, it is just an example of how to use librashader in Direct3D11. +// +// Namely, you should not recreate the input texture every frame. It is much cheaper to have one long lived copy texture. #define WIN32_LEAN_AND_MEAN #define NOMINMAX #define UNICODE diff --git a/test/capi-tests/librashader-capi-tests/librashader-capi-tests.sln b/test/capi-tests/librashader-capi-tests/librashader-capi-tests.sln index d897ad6..dea1eef 100644 --- a/test/capi-tests/librashader-capi-tests/librashader-capi-tests.sln +++ b/test/capi-tests/librashader-capi-tests/librashader-capi-tests.sln @@ -7,6 +7,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "librashader-capi-tests", "l EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dx11-example", "dx11-example\dx11-example.vcxproj", "{ACDE0543-C068-456D-B4C0-6C5E39296ABB}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dx11-example-2", "dx11-example-2\dx11-example-2.vcxproj", "{D67D8561-4D02-430E-8BF7-3715F2456410}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 @@ -31,6 +33,14 @@ Global {ACDE0543-C068-456D-B4C0-6C5E39296ABB}.Release|x64.Build.0 = Release|x64 {ACDE0543-C068-456D-B4C0-6C5E39296ABB}.Release|x86.ActiveCfg = Release|Win32 {ACDE0543-C068-456D-B4C0-6C5E39296ABB}.Release|x86.Build.0 = Release|Win32 + {D67D8561-4D02-430E-8BF7-3715F2456410}.Debug|x64.ActiveCfg = Debug|x64 + {D67D8561-4D02-430E-8BF7-3715F2456410}.Debug|x64.Build.0 = Debug|x64 + {D67D8561-4D02-430E-8BF7-3715F2456410}.Debug|x86.ActiveCfg = Debug|Win32 + {D67D8561-4D02-430E-8BF7-3715F2456410}.Debug|x86.Build.0 = Debug|Win32 + {D67D8561-4D02-430E-8BF7-3715F2456410}.Release|x64.ActiveCfg = Release|x64 + {D67D8561-4D02-430E-8BF7-3715F2456410}.Release|x64.Build.0 = Release|x64 + {D67D8561-4D02-430E-8BF7-3715F2456410}.Release|x86.ActiveCfg = Release|Win32 + {D67D8561-4D02-430E-8BF7-3715F2456410}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE