diff --git a/Windows_Libs/Dev/Input/Input.vcxproj b/Windows_Libs/Dev/Input/Input.vcxproj index d50f5ae..9c1f194 100644 --- a/Windows_Libs/Dev/Input/Input.vcxproj +++ b/Windows_Libs/Dev/Input/Input.vcxproj @@ -1,182 +1,182 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - 18.0 - Win32Proj - {258f8cf7-6317-480d-b07d-52a6846adf67} - input - 10.0 - Input - - - - StaticLibrary - true - v145 - Unicode - - - StaticLibrary - false - v145 - true - Unicode - - - StaticLibrary - true - v145 - Unicode - - - StaticLibrary - false - v145 - true - Unicode - - - - - - - - - - - - - - - - - - - - - 4J_$(ProjectName)_d - - - 4J_$(ProjectName) - - - - Level3 - true - _CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - true - stdcpp20 - Use - pch.h - - - - - true - - - - - Level3 - true - true - true - _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - true - stdcpp20 - Use - pch.h - - - - - true - - - - - Level3 - true - _CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_DEBUG;_LIB;%(PreprocessorDefinitions) - true - stdcpp20 - Use - stdafx.h - stdafx.h - true - MultiThreadedDebug - - - - - true - - - - - - Level3 - true - true - true - _CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;NDEBUG;_LIB;%(PreprocessorDefinitions) - true - stdcpp20 - Use - stdafx.h - stdafx.h - true - MultiThreaded - - - - - true - - - - - - - - - - - - - - - - - - - - - Create - Create - Create - Create - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 18.0 + Win32Proj + {258f8cf7-6317-480d-b07d-52a6846adf67} + input + 10.0 + Input + + + + StaticLibrary + true + v145 + Unicode + + + StaticLibrary + false + v145 + true + Unicode + + + StaticLibrary + true + v145 + Unicode + + + StaticLibrary + false + v110 + true + Unicode + + + + + + + + + + + + + + + + + + + + + 4J_$(ProjectName)_d + + + 4J_$(ProjectName) + + + + Level3 + true + _CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + stdcpp20 + Use + pch.h + + + + + true + + + + + Level3 + true + true + true + _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + stdcpp20 + Use + pch.h + + + + + true + + + + + Level3 + true + _CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + stdcpp20 + Use + stdafx.h + stdafx.h + true + MultiThreadedDebug + + + + + true + + + + + + Level3 + true + true + true + _CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + stdcpp20 + Use + stdafx.h + stdafx.h + true + MultiThreaded + + + + + true + + + + + + + + + + + + + + + + + + + + + Create + Create + Create + Create + + + + + \ No newline at end of file diff --git a/Windows_Libs/Dev/Profile/Profile.vcxproj b/Windows_Libs/Dev/Profile/Profile.vcxproj index 25c8952..ed58ddb 100644 --- a/Windows_Libs/Dev/Profile/Profile.vcxproj +++ b/Windows_Libs/Dev/Profile/Profile.vcxproj @@ -1,183 +1,183 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - 18.0 - Win32Proj - {d68297b9-ca86-4a8c-b81f-61811d7f96b8} - profile - 10.0 - Profile - - - - StaticLibrary - true - v145 - Unicode - - - StaticLibrary - false - v145 - true - Unicode - - - StaticLibrary - true - v145 - Unicode - - - StaticLibrary - false - v145 - true - Unicode - - - - - - - - - - - - - - - - - - - - - 4J_$(ProjectName) - - - 4J_$(ProjectName)_d - - - - Level3 - true - WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - true - stdcpp20 - Use - pch.h - - - - - true - - - - - Level3 - true - true - true - WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - true - stdcpp20 - Use - pch.h - - - - - true - - - - - Level3 - true - _CRT_SECURE_NO_WARNINGS;_DEBUG;_LIB;%(PreprocessorDefinitions) - true - stdcpp20 - Use - stdafx.h - true - stdafx.h - MultiThreadedDebug - - - - - true - - - - - - Level3 - true - true - true - _CRT_SECURE_NO_WARNINGS;NDEBUG;_LIB;%(PreprocessorDefinitions) - true - stdcpp20 - Use - stdafx.h - true - stdafx.h - MultiThreaded - - - - - true - - - - - - - - - - - - - - - - - - - - - - Create - Create - Create - Create - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 18.0 + Win32Proj + {d68297b9-ca86-4a8c-b81f-61811d7f96b8} + profile + 10.0 + Profile + + + + StaticLibrary + true + v145 + Unicode + + + StaticLibrary + false + v145 + true + Unicode + + + StaticLibrary + true + v145 + Unicode + + + StaticLibrary + false + v110 + true + Unicode + + + + + + + + + + + + + + + + + + + + + 4J_$(ProjectName) + + + 4J_$(ProjectName)_d + + + + Level3 + true + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + stdcpp20 + Use + pch.h + + + + + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + stdcpp20 + Use + pch.h + + + + + true + + + + + Level3 + true + _CRT_SECURE_NO_WARNINGS;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + stdcpp20 + Use + stdafx.h + true + stdafx.h + MultiThreadedDebug + + + + + true + + + + + + Level3 + true + true + true + _CRT_SECURE_NO_WARNINGS;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + stdcpp20 + Use + stdafx.h + true + stdafx.h + MultiThreaded + + + + + true + + + + + + + + + + + + + + + + + + + + + + Create + Create + Create + Create + + + + + \ No newline at end of file diff --git a/Windows_Libs/Dev/Render/4J_Render.cpp b/Windows_Libs/Dev/Render/4J_Render.cpp index 7b801e7..2089c6a 100644 --- a/Windows_Libs/Dev/Render/4J_Render.cpp +++ b/Windows_Libs/Dev/Render/4J_Render.cpp @@ -1,4 +1,478 @@ -#pragma once +#include "stdafx.h" #include "4J_Render.h" +#include "Renderer.h" -C4JRender RenderManager; \ No newline at end of file +void C4JRender::Tick() +{ +} + +void C4JRender::UpdateGamma(unsigned short usGamma) +{ + InternalRenderManager.UpdateGamma(usGamma); +} + +void C4JRender::MatrixMode(int type) +{ + InternalRenderManager.MatrixMode(type); +} + +void C4JRender::MatrixSetIdentity() +{ + InternalRenderManager.MatrixSetIdentity(); +} + +void C4JRender::MatrixTranslate(float x, float y, float z) +{ + InternalRenderManager.MatrixTranslate(x, y, z); +} + +void C4JRender::MatrixRotate(float angle, float x, float y, float z) +{ + InternalRenderManager.MatrixRotate(angle, x, y, z); +} + +void C4JRender::MatrixScale(float x, float y, float z) +{ + InternalRenderManager.MatrixScale(x, y, z); +} + +void C4JRender::MatrixPerspective(float fovy, float aspect, float zNear, float zFar) +{ + InternalRenderManager.MatrixPerspective(fovy, aspect, zNear, zFar); +} + +void C4JRender::MatrixOrthogonal(float left, float right, float bottom, float top, float zNear, float zFar) +{ + InternalRenderManager.MatrixOrthogonal(left, right, bottom, top, zNear, zFar); +} + +void C4JRender::MatrixPop() +{ + InternalRenderManager.MatrixPop(); +} + +void C4JRender::MatrixPush() +{ + InternalRenderManager.MatrixPush(); +} + +void C4JRender::MatrixMult(float* mat) +{ + InternalRenderManager.MatrixMult(mat); +} + +const float* C4JRender::MatrixGet(int type) +{ + return InternalRenderManager.MatrixGet(type); +} + +void C4JRender::Set_matrixDirty() +{ + InternalRenderManager.Set_matrixDirty(); +} + +void C4JRender::Initialise(ID3D11Device* pDevice, IDXGISwapChain* pSwapChain) +{ + InternalRenderManager.Initialise(pDevice, pSwapChain); +} + +void C4JRender::InitialiseContext() +{ + InternalRenderManager.InitialiseContext(false); +} + +void C4JRender::StartFrame() +{ + InternalRenderManager.StartFrame(); +} + +void C4JRender::DoScreenGrabOnNextPresent() +{ + InternalRenderManager.DoScreenGrabOnNextPresent(); +} + +void C4JRender::Present() +{ + InternalRenderManager.Present(); +} + +void C4JRender::Clear(int flags, D3D11_RECT* pRect) +{ + InternalRenderManager.Clear(flags, pRect); +} + +void C4JRender::SetClearColour(const float colourRGBA[4]) +{ + InternalRenderManager.SetClearColour(colourRGBA); +} + +bool C4JRender::IsWidescreen() +{ + return InternalRenderManager.IsWidescreen(); +} + +bool C4JRender::IsHiDef() +{ + return InternalRenderManager.IsHiDef(); +} + +void C4JRender::CaptureThumbnail(ImageFileBuffer* pngOut) +{ + InternalRenderManager.CaptureThumbnail(pngOut); +} + +void C4JRender::CaptureScreen(ImageFileBuffer* jpgOut, XSOCIAL_PREVIEWIMAGE* previewOut) +{ + InternalRenderManager.CaptureScreen(jpgOut, previewOut); +} + +void C4JRender::BeginConditionalSurvey(int identifier) +{ + InternalRenderManager.BeginConditionalSurvey(identifier); +} + +void C4JRender::EndConditionalSurvey() +{ + InternalRenderManager.EndConditionalSurvey(); +} + +void C4JRender::BeginConditionalRendering(int identifier) +{ + InternalRenderManager.BeginConditionalRendering(identifier); +} + +void C4JRender::EndConditionalRendering() +{ + InternalRenderManager.EndConditionalRendering(); +} + +void C4JRender::DrawVertices(ePrimitiveType PrimitiveType, int count, void* dataIn, eVertexType vType, ePixelShaderType psType) +{ + InternalRenderManager.DrawVertices(PrimitiveType, count, dataIn, vType, psType); +} + +void C4JRender::DrawVertexBuffer(ePrimitiveType PrimitiveType, int count, ID3D11Buffer* buffer, eVertexType vType, ePixelShaderType psType) +{ + InternalRenderManager.DrawVertexBuffer(PrimitiveType, count, buffer, vType, psType); +} + +void C4JRender::CBuffLockStaticCreations() +{ + InternalRenderManager.CBuffLockStaticCreations(); +} + +int C4JRender::CBuffCreate(int count) +{ + return InternalRenderManager.CBuffCreate(count); +} + +void C4JRender::CBuffDelete(int first, int count) +{ + InternalRenderManager.CBuffDelete(first, count); +} + +void C4JRender::CBuffStart(int index, bool full) +{ + InternalRenderManager.CBuffStart(index, full); +} + +void C4JRender::CBuffClear(int index) +{ + InternalRenderManager.CBuffClear(index); +} + +int C4JRender::CBuffSize(int index) +{ + return InternalRenderManager.CBuffSize(index); +} + +void C4JRender::CBuffEnd() +{ + InternalRenderManager.CBuffEnd(); +} + +bool C4JRender::CBuffCall(int index, bool full) +{ + return InternalRenderManager.CBuffCall(index, full); +} + +void C4JRender::CBuffTick() +{ + InternalRenderManager.CBuffTick(); +} + +void C4JRender::CBuffDeferredModeStart() +{ + InternalRenderManager.CBuffDeferredModeStart(); +} + +void C4JRender::CBuffDeferredModeEnd() +{ + InternalRenderManager.CBuffDeferredModeEnd(); +} + +int C4JRender::TextureCreate() +{ + return InternalRenderManager.TextureCreate(); +} + +void C4JRender::TextureFree(int idx) +{ + InternalRenderManager.TextureFree(idx); +} + +void C4JRender::TextureBind(int idx) +{ + InternalRenderManager.TextureBind(idx); +} + +void C4JRender::TextureBindVertex(int idx) +{ + InternalRenderManager.TextureBindVertex(idx); +} + +void C4JRender::TextureSetTextureLevels(int levels) +{ + InternalRenderManager.TextureSetTextureLevels(levels); +} + +int C4JRender::TextureGetTextureLevels() +{ + return InternalRenderManager.TextureGetTextureLevels(); +} + +void C4JRender::TextureData(int width, int height, void* data, int level, eTextureFormat format) +{ + InternalRenderManager.TextureData(width, height, data, level, format); +} + +void C4JRender::TextureDataUpdate(int xoffset, int yoffset, int width, int height, void* data, int level) +{ + InternalRenderManager.TextureDataUpdate(xoffset, yoffset, width, height, data, level); +} + +void C4JRender::TextureSetParam(int param, int value) +{ + InternalRenderManager.TextureSetParam(param, value); +} + +void C4JRender::TextureDynamicUpdateStart() +{ + InternalRenderManager.TextureDynamicUpdateStart(); +} + +void C4JRender::TextureDynamicUpdateEnd() +{ + InternalRenderManager.TextureDynamicUpdateEnd(); +} + +HRESULT C4JRender::LoadTextureData(const char* szFilename, D3DXIMAGE_INFO* pSrcInfo, int** ppDataOut) +{ + return InternalRenderManager.LoadTextureData(szFilename, pSrcInfo, ppDataOut); +} + +HRESULT C4JRender::LoadTextureData(BYTE* pbData, DWORD dwBytes, D3DXIMAGE_INFO* pSrcInfo, int** ppDataOut) +{ + return InternalRenderManager.LoadTextureData(pbData, dwBytes, pSrcInfo, ppDataOut); +} + +HRESULT C4JRender::SaveTextureData(const char* szFilename, D3DXIMAGE_INFO* pSrcInfo, int* ppDataOut) +{ + return InternalRenderManager.SaveTextureData(szFilename, pSrcInfo, ppDataOut); +} + +HRESULT C4JRender::SaveTextureDataToMemory(void* pOutput, int outputCapacity, int* outputLength, int width, int height, int* ppDataIn) +{ + return InternalRenderManager.SaveTextureDataToMemory(pOutput, outputCapacity, outputLength, width, height, ppDataIn); +} + +void C4JRender::TextureGetStats() +{ +} + +ID3D11ShaderResourceView* C4JRender::TextureGetTexture(int idx) +{ + return InternalRenderManager.TextureGetTexture(idx); +} + +void C4JRender::StateSetColour(float r, float g, float b, float a) +{ + InternalRenderManager.StateSetColour(r, g, b, a); +} + +void C4JRender::StateSetDepthMask(bool enable) +{ + InternalRenderManager.StateSetDepthMask(enable); +} + +void C4JRender::StateSetBlendEnable(bool enable) +{ + InternalRenderManager.StateSetBlendEnable(enable); +} + +void C4JRender::StateSetBlendFunc(int src, int dst) +{ + InternalRenderManager.StateSetBlendFunc(src, dst); +} + +void C4JRender::StateSetBlendFactor(unsigned int colour) +{ + InternalRenderManager.StateSetBlendFactor(colour); +} + +void C4JRender::StateSetAlphaFunc(int func, float param) +{ + InternalRenderManager.StateSetAlphaFunc(func, param); +} + +void C4JRender::StateSetDepthFunc(int func) +{ + InternalRenderManager.StateSetDepthFunc(func); +} + +void C4JRender::StateSetFaceCull(bool enable) +{ + InternalRenderManager.StateSetFaceCull(enable); +} + +void C4JRender::StateSetFaceCullCW(bool enable) +{ + InternalRenderManager.StateSetFaceCullCW(enable); +} + +void C4JRender::StateSetLineWidth(float width) +{ + InternalRenderManager.StateSetLineWidth(width); +} + +void C4JRender::StateSetWriteEnable(bool red, bool green, bool blue, bool alpha) +{ + InternalRenderManager.StateSetWriteEnable(red, green, blue, alpha); +} + +void C4JRender::StateSetDepthTestEnable(bool enable) +{ + InternalRenderManager.StateSetDepthTestEnable(enable); +} + +void C4JRender::StateSetAlphaTestEnable(bool enable) +{ + InternalRenderManager.StateSetAlphaTestEnable(enable); +} + +void C4JRender::StateSetDepthSlopeAndBias(float slope, float bias) +{ + InternalRenderManager.StateSetDepthSlopeAndBias(slope, bias); +} + +void C4JRender::StateSetFogEnable(bool enable) +{ + InternalRenderManager.StateSetFogEnable(enable); +} + +void C4JRender::StateSetFogMode(int mode) +{ + InternalRenderManager.StateSetFogMode(mode); +} + +void C4JRender::StateSetFogNearDistance(float dist) +{ + InternalRenderManager.StateSetFogNearDistance(dist); +} + +void C4JRender::StateSetFogFarDistance(float dist) +{ + InternalRenderManager.StateSetFogFarDistance(dist); +} + +void C4JRender::StateSetFogDensity(float density) +{ + InternalRenderManager.StateSetFogDensity(density); +} + +void C4JRender::StateSetFogColour(float red, float green, float blue) +{ + InternalRenderManager.StateSetFogColour(red, green, blue); +} + +void C4JRender::StateSetLightingEnable(bool enable) +{ + InternalRenderManager.StateSetLightingEnable(enable); +} + +void C4JRender::StateSetVertexTextureUV(float u, float v) +{ + InternalRenderManager.StateSetVertexTextureUV(u, v); +} + +void C4JRender::StateSetLightColour(int light, float red, float green, float blue) +{ + InternalRenderManager.StateSetLightColour(light, red, green, blue); +} + +void C4JRender::StateSetLightAmbientColour(float red, float green, float blue) +{ + InternalRenderManager.StateSetLightAmbientColour(red, green, blue); +} + +void C4JRender::StateSetLightDirection(int light, float x, float y, float z) +{ + InternalRenderManager.StateSetLightDirection(light, x, y, z); +} + +void C4JRender::StateSetLightEnable(int light, bool enable) +{ + InternalRenderManager.StateSetLightEnable(light, enable); +} + +void C4JRender::StateSetViewport(eViewportType viewportType) +{ + InternalRenderManager.StateSetViewport(viewportType); +} + +void C4JRender::StateSetEnableViewportClipPlanes(bool enable) +{ + InternalRenderManager.StateSetEnableViewportClipPlanes(enable); +} + +void C4JRender::StateSetTexGenCol(int col, float x, float y, float z, float w, bool eyeSpace) +{ + InternalRenderManager.StateSetTexGenCol(col, x, y, z, w, eyeSpace); +} + +void C4JRender::StateSetStencil(int Function, uint8_t stencil_ref, uint8_t stencil_func_mask, uint8_t stencil_write_mask) +{ + InternalRenderManager.StateSetStencil((D3D11_COMPARISON_FUNC)Function, stencil_ref, stencil_func_mask, stencil_write_mask); +} + +void C4JRender::StateSetForceLOD(int LOD) +{ + InternalRenderManager.StateSetForceLOD(LOD); +} + +void C4JRender::BeginEvent(LPCWSTR eventName) +{ + InternalRenderManager.BeginEvent(eventName); +} + +void C4JRender::EndEvent() +{ + InternalRenderManager.EndEvent(); +} + +void C4JRender::Suspend() +{ + InternalRenderManager.Suspend(); +} + +bool C4JRender::Suspended() +{ + return InternalRenderManager.Suspended(); +} + +void C4JRender::Resume() +{ + InternalRenderManager.Resume(); +} + +C4JRender RenderManager; diff --git a/Windows_Libs/Dev/Render/Render.vcxproj b/Windows_Libs/Dev/Render/Render.vcxproj index e2bde31..aab379d 100644 --- a/Windows_Libs/Dev/Render/Render.vcxproj +++ b/Windows_Libs/Dev/Render/Render.vcxproj @@ -1,346 +1,346 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - 18.0 - Win32Proj - {cc99eb47-7231-4067-8717-c6bf4abde338} - render - 10.0 - Render_PC - - - - StaticLibrary - true - v145 - Unicode - - - StaticLibrary - false - v145 - true - Unicode - - - StaticLibrary - true - v145 - Unicode - - - StaticLibrary - false - v145 - true - Unicode - - - - - - - - - - - - - - - - - - - - - 4J_$(ProjectName)_d - - - 4J_$(ProjectName) - - - - Level3 - true - WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - true - stdcpp20 - Use - pch.h - - - - - true - - - - - Level3 - true - true - true - WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - true - stdcpp20 - Use - pch.h - - - - - true - - - - - Level3 - true - _CRT_SECURE_NO_WARNINGS;_DEBUG;_LIB;%(PreprocessorDefinitions) - true - stdcpp20 - Use - stdafx.h - true - stdafx.h - MultiThreadedDebug - libpng\;zlib\;%(AdditionalIncludeDirectories) - - - - - true - - - - - - Level3 - true - true - true - _CRT_SECURE_NO_WARNINGS;NDEBUG;_LIB;%(PreprocessorDefinitions) - true - stdcpp20 - Use - stdafx.h - true - stdafx.h - MultiThreaded - libpng\;zlib\;%(AdditionalIncludeDirectories) - - - - - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Default - - - NotUsing - NotUsing - - - - - Default - - - NotUsing - NotUsing - - - - - Default - - - NotUsing - NotUsing - - - - - Default - - - NotUsing - NotUsing - - - - - Default - - - NotUsing - NotUsing - - - - - Default - - - NotUsing - NotUsing - - - - - Default - - - NotUsing - NotUsing - - - - - Default - - - NotUsing - NotUsing - - - - - Default - - - NotUsing - NotUsing - - - - - Default - - - NotUsing - NotUsing - - - - - Default - - - NotUsing - NotUsing - - - - - Default - - - NotUsing - NotUsing - - - - - Default - - - NotUsing - NotUsing - - - - - Default - - - NotUsing - NotUsing - - - - - Default - - - NotUsing - NotUsing - - - - - Default - - - NotUsing - NotUsing - - - - - - - - - - - Create - Create - Create - Create - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 18.0 + Win32Proj + {cc99eb47-7231-4067-8717-c6bf4abde338} + render + 10.0 + Render_PC + + + + StaticLibrary + true + v145 + Unicode + + + StaticLibrary + false + v145 + true + Unicode + + + StaticLibrary + true + v145 + Unicode + + + StaticLibrary + false + v110 + true + Unicode + + + + + + + + + + + + + + + + + + + + + 4J_$(ProjectName)_d + + + 4J_$(ProjectName) + + + + Level3 + true + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + stdcpp20 + Use + pch.h + + + + + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + stdcpp20 + Use + pch.h + + + + + true + + + + + Level3 + true + _CRT_SECURE_NO_WARNINGS;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + stdcpp20 + Use + stdafx.h + true + stdafx.h + MultiThreadedDebug + libpng\;zlib\;%(AdditionalIncludeDirectories) + + + + + true + + + + + + Level3 + true + true + true + _CRT_SECURE_NO_WARNINGS;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + stdcpp20 + Use + stdafx.h + true + stdafx.h + MultiThreaded + libpng\;zlib\;%(AdditionalIncludeDirectories) + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Default + + + NotUsing + NotUsing + + + + + Default + + + NotUsing + NotUsing + + + + + Default + + + NotUsing + NotUsing + + + + + Default + + + NotUsing + NotUsing + + + + + Default + + + NotUsing + NotUsing + + + + + Default + + + NotUsing + NotUsing + + + + + Default + + + NotUsing + NotUsing + + + + + Default + + + NotUsing + NotUsing + + + + + Default + + + NotUsing + NotUsing + + + + + Default + + + NotUsing + NotUsing + + + + + Default + + + NotUsing + NotUsing + + + + + Default + + + NotUsing + NotUsing + + + + + Default + + + NotUsing + NotUsing + + + + + Default + + + NotUsing + NotUsing + + + + + Default + + + NotUsing + NotUsing + + + + + Default + + + NotUsing + NotUsing + + + + + + + + + + + Create + Create + Create + Create + + + + + \ No newline at end of file diff --git a/Windows_Libs/Dev/Render/Renderer.h b/Windows_Libs/Dev/Render/Renderer.h index d3f93e8..92340ba 100644 --- a/Windows_Libs/Dev/Render/Renderer.h +++ b/Windows_Libs/Dev/Render/Renderer.h @@ -1,10 +1,133 @@ #pragma once #include "4J_Render.h" +#include +#include +#include #define MAX_MIP_LEVELS 5 class Renderer { +public: + struct Context; + struct CommandBuffer; + + void Tick(); + void UpdateGamma(unsigned short usGamma); + void MatrixMode(int type); + void MatrixSetIdentity(); + void MatrixTranslate(float x, float y, float z); + void MatrixRotate(float angle, float x, float y, float z); + void MatrixScale(float x, float y, float z); + void MatrixPerspective(float fovy, float aspect, float zNear, float zFar); + void MatrixOrthogonal(float left, float right, float bottom, float top, float zNear, float zFar); + void MatrixPop(); + void MatrixPush(); + void MatrixMult(float* mat); + const float* MatrixGet(int type); + void Set_matrixDirty(); + void Initialise(ID3D11Device* pDevice, IDXGISwapChain* pSwapChain); + ID3D11DeviceContext* InitialiseContext(bool fromPresent); + void StartFrame(); + void DoScreenGrabOnNextPresent(); + void Present(); + void Clear(int flags, D3D11_RECT* pRect); + void SetClearColour(const float colourRGBA[4]); + bool IsWidescreen(); + bool IsHiDef(); + void CaptureThumbnail(ImageFileBuffer* pngOut); + void CaptureScreen(ImageFileBuffer* jpgOut, XSOCIAL_PREVIEWIMAGE* previewOut); + void BeginConditionalSurvey(int identifier); + void EndConditionalSurvey(); + void BeginConditionalRendering(int identifier); + void EndConditionalRendering(); + void DrawVertices(C4JRender::ePrimitiveType PrimitiveType, int count, void* dataIn, C4JRender::eVertexType vType, C4JRender::ePixelShaderType psType); + void DrawVertexBuffer(C4JRender::ePrimitiveType PrimitiveType, int count, ID3D11Buffer* buffer, C4JRender::eVertexType vType, C4JRender::ePixelShaderType psType); + void CBuffLockStaticCreations(); + int CBuffCreate(int count); + void CBuffDelete(int first, int count); + void CBuffStart(int index, bool full); + void CBuffClear(int index); + int CBuffSize(int index); + void CBuffEnd(); + bool CBuffCall(int index, bool full); + void CBuffTick(); + void CBuffDeferredModeStart(); + void CBuffDeferredModeEnd(); + int TextureCreate(); + void TextureFree(int idx); + void TextureBind(int idx); + void TextureBindVertex(int idx); + void TextureSetTextureLevels(int levels); + int TextureGetTextureLevels(); + void TextureSetParam(int param, int value); + void TextureDynamicUpdateStart(); + void TextureDynamicUpdateEnd(); + void TextureData(int width, int height, void* data, int level, C4JRender::eTextureFormat format); + void TextureDataUpdate(int xoffset, int yoffset, int width, int height, void* data, int level); + HRESULT LoadTextureData(const char* szFilename, D3DXIMAGE_INFO* pSrcInfo, int** ppDataOut); + HRESULT LoadTextureData(BYTE* pbData, DWORD dwBytes, D3DXIMAGE_INFO* pSrcInfo, int** ppDataOut); + HRESULT SaveTextureData(const char* szFilename, D3DXIMAGE_INFO* pSrcInfo, int* ppDataOut); + HRESULT SaveTextureDataToMemory(void* pOutput, int outputCapacity, int* outputLength, int width, int height, int* ppDataIn); + void TextureGetStats(); + ID3D11ShaderResourceView* TextureGetTexture(int idx); + void StateSetColour(float r, float g, float b, float a); + void StateSetDepthMask(bool enable); + void StateSetBlendEnable(bool enable); + void StateSetBlendFunc(int src, int dst); + void StateSetBlendFactor(unsigned int colour); + void StateSetAlphaFunc(int func, float param); + void StateSetDepthFunc(int func); + void StateSetFaceCull(bool enable); + void StateSetFaceCullCW(bool enable); + void StateSetLineWidth(float width); + void StateSetWriteEnable(bool red, bool green, bool blue, bool alpha); + void StateSetDepthTestEnable(bool enable); + void StateSetAlphaTestEnable(bool enable); + void StateSetDepthSlopeAndBias(float slope, float bias); + void StateSetFogEnable(bool enable); + void StateSetFogMode(int mode); + void StateSetFogNearDistance(float dist); + void StateSetFogFarDistance(float dist); + void StateSetFogDensity(float density); + void StateSetFogColour(float red, float green, float blue); + void StateSetLightingEnable(bool enable); + void StateSetVertexTextureUV(float u, float v); + void StateSetLightColour(int light, float red, float green, float blue); + void StateSetLightAmbientColour(float red, float green, float blue); + void StateSetLightDirection(int light, float x, float y, float z); + void StateSetLightEnable(int light, bool enable); + void StateSetViewport(C4JRender::eViewportType viewportType); + void StateSetEnableViewportClipPlanes(bool enable); + void StateSetTexGenCol(int col, float x, float y, float z, float w, bool eyeSpace); + void StateSetStencil(D3D11_COMPARISON_FUNC function, uint8_t stencil_ref, uint8_t stencil_func_mask, uint8_t stencil_write_mask); + void StateSetForceLOD(int LOD); + void BeginEvent(LPCWSTR eventName); + void EndEvent(); + void Suspend(); + bool Suspended(); + void Resume(); + void StateUpdate(); + +private: + void SetupShaders(); + void ConvertLinearToPng(ImageFileBuffer* pngOut, unsigned char* linearData, unsigned int width, unsigned int height); + void DrawVertexSetup(C4JRender::eVertexType vType, C4JRender::ePixelShaderType psType, C4JRender::ePrimitiveType primitiveType, int* count, bool* drawIndexed); + void UpdateTexGenState(); + void UpdateLightingState(); + void UpdateViewportState(); + void UpdateFogState(); + void UpdateTextureState(bool vertexSampler); + void MultWithStack(DirectX::XMMATRIX matrix); + ID3D11DepthStencilState* GetManagedDepthStencilState(); + ID3D11BlendState* GetManagedBlendState(); + ID3D11RasterizerState* GetManagedRasterizerState(); + ID3D11SamplerState* GetManagedSamplerState(); + void DeleteInternalBuffer(int index); + Renderer::Context& getContext(); + static D3D11_PRIMITIVE_TOPOLOGY* m_Topologies; + static DXGI_FORMAT textureFormats[C4JRender::MAX_TEXTURE_FORMATS]; + public: struct Texture @@ -12,10 +135,10 @@ public: bool allocated; ID3D11Texture2D* texture; ID3D11ShaderResourceView* view; - DWORD dword18; - DWORD mip_levels; - DWORD dword20; - DWORD param; + DWORD textureFlags; + DWORD mipLevels; + DWORD textureFormat; + DWORD samplerParams; }; struct TexgenCBuffer @@ -46,10 +169,34 @@ public: struct CommandBuffer { + CommandBuffer(bool full); + ~CommandBuffer(); + void StartRecording(); + void EndRecording(ID3D11Device* device); + std::uint64_t GetAllocated(); + bool IsBusy(); + void AddMatrix(const float* matrix); + void AddVertices(unsigned int stride, unsigned int count, void* dataIn, Renderer::Context& context); + void BindTexture(int idx); + void SetColor(float r, float g, float b, float a); + void SetDepthFunc(int func); + void SetDepthMask(bool enable); + void SetDepthTestEnable(bool enable); + void SetLightingEnable(bool enable); + void SetLightEnable(int light, bool enable); + void SetLightDirection(int light, float x, float y, float z); + void SetLightColour(int light, float r, float g, float b); + void SetLightAmbientColour(float r, float g, float b); + void SetBlendEnable(bool enable); + void SetBlendFunc(int src, int dst); + void SetBlendFactor(unsigned int factor); + void SetFaceCull(bool enable); + void Render(C4JRender::eVertexType vertexType, Renderer::Context& context, int primitiveType); + struct Command { Renderer::eCommandType m_command_type; - BYTE gap4[12]; + BYTE commandPadding[12]; union { @@ -106,8 +253,8 @@ public: struct { int m_light_index; - float m_direction[3]; - //DirectX::XMVECTOR m_direction; + float padding[3]; + float m_direction[4]; } set_light_direction; struct @@ -118,6 +265,7 @@ public: struct { + BYTE padding; float m_color[3]; } set_light_ambient_colour; @@ -143,6 +291,13 @@ public: } set_face_cull; }; }; + ID3D11Buffer* m_vertexBuffer; + void* m_vertexData; + std::uint64_t m_vertexDataLength; + std::vector m_commands; + std::uint64_t m_allocated; + BYTE isActive; + BYTE paddingAfterActive[7]; }; @@ -158,156 +313,138 @@ public: struct Context { + Context(ID3D11Device* device, ID3D11DeviceContext* deviceContext); ID3D11DeviceContext* m_pDeviceContext; - ID3DUserDefinedAnnotation* pvoid8; - DWORD dword10; - BYTE gap14[12]; - DirectX::XMMATRIX arraymatrix20[4][16]; - bool bool1020; - bool bool1021; - bool bool1022; - bool bool1023; - DWORD arraydword1024[4]; - DWORD stackType; - DWORD textureIdx; - BYTE byte103C; - BYTE byte103D; - BYTE byte103E; - float float1040; - BYTE byte1044; - BYTE byte1045; - BYTE gap1046[14]; - DWORD dword1054; - DWORD dword1058; - DWORD dword105C; - BYTE gap1060[4]; - BYTE byte1064; - BYTE gap1065[2]; - BYTE byte1067; - DWORD dword1068; - BYTE gap106C[4]; - char char1070; - BYTE gap1071[79]; - ID3D11Buffer* pid3d11buffer10C0; - ID3D11Buffer* pid3d11buffer10C8; - ID3D11Buffer* pid3d11buffer10D0; - ID3D11Buffer* pid3d11buffer10D8; - ID3D11Buffer* pid3d11buffer10E0; - ID3D11Buffer* pid3d11buffer10E8; - ID3D11Buffer* pid3d11buffer10F0; - ID3D11Buffer* pid3d11buffer10F8; - ID3D11Buffer* pid3d11buffer1100; - ID3D11Buffer* pid3d11buffer1108; - ID3D11Buffer* pid3d11buffer1110; - ID3D11Buffer* pid3d11buffer1118; - ID3D11Buffer* pid3d11buffer1120; - ID3D11Buffer* pid3d11buffer1128; - ID3D11Buffer* pid3d11buffer1130; - ID3D11Buffer* pid3d11buffer1138; - uint64_t qword1140; - DWORD dword1148; - BYTE gap114C[4]; - ID3D11Buffer* pid3d11buffer1150; - BYTE gap1158[8]; - DirectX::XMMATRIX arraymatrix1160[2]; - Renderer::CommandBuffer* qword11E0; - DWORD dword11E8; - DWORD dword11EC; - DWORD dword11F0; - BYTE byte11F4; - BYTE gap11F5[3]; - std::vector std__vector11F8; - DWORD dword1218; - DWORD dword121C; - DWORD dword1220; - DWORD dword1224; - DWORD dword1228; - DWORD dword122C; - DWORD dword1230; - DWORD dword1234; - DWORD dword1238; - BYTE byte123C; - BYTE gap123D[227]; - DWORD dword1320; - DWORD dword1324; - DWORD dword1328; - DWORD dword132C; - BYTE byte1330; - BYTE byte1331; - DWORD dword1334; - DWORD dword1338; - DWORD dword133C; - DWORD dword1340; - DWORD dword1344; - DWORD dword1348; - DWORD dword134C; - DWORD dword1350; - DWORD dword1354; - DWORD dword1358; - DWORD dword135C; - DWORD dword1360; - DWORD dword1364; - DWORD dword1368; - DWORD dword136C; - DWORD dword1370; - DWORD dword1374; - DWORD dword1378; - DWORD dword137C; - DWORD dword1380; - DWORD dword1384; - DWORD dword1388; + ID3DUserDefinedAnnotation* userAnnotation; + DWORD contextStateFlags; + BYTE paddingAfterFlags[12]; + DirectX::XMMATRIX matrixStacks[4][16]; + bool matrixDirty[4]; + DWORD matrixStackDepth[4]; + DWORD matrixModeType; + DWORD boundTextureIndex; + BYTE faceCullEnabled; + BYTE depthTestEnabled; + BYTE alphaTestEnabled; + float alphaReference; + BYTE depthWriteEnabled; + BYTE fogEnabled; + BYTE paddingAfterFogFlags[2]; + float fogNearDistance; + float fogFarDistance; + float fogDensity; + float fogColourRed; + float fogColourBlue; + float fogColourGreen; + DWORD fogMode; + BYTE lightingEnabled; + BYTE lightEnabled[2]; + BYTE lightingDirty; + DWORD forcedLOD; + BYTE paddingAfterForceLOD[4]; + DirectX::XMFLOAT4 lightDirection[2]; + DirectX::XMFLOAT4 lightColour[2]; + DirectX::XMFLOAT4 lightAmbientColour; + ID3D11Buffer* cbMatrix0; + ID3D11Buffer* cbMatrix1; + ID3D11Buffer* cbMatrix2; + ID3D11Buffer* cbMatrix3; + ID3D11Buffer* cbVertexTexcoord; + ID3D11Buffer* cbFogParams; + ID3D11Buffer* cbLighting; + ID3D11Buffer* cbTexGen; + ID3D11Buffer* cbAux0; + ID3D11Buffer* cbAux1; + ID3D11Buffer* cbColour; + ID3D11Buffer* cbFogColour; + ID3D11Buffer* cbAux2; + ID3D11Buffer* cbAlphaTest; + ID3D11Buffer* cbAux3; + ID3D11Buffer* cbAux4; + uint64_t dynamicVertexBase; + DWORD dynamicVertexOffset; + BYTE paddingAfterDynamicOffset[4]; + ID3D11Buffer* dynamicVertexBuffer; + BYTE paddingBeforeTexGen[8]; + DirectX::XMMATRIX texGenMatrices[2]; + Renderer::CommandBuffer* commandBuffer; + DWORD recordingBufferIndex; + DWORD recordingVertexType; + DWORD recordingPrimitiveType; + BYTE deferredModeEnabled; + BYTE paddingAfterDeferredModeEnabled[3]; + std::vector deferredBuffers; + D3D11_BLEND_DESC blendDesc; + D3D11_DEPTH_STENCIL_DESC depthStencilDesc; + D3D11_RASTERIZER_DESC rasterizerDesc; + float blendFactor[4]; + DWORD reservedContext0; + DWORD reservedContext1; }; static DWORD tlsIdx; + static unsigned int s_auiWidths[MAX_MIP_LEVELS + 1]; + static unsigned int s_auiHeights[MAX_MIP_LEVELS + 1]; + static D3D11_INPUT_ELEMENT_DESC g_vertex_PTN_Elements_PF3_TF2_CB4_NB4_XW1[5]; + static D3D11_INPUT_ELEMENT_DESC g_vertex_PTN_Elements_Compressed[2]; + static D3D11_PRIMITIVE_TOPOLOGY g_topologies[C4JRender::PRIMITIVE_TYPE_COUNT]; + static int totalAlloc; + static _RTL_CRITICAL_SECTION totalAllocCS; float m_fClearColor[4]; ID3D11Device* m_pDevice; ID3D11DeviceContext* m_pDeviceContext; - uint64_t qword20; - ID3D11RenderTargetView* pid3d11rendertargetview28; - ID3D11RenderTargetView* arrayqword30[4]; - ID3D11ShaderResourceView* pid3d11shaderresourceview50; - ID3D11Resource* arrayqword58[4]; - ID3D11Texture2D* pid3d11texture2d78; - BYTE gap80[24]; - ID3D11DepthStencilView* qword98; - ID3D11VertexShader** qwordA0; - BYTE gapA8[16]; - uint64_t qwordB8; - BYTE gapC0[16]; - uint64_t qwordD0; - ID3D11InputLayout** qwordD8; - ID3D11Buffer* qwordE0; - ID3D11Buffer* qwordE8; - DWORD dwordF0; - WORD wordF4; - BYTE gapF6[2]; - DWORD dwordF8; - BYTE byteFC; - BYTE gapFD[3]; + IDXGISwapChain* m_pSwapChain; + ID3D11RenderTargetView* renderTargetView; + ID3D11RenderTargetView* renderTargetViews[4]; + ID3D11ShaderResourceView* renderTargetShaderResourceView; + ID3D11ShaderResourceView* renderTargetShaderResourceViews[4]; + ID3D11Texture2D* renderTargetTextures[4]; + ID3D11DepthStencilView* depthStencilView; + ID3D11VertexShader** vertexShaderTable; + ID3D11VertexShader* screenSpaceVertexShader; + ID3D11VertexShader* screenClearVertexShader; + ID3D11PixelShader** pixelShaderTable; + ID3D11PixelShader* screenSpacePixelShader; + ID3D11PixelShader* screenClearPixelShader; + unsigned int* vertexStrideTable; + ID3D11InputLayout** inputLayoutTable; + ID3D11Buffer* quadIndexBuffer; + ID3D11Buffer* fanIndexBuffer; + DWORD defaultTextureIndex; + WORD reservedRendererWord0; + BYTE paddingAfterRendererWord0[2]; + DWORD presentCount; + BYTE rendererFlag0; + BYTE paddingAfterRendererFlag0[3]; _RTL_CRITICAL_SECTION rtl_critical_section100; - DWORD dword128; - DWORD dword12C; + DWORD activeVertexType; + DWORD activePixelType; C4JRender::eViewportType m_ViewportType; - BYTE byte134; - BYTE gap135[3]; + BYTE reservedRendererByte0; + BYTE paddingAfterViewportType[3]; Renderer::Texture m_textures[512]; - DWORD dword5138; - DWORD dword513C; - BYTE byte5140; - BYTE gap5141[3]; - DWORD dword5144; - void* pvoid5148; - void* pvoid5150; - uint64_t qword5158; - void* pvoid5160; - void* pvoid5168; - void* pvoid5170; - DWORD dword5178; - DWORD dword517C; - BYTE gap5180[328]; - BYTE m_bShouldScreenGrabNextFrame; + DWORD backBufferWidth; + DWORD backBufferHeight; + BYTE reservedRendererByte1; + BYTE paddingAfterRendererByte1[3]; + DWORD reservedRendererDword1; + void* reservedRendererPtr2; + void* reservedRendererPtr3; + uint64_t reservedRendererPtr1; + void* reservedRendererPtr4; + void* reservedRendererPtr5; + void* reservedRendererPtr6; + DWORD reservedRendererDword2; + DWORD reservedRendererDword3; + std::unordered_map managedBlendStates; + std::unordered_map managedDepthStencilStates; + std::unordered_map managedSamplerStates; + std::unordered_map managedRasterizerStates; + BYTE shouldScreenGrabNextFrame; + BYTE suspended; + BYTE paddingAfterSuspendState[2]; }; // Singleton -extern Renderer InternalRenderManager; \ No newline at end of file +extern Renderer InternalRenderManager; diff --git a/Windows_Libs/Dev/Render/RendererCBuff.cpp b/Windows_Libs/Dev/Render/RendererCBuff.cpp index 6f70f09..042125b 100644 --- a/Windows_Libs/Dev/Render/RendererCBuff.cpp +++ b/Windows_Libs/Dev/Render/RendererCBuff.cpp @@ -1 +1,872 @@ #pragma once +#include "Renderer.h" + +#include +#include +#include +#include +#include +#include + +Renderer::CommandBuffer::CommandBuffer(bool full) + : m_vertexBuffer(nullptr) + , m_vertexData(nullptr) + , m_vertexDataLength(0) + , m_commands() + , m_allocated(0x1000) + , isActive(full ? 1 : 0) +{ + std::memset(paddingAfterActive, 0, sizeof(paddingAfterActive)); + m_vertexData = std::malloc(m_allocated); + EnterCriticalSection(&Renderer::totalAllocCS); + Renderer::totalAlloc += static_cast(m_allocated); + LeaveCriticalSection(&Renderer::totalAllocCS); +} + +Renderer::CommandBuffer::~CommandBuffer() +{ + if (m_vertexBuffer) + { + m_vertexBuffer->Release(); + } + + std::free(m_vertexData); + + EnterCriticalSection(&Renderer::totalAllocCS); + Renderer::totalAlloc -= static_cast(m_allocated); + LeaveCriticalSection(&Renderer::totalAllocCS); +} + +void Renderer::CommandBuffer::StartRecording() +{ +} + +void Renderer::CommandBuffer::EndRecording(ID3D11Device* device) +{ + if (m_vertexDataLength != 0) + { + D3D11_BUFFER_DESC desc = {}; + desc.ByteWidth = m_vertexDataLength; + desc.Usage = D3D11_USAGE_IMMUTABLE; + desc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + + D3D11_SUBRESOURCE_DATA data = {}; + data.pSysMem = m_vertexData; + device->CreateBuffer(&desc, &data, &m_vertexBuffer); + } + + std::free(m_vertexData); + m_vertexData = nullptr; +} + +std::uint64_t Renderer::CommandBuffer::GetAllocated() +{ + return m_allocated; +} + +bool Renderer::CommandBuffer::IsBusy() +{ + return false; +} + +void Renderer::CommandBuffer::AddMatrix(const float* matrix) +{ + Command command = {}; + command.m_command_type = COMMAND_ADD_MATRIX; + std::memcpy(command.add_matrix.m_matrix, matrix, sizeof(command.add_matrix.m_matrix)); + m_commands.push_back(command); +} + +void Renderer::CommandBuffer::AddVertices(unsigned int stride, unsigned int count, void* dataIn, Renderer::Context& context) +{ + if (context.matrixDirty[3]) + { + this->AddMatrix(InternalRenderManager.MatrixGet(3)); + context.matrixDirty[3] = false; + } + + const std::uint64_t vertexOffset = m_vertexDataLength; + const std::uint64_t copySize = std::uint64_t(stride) * std::uint64_t(count); + + Command command = {}; + command.m_command_type = COMMAND_ADD_VERTICES; + command.add_vertices.m_vertex_index_start = (unsigned int)vertexOffset; + command.add_vertices.m_vertex_count = count; + + m_vertexDataLength = vertexOffset + copySize; + if (m_vertexDataLength > m_allocated) + { + EnterCriticalSection(&Renderer::totalAllocCS); + Renderer::totalAlloc -= static_cast(m_allocated); + LeaveCriticalSection(&Renderer::totalAllocCS); + + m_allocated = ((m_vertexDataLength + (0x1000u - 1u)) & ~(0x1000u - 1u)); + m_vertexData = std::realloc(m_vertexData, m_allocated); + + EnterCriticalSection(&Renderer::totalAllocCS); + Renderer::totalAlloc += static_cast(m_allocated); + LeaveCriticalSection(&Renderer::totalAllocCS); + } + + const std::size_t byteCount = std::size_t(stride) * std::size_t(count); + std::memcpy(static_cast(m_vertexData) + vertexOffset, dataIn, byteCount); + m_commands.push_back(command); +} + +void Renderer::CommandBuffer::BindTexture(int idx) +{ + Command command = {}; + command.m_command_type = COMMAND_BIND_TEXTURE; + command.bind_texture.m_texture_index = idx; + m_commands.push_back(command); +} + +void Renderer::CommandBuffer::SetColor(float r, float g, float b, float a) +{ + Command command = {}; + command.m_command_type = COMMAND_SET_COLOR; + command.set_color.m_color[0] = r; + command.set_color.m_color[1] = g; + command.set_color.m_color[2] = b; + command.set_color.m_color[3] = a; + m_commands.push_back(command); +} + +void Renderer::CommandBuffer::SetDepthFunc(int func) +{ + Command command = {}; + command.m_command_type = COMMAND_SET_DEPTH_FUNC; + command.set_depth_func.m_depth_func = func; + m_commands.push_back(command); +} + +void Renderer::CommandBuffer::SetDepthMask(bool enable) +{ + Command command = {}; + command.m_command_type = COMMAND_SET_DEPTH_MASK; + command.set_depth_mask.m_enable = enable; + m_commands.push_back(command); +} + +void Renderer::CommandBuffer::SetDepthTestEnable(bool enable) +{ + Command command = {}; + command.m_command_type = COMMAND_SET_DEPTH_TEST; + command.set_depth_test.m_enable = enable; + m_commands.push_back(command); +} + +void Renderer::CommandBuffer::SetLightingEnable(bool enable) +{ + Command command = {}; + command.m_command_type = COMMAND_SET_LIGHTING_ENABLE; + command.set_lighting_enable.m_enable = enable; + m_commands.push_back(command); +} + +void Renderer::CommandBuffer::SetLightEnable(int light, bool enable) +{ + Command command = {}; + command.m_command_type = COMMAND_SET_LIGHT_ENABLE; + command.set_light_enable.m_light_index = light; + command.set_light_enable.m_enable = enable; + m_commands.push_back(command); +} + +void Renderer::CommandBuffer::SetLightDirection(int light, float x, float y, float z) +{ + Renderer::Context& context = InternalRenderManager.getContext(); + const std::uint32_t depth = context.matrixStackDepth[3]; + const DirectX::XMMATRIX& matrix = context.matrixStacks[3][depth]; + + DirectX::XMVECTOR direction = DirectX::XMVectorSet(x, y, z, 0.0f); + direction = DirectX::XMVector3TransformNormal(direction, matrix); + direction = DirectX::XMVector3Normalize(direction); + + Command command = {}; + command.m_command_type = COMMAND_SET_LIGHT_DIRECTION; + command.set_light_direction.m_light_index = light; + DirectX::XMFLOAT4 outDirection; + DirectX::XMStoreFloat4(&outDirection, direction); + command.set_light_direction.m_direction[0] = outDirection.x; + command.set_light_direction.m_direction[1] = outDirection.y; + command.set_light_direction.m_direction[2] = outDirection.z; + command.set_light_direction.m_direction[3] = outDirection.w; + m_commands.push_back(command); +} + +void Renderer::CommandBuffer::SetLightColour(int light, float r, float g, float b) +{ + Command command = {}; + command.m_command_type = COMMAND_SET_LIGHT_COLOUR; + command.set_light_colour.m_light_index = light; + command.set_light_colour.m_color[0] = r; + command.set_light_colour.m_color[1] = g; + command.set_light_colour.m_color[2] = b; + m_commands.push_back(command); +} + +void Renderer::CommandBuffer::SetLightAmbientColour(float r, float g, float b) +{ + Command command = {}; + command.m_command_type = COMMAND_SET_LIGHT_AMBIENT_COLOUR; + command.set_light_ambient_colour.m_color[0] = r; + command.set_light_ambient_colour.m_color[1] = g; + command.set_light_ambient_colour.m_color[2] = b; + m_commands.push_back(command); +} + +void Renderer::CommandBuffer::SetBlendEnable(bool enable) +{ + Command command = {}; + command.m_command_type = COMMAND_SET_BLEND_ENABLE; + command.set_blend_enable.m_enable = enable; + m_commands.push_back(command); +} + +void Renderer::CommandBuffer::SetBlendFunc(int src, int dst) +{ + Command command = {}; + command.m_command_type = COMMAND_SET_BLEND_FUNC; + command.set_blend_func.m_src = src; + command.set_blend_func.m_dst = dst; + m_commands.push_back(command); +} + +void Renderer::CommandBuffer::SetBlendFactor(unsigned int factor) +{ + Command command = {}; + command.m_command_type = COMMAND_SET_BLEND_FACTOR; + command.set_blend_factor.m_blend_factor = factor; + m_commands.push_back(command); +} + +void Renderer::CommandBuffer::SetFaceCull(bool enable) +{ + Command command = {}; + command.m_command_type = COMMAND_SET_FACE_CULL; + command.set_face_cull.m_enable = enable; + m_commands.push_back(command); +} + +void Renderer::CommandBuffer::Render(C4JRender::eVertexType vertexType, Renderer::Context& context, int primitiveType) +{ + if (!m_vertexBuffer) + { + return; + } + + int drawVertexType = vertexType; + int shaderVertexType = drawVertexType; + bool matrixOverride = false; + + for (std::vector::const_iterator it = m_commands.begin(); it != m_commands.end(); ++it) + { + const Command& command = *it; + switch (command.m_command_type) + { + case COMMAND_ADD_MATRIX: + { + if (drawVertexType == C4JRender::VERTEX_TYPE_COMPRESSED) + { + const float row[4] = + { + command.add_matrix.m_matrix[12], + command.add_matrix.m_matrix[13], + command.add_matrix.m_matrix[14], + command.add_matrix.m_matrix[15] + }; + D3D11_MAPPED_SUBRESOURCE mappedAux0 = {}; + context.m_pDeviceContext->Map(context.cbAux0, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedAux0); + std::memcpy(mappedAux0.pData, row, sizeof(row)); + context.m_pDeviceContext->Unmap(context.cbAux0, 0); + } + else + { + D3D11_MAPPED_SUBRESOURCE mappedMatrix1 = {}; + context.m_pDeviceContext->Map(context.cbMatrix1, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedMatrix1); + std::memcpy(mappedMatrix1.pData, command.add_matrix.m_matrix, sizeof(command.add_matrix.m_matrix)); + context.m_pDeviceContext->Unmap(context.cbMatrix1, 0); + matrixOverride = true; + } + break; + } + case COMMAND_ADD_VERTICES: + { + if (isActive) + { + InternalRenderManager.UpdateLightingState(); + + if (drawVertexType == C4JRender::VERTEX_TYPE_PF3_TF2_CB4_NB4_XW1) + { + if (context.lightingEnabled) + { + drawVertexType = C4JRender::VERTEX_TYPE_PF3_TF2_CB4_NB4_XW1_LIT; + shaderVertexType = C4JRender::VERTEX_TYPE_PF3_TF2_CB4_NB4_XW1_LIT; + } + } + else if (drawVertexType == C4JRender::VERTEX_TYPE_PF3_TF2_CB4_NB4_XW1_LIT && !context.lightingEnabled) + { + drawVertexType = C4JRender::VERTEX_TYPE_PF3_TF2_CB4_NB4_XW1; + shaderVertexType = C4JRender::VERTEX_TYPE_PF3_TF2_CB4_NB4_XW1; + } + + if (static_cast(drawVertexType) != InternalRenderManager.activeVertexType) + { + context.m_pDeviceContext->VSSetShader(InternalRenderManager.vertexShaderTable[shaderVertexType], nullptr, 0); + context.m_pDeviceContext->IASetInputLayout(InternalRenderManager.inputLayoutTable[shaderVertexType]); + InternalRenderManager.activeVertexType = drawVertexType; + } + } + + unsigned int drawCount = command.add_vertices.m_vertex_count; + bool drawIndexed = false; + if (primitiveType == C4JRender::PRIMITIVE_TYPE_QUAD_LIST) + { + drawCount = (drawCount * 6u) / 4u; + drawIndexed = true; + } + else if (primitiveType == C4JRender::PRIMITIVE_TYPE_TRIANGLE_FAN) + { + drawCount = (drawCount - 2u) * 3u; + drawIndexed = true; + } + + ID3D11Buffer* buffer = m_vertexBuffer; + const UINT stride = InternalRenderManager.vertexStrideTable[drawVertexType]; + const UINT offset = command.add_vertices.m_vertex_index_start; + context.m_pDeviceContext->IASetVertexBuffers(0, 1, &buffer, &stride, &offset); + + if (drawIndexed) + { + context.m_pDeviceContext->DrawIndexed(drawCount, 0, 0); + } + else + { + context.m_pDeviceContext->Draw(drawCount, 0); + } + break; + } + case COMMAND_BIND_TEXTURE: + { + context.boundTextureIndex = command.bind_texture.m_texture_index; + ID3D11ShaderResourceView* view = InternalRenderManager.m_textures[context.boundTextureIndex].view; + context.m_pDeviceContext->PSSetShaderResources(0, 1, &view); + InternalRenderManager.UpdateTextureState(false); + break; + } + case COMMAND_SET_COLOR: + { + D3D11_MAPPED_SUBRESOURCE mappedColour = {}; + context.m_pDeviceContext->Map(context.cbColour, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedColour); + std::memcpy(mappedColour.pData, command.set_color.m_color, sizeof(command.set_color.m_color)); + context.m_pDeviceContext->Unmap(context.cbColour, 0); + break; + } + case COMMAND_SET_DEPTH_FUNC: + { + context.depthStencilDesc.DepthFunc = static_cast(command.set_depth_func.m_depth_func); + context.m_pDeviceContext->OMSetDepthStencilState(InternalRenderManager.GetManagedDepthStencilState(), 0); + break; + } + case COMMAND_SET_DEPTH_MASK: + { + context.depthWriteEnabled = command.set_depth_mask.m_enable ? 1 : 0; + context.depthStencilDesc.DepthWriteMask = command.set_depth_mask.m_enable ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO; + context.m_pDeviceContext->OMSetDepthStencilState(InternalRenderManager.GetManagedDepthStencilState(), 0); + break; + } + case COMMAND_SET_DEPTH_TEST: + { + context.depthTestEnabled = command.set_depth_test.m_enable ? 1 : 0; + context.depthStencilDesc.DepthEnable = command.set_depth_test.m_enable ? TRUE : FALSE; + context.m_pDeviceContext->OMSetDepthStencilState(InternalRenderManager.GetManagedDepthStencilState(), 0); + break; + } + case COMMAND_SET_LIGHTING_ENABLE: + { + context.lightingEnabled = command.set_lighting_enable.m_enable ? 1 : 0; + break; + } + case COMMAND_SET_LIGHT_ENABLE: + { + const int light = command.set_light_enable.m_light_index; + if (light >= 0 && light < 2) + { + context.lightEnabled[light] = command.set_light_enable.m_enable ? 1 : 0; + context.lightingDirty = 1; + } + break; + } + case COMMAND_SET_LIGHT_DIRECTION: + { + const int light = command.set_light_direction.m_light_index; + if (light >= 0 && light < 2) + { + context.lightDirection[light].x = command.set_light_direction.m_direction[0]; + context.lightDirection[light].y = command.set_light_direction.m_direction[1]; + context.lightDirection[light].z = command.set_light_direction.m_direction[2]; + context.lightDirection[light].w = command.set_light_direction.m_direction[3]; + context.lightingDirty = 1; + } + break; + } + case COMMAND_SET_LIGHT_COLOUR: + { + const int light = command.set_light_colour.m_light_index; + if (light >= 0 && light < 2) + { + context.lightColour[light].x = command.set_light_colour.m_color[0]; + context.lightColour[light].y = command.set_light_colour.m_color[1]; + context.lightColour[light].z = command.set_light_colour.m_color[2]; + context.lightColour[light].w = 1.0f; + context.lightingDirty = 1; + } + break; + } + case COMMAND_SET_LIGHT_AMBIENT_COLOUR: + { + context.lightAmbientColour.x = command.set_light_ambient_colour.m_color[0]; + context.lightAmbientColour.y = command.set_light_ambient_colour.m_color[1]; + context.lightAmbientColour.z = command.set_light_ambient_colour.m_color[2]; + context.lightAmbientColour.w = 1.0f; + context.lightingDirty = 1; + break; + } + case COMMAND_SET_BLEND_ENABLE: + { + context.blendDesc.RenderTarget[0].BlendEnable = command.set_blend_enable.m_enable ? TRUE : FALSE; + break; + } + case COMMAND_SET_BLEND_FUNC: + { + context.blendDesc.RenderTarget[0].SrcBlend = static_cast(command.set_blend_func.m_src); + context.blendDesc.RenderTarget[0].DestBlend = static_cast(command.set_blend_func.m_dst); + context.m_pDeviceContext->OMSetBlendState(InternalRenderManager.GetManagedBlendState(), context.blendFactor, 0xFFFFFFFFu); + break; + } + case COMMAND_SET_BLEND_FACTOR: + { + const unsigned int factor = command.set_blend_factor.m_blend_factor; + context.blendFactor[0] = float((factor >> 0) & 0xFFu) / 255.0f; + context.blendFactor[1] = float((factor >> 8) & 0xFFu) / 255.0f; + context.blendFactor[2] = float((factor >> 16) & 0xFFu) / 255.0f; + context.blendFactor[3] = float((factor >> 24) & 0xFFu) / 255.0f; + context.m_pDeviceContext->OMSetBlendState(InternalRenderManager.GetManagedBlendState(), context.blendFactor, 0xFFFFFFFFu); + break; + } + case COMMAND_SET_FACE_CULL: + { + context.rasterizerDesc.CullMode = command.set_face_cull.m_enable ? D3D11_CULL_BACK : D3D11_CULL_NONE; + context.m_pDeviceContext->RSSetState(InternalRenderManager.GetManagedRasterizerState()); + context.faceCullEnabled = command.set_face_cull.m_enable ? 1 : 0; + break; + } + default: + break; + } + } + + if (matrixOverride) + { + const DirectX::XMMATRIX identity = DirectX::XMMatrixIdentity(); + D3D11_MAPPED_SUBRESOURCE mappedIdentity = {}; + context.m_pDeviceContext->Map(context.cbMatrix1, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedIdentity); + std::memcpy(mappedIdentity.pData, &identity, sizeof(identity)); + context.m_pDeviceContext->Unmap(context.cbMatrix1, 0); + } +} + +bool Renderer::CBuffCall(int index, bool full) +{ + EnterCriticalSection(&rtl_critical_section100); + + bool result = false; + std::int16_t* externalToInternal = static_cast(reservedRendererPtr2); + const int internalIndex = externalToInternal[index]; + if (internalIndex >= 0) + { + Renderer::Context& context = this->getContext(); + const std::uint8_t vertexType = static_cast(reservedRendererPtr6)[internalIndex]; + const std::uint8_t primitiveType = reinterpret_cast(reservedRendererPtr1)[internalIndex]; + + if (full) + { + if (context.matrixDirty[0]) + { + D3D11_MAPPED_SUBRESOURCE mappedMatrix0 = {}; + context.m_pDeviceContext->Map(context.cbMatrix0, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedMatrix0); + std::memcpy(mappedMatrix0.pData, this->MatrixGet(0), sizeof(DirectX::XMMATRIX)); + context.m_pDeviceContext->Unmap(context.cbMatrix0, 0); + context.matrixDirty[0] = false; + } + + if (context.matrixDirty[1]) + { + D3D11_MAPPED_SUBRESOURCE mappedMatrix2 = {}; + context.m_pDeviceContext->Map(context.cbMatrix2, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedMatrix2); + std::memcpy(mappedMatrix2.pData, this->MatrixGet(1), sizeof(DirectX::XMMATRIX)); + context.m_pDeviceContext->Unmap(context.cbMatrix2, 0); + context.matrixDirty[1] = false; + } + + if (context.matrixDirty[2]) + { + D3D11_MAPPED_SUBRESOURCE mappedMatrix3 = {}; + context.m_pDeviceContext->Map(context.cbMatrix3, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedMatrix3); + std::memcpy(mappedMatrix3.pData, this->MatrixGet(2), sizeof(DirectX::XMMATRIX)); + context.m_pDeviceContext->Unmap(context.cbMatrix3, 0); + context.matrixDirty[2] = false; + } + + this->UpdateFogState(); + this->UpdateLightingState(); + this->UpdateViewportState(); + this->UpdateTexGenState(); + + if (vertexType != activeVertexType) + { + context.m_pDeviceContext->VSSetShader(vertexShaderTable[vertexType], nullptr, 0); + context.m_pDeviceContext->IASetInputLayout(inputLayoutTable[vertexType]); + activeVertexType = vertexType; + } + + int pixelType = 0; + if (static_cast(context.forcedLOD) > -1) + { + const float forcedLod[4] = { static_cast(static_cast(context.forcedLOD)), 0.0f, 0.0f, 0.0f }; + D3D11_MAPPED_SUBRESOURCE mappedAux4 = {}; + context.m_pDeviceContext->Map(context.cbAux4, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedAux4); + std::memcpy(mappedAux4.pData, forcedLod, sizeof(forcedLod)); + context.m_pDeviceContext->Unmap(context.cbAux4, 0); + pixelType = C4JRender::PIXEL_SHADER_TYPE_FORCELOD; + } + + if (static_cast(pixelType) != activePixelType) + { + context.m_pDeviceContext->PSSetShader(pixelShaderTable[pixelType], nullptr, 0); + activePixelType = pixelType; + } + + context.m_pDeviceContext->IASetPrimitiveTopology(m_Topologies[primitiveType]); + + ID3D11Buffer* indexBuffer = nullptr; + if (primitiveType == C4JRender::PRIMITIVE_TYPE_QUAD_LIST) + { + indexBuffer = quadIndexBuffer; + } + else if (primitiveType == C4JRender::PRIMITIVE_TYPE_TRIANGLE_FAN) + { + indexBuffer = fanIndexBuffer; + } + + context.m_pDeviceContext->IASetIndexBuffer(indexBuffer, DXGI_FORMAT_R16_UINT, 0); + } + + Renderer::CommandBuffer* commandBuffer = static_cast(reservedRendererPtr3)[internalIndex]; + commandBuffer->Render(static_cast(vertexType), context, primitiveType); + + if (full) + { + this->MultWithStack(static_cast(reservedRendererPtr4)[internalIndex]); + context.matrixStacks[3][0] = DirectX::XMMatrixIdentity(); + context.matrixDirty[3] = true; + } + + result = true; + } + + LeaveCriticalSection(&rtl_critical_section100); + return result; +} + +void Renderer::CBuffClear(int index) +{ + EnterCriticalSection(&rtl_critical_section100); + + std::int16_t* externalToInternal = static_cast(reservedRendererPtr2); + const int internalIndex = externalToInternal[index]; + if (internalIndex >= 0) + { + this->DeleteInternalBuffer(internalIndex); + externalToInternal[index] = static_cast(-2); + } + + LeaveCriticalSection(&rtl_critical_section100); +} + +int Renderer::CBuffCreate(int count) +{ + const int kMaxExternalCBuffers = 0x800000; + + EnterCriticalSection(&rtl_critical_section100); + + int first = reservedRendererDword1; + std::int16_t* externalToInternal = static_cast(reservedRendererPtr2); + + if (first < kMaxExternalCBuffers) + { + int probe = first; + int end = first + count; + while (true) + { + int cursor = probe; + while (cursor < end && cursor < kMaxExternalCBuffers && externalToInternal[cursor] == static_cast(-1)) + { + ++cursor; + } + + if (cursor >= end) + { + break; + } + + ++first; + ++probe; + ++end; + if (first >= kMaxExternalCBuffers || end > kMaxExternalCBuffers) + { + first = -1; + break; + } + } + + if (first >= 0) + { + const int allocationEnd = first + count; + for (int i = first; i < allocationEnd; ++i) + { + externalToInternal[i] = static_cast(-2); + } + + if (reservedRendererByte1) + { + reservedRendererDword1 = allocationEnd; + } + } + } + else + { + first = -1; + } + + LeaveCriticalSection(&rtl_critical_section100); + return first; +} + +void Renderer::CBuffDeferredModeEnd() +{ + Renderer::Context& context = this->getContext(); + if (!context.deferredModeEnabled) + { + return; + } + + EnterCriticalSection(&rtl_critical_section100); + context.deferredModeEnabled = 0; + + std::int16_t* externalToInternal = static_cast(reservedRendererPtr2); + int* internalToExternal = static_cast(reservedRendererPtr5); + std::uint8_t* internalVertexTypes = static_cast(reservedRendererPtr6); + std::uint8_t* internalPrimitiveTypes = reinterpret_cast(reservedRendererPtr1); + Renderer::CommandBuffer** internalBuffers = static_cast(reservedRendererPtr3); + DirectX::XMMATRIX* internalMatrices = static_cast(reservedRendererPtr4); + + for (std::vector::const_iterator it = context.deferredBuffers.begin(); it != context.deferredBuffers.end(); ++it) + { + const Renderer::DeferredCBuff& deferred = *it; + const int existingIndex = externalToInternal[deferred.m_vertex_index]; + if (existingIndex >= 0) + { + this->DeleteInternalBuffer(existingIndex); + } + + if (static_cast(reservedRendererDword2 + reservedRendererDword3 + 10u) > 16000) + { + DebugBreak(); + } + + const int internalSlot = reservedRendererDword2; + ++reservedRendererDword2; + + externalToInternal[deferred.m_vertex_index] = static_cast(internalSlot); + internalToExternal[internalSlot] = deferred.m_vertex_index; + internalVertexTypes[internalSlot] = static_cast(deferred.m_vertex_type); + internalPrimitiveTypes[internalSlot] = static_cast(deferred.m_primitive_type); + internalBuffers[internalSlot] = deferred.m_command_buf; + internalMatrices[internalSlot] = deferred.m_matrix; + } + + context.deferredBuffers.clear(); + LeaveCriticalSection(&rtl_critical_section100); +} + +void Renderer::CBuffDeferredModeStart() +{ + this->getContext().deferredModeEnabled = 1; +} + +void Renderer::CBuffDelete(int first, int count) +{ + EnterCriticalSection(&rtl_critical_section100); + + std::int16_t* externalToInternal = static_cast(reservedRendererPtr2); + const int end = first + count; + for (int i = first; i < end; ++i) + { + const int internalIndex = externalToInternal[i]; + if (internalIndex >= 0) + { + this->DeleteInternalBuffer(internalIndex); + } + + externalToInternal[i] = static_cast(-1); + } + + LeaveCriticalSection(&rtl_critical_section100); +} + +void Renderer::CBuffEnd() +{ + Renderer::Context& context = this->getContext(); + EnterCriticalSection(&rtl_critical_section100); + + if (context.deferredModeEnabled) + { + Renderer::DeferredCBuff deferred; + deferred.m_command_buf = context.commandBuffer; + deferred.m_vertex_index = context.recordingBufferIndex; + deferred.m_vertex_type = context.recordingVertexType; + deferred.m_primitive_type = context.recordingPrimitiveType; + deferred.m_matrix = context.matrixStacks[3][0]; + context.deferredBuffers.push_back(deferred); + } + else + { + std::int16_t* externalToInternal = static_cast(reservedRendererPtr2); + int* internalToExternal = static_cast(reservedRendererPtr5); + std::uint8_t* internalVertexTypes = static_cast(reservedRendererPtr6); + std::uint8_t* internalPrimitiveTypes = reinterpret_cast(reservedRendererPtr1); + Renderer::CommandBuffer** internalBuffers = static_cast(reservedRendererPtr3); + DirectX::XMMATRIX* internalMatrices = static_cast(reservedRendererPtr4); + + const int existingIndex = externalToInternal[context.recordingBufferIndex]; + if (existingIndex >= 0) + { + this->DeleteInternalBuffer(existingIndex); + } + + if (static_cast(reservedRendererDword2 + reservedRendererDword3 + 10u) > 16000) + { + DebugBreak(); + } + + const int internalSlot = reservedRendererDword2; + ++reservedRendererDword2; + + externalToInternal[context.recordingBufferIndex] = static_cast(internalSlot); + internalToExternal[internalSlot] = context.recordingBufferIndex; + internalVertexTypes[internalSlot] = static_cast(context.recordingVertexType); + internalPrimitiveTypes[internalSlot] = static_cast(context.recordingPrimitiveType); + internalBuffers[internalSlot] = context.commandBuffer; + internalMatrices[internalSlot] = context.matrixStacks[3][0]; + } + + context.matrixModeType = 0; + context.commandBuffer->EndRecording(m_pDevice); + context.commandBuffer = nullptr; + + LeaveCriticalSection(&rtl_critical_section100); +} + +void Renderer::CBuffLockStaticCreations() +{ + reservedRendererByte1 = 0; +} + +int Renderer::CBuffSize(int index) +{ + if (index == -1) + { + return totalAlloc < 0 ? 0 : totalAlloc; + } + + unsigned int size = 0; + EnterCriticalSection(&rtl_critical_section100); + const int internalIndex = static_cast(reservedRendererPtr2)[index]; + if (internalIndex >= 0) + { + size = static_cast(reservedRendererPtr3)[internalIndex]->GetAllocated(); + } + LeaveCriticalSection(&rtl_critical_section100); + return size; +} + +void Renderer::CBuffStart(int index, bool full) +{ + Renderer::Context& context = this->getContext(); + context.commandBuffer = new (std::nothrow) Renderer::CommandBuffer(full); + context.recordingBufferIndex = index; + context.matrixModeType = 3; + context.matrixStackDepth[3] = 0; + context.matrixStacks[3][0] = DirectX::XMMatrixIdentity(); + context.matrixDirty[3] = true; +} + +void Renderer::CBuffTick() +{ + const int kMaxInternalCBuffers = 16000; + + EnterCriticalSection(&rtl_critical_section100); + + Renderer::CommandBuffer** buffers = static_cast(reservedRendererPtr3); + const int firstPending = kMaxInternalCBuffers - static_cast(reservedRendererDword3); + for (int i = firstPending; i < kMaxInternalCBuffers; ++i) + { + Renderer::CommandBuffer* buffer = buffers[i]; + if (buffer) + { + delete buffer; + } + buffers[i] = nullptr; + } + + reservedRendererDword3 = 0; + LeaveCriticalSection(&rtl_critical_section100); +} + +void Renderer::DeleteInternalBuffer(int index) +{ + const int kMaxInternalCBuffers = 16000; + + EnterCriticalSection(&rtl_critical_section100); + + Renderer::CommandBuffer** internalBuffers = static_cast(reservedRendererPtr3); + DirectX::XMMATRIX* internalMatrices = static_cast(reservedRendererPtr4); + std::uint8_t* internalVertexTypes = static_cast(reservedRendererPtr6); + std::uint8_t* internalPrimitiveTypes = reinterpret_cast(reservedRendererPtr1); + std::int16_t* externalToInternal = static_cast(reservedRendererPtr2); + int* internalToExternal = static_cast(reservedRendererPtr5); + + ++reservedRendererDword3; + const int recycledSlot = kMaxInternalCBuffers - static_cast(reservedRendererDword3); + + internalBuffers[recycledSlot] = internalBuffers[index]; + internalMatrices[recycledSlot] = internalMatrices[index]; + + if (reservedRendererDword2-- != 1) + { + const int lastActive = reservedRendererDword2; + + internalBuffers[index] = internalBuffers[lastActive]; + internalMatrices[index] = internalMatrices[lastActive]; + internalVertexTypes[index] = internalVertexTypes[lastActive]; + internalPrimitiveTypes[index] = internalPrimitiveTypes[lastActive]; + + const int externalIndex = internalToExternal[lastActive]; + externalToInternal[externalIndex] = static_cast(index); + internalToExternal[index] = externalIndex; + } + + LeaveCriticalSection(&rtl_critical_section100); +} diff --git a/Windows_Libs/Dev/Render/RendererCore.cpp b/Windows_Libs/Dev/Render/RendererCore.cpp index 643712e..9d2f666 100644 --- a/Windows_Libs/Dev/Render/RendererCore.cpp +++ b/Windows_Libs/Dev/Render/RendererCore.cpp @@ -1,6 +1,959 @@ #pragma once +#include "CompiledShaders.h" #include "Renderer.h" +#include +#include +#include +#include +#include +#include + +static const unsigned int kVertexBufferSize = 0x100000u; +static const float kAspectRatio = 1.7777778f; +static const unsigned int kScreenGrabWidth = 1920u; +static const unsigned int kScreenGrabHeight = 1080u; +static const unsigned int kThumbnailSize = 64u; + +static const unsigned int g_vertexStrides[C4JRender::VERTEX_TYPE_COUNT] = { + 32u, 16u, 32u, 32u}; + Renderer InternalRenderManager; DWORD Renderer::tlsIdx = TlsAlloc(); +unsigned int Renderer::s_auiWidths[MAX_MIP_LEVELS + 1] = {1920u, 512u, 256u, + 128u, 64u, 0u}; +unsigned int Renderer::s_auiHeights[MAX_MIP_LEVELS + 1] = { + 1080u, 512u, 256u, 128u, 64u, 0xFFFFFFFFu}; +D3D11_INPUT_ELEMENT_DESC Renderer::g_vertex_PTN_Elements_PF3_TF2_CB4_NB4_XW1[5] = { + {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, + D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, + D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, 20, D3D11_INPUT_PER_VERTEX_DATA, + 0}, + {"NORMAL", 0, DXGI_FORMAT_R8G8B8A8_SNORM, 0, 24, + D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"TEXCOORD", 1, DXGI_FORMAT_R16G16_SINT, 0, 28, D3D11_INPUT_PER_VERTEX_DATA, + 0}, +}; +D3D11_INPUT_ELEMENT_DESC Renderer::g_vertex_PTN_Elements_Compressed[2] = { + {"POSITION", 0, DXGI_FORMAT_R16G16B16A16_SINT, 0, 0, + D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"TEXCOORD", 0, DXGI_FORMAT_R16G16B16A16_SINT, 0, 8, + D3D11_INPUT_PER_VERTEX_DATA, 0}, +}; +D3D11_PRIMITIVE_TOPOLOGY Renderer::g_topologies[C4JRender::PRIMITIVE_TYPE_COUNT] = { + D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST, + D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, + D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST, + D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST, + D3D11_PRIMITIVE_TOPOLOGY_LINELIST, + D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP, +}; +int Renderer::totalAlloc = 0; +_RTL_CRITICAL_SECTION Renderer::totalAllocCS = {0}; + +Renderer::Context::Context(ID3D11Device *device, + ID3D11DeviceContext *deviceContext) + : m_pDeviceContext(deviceContext), userAnnotation(nullptr), + contextStateFlags(0), matrixModeType(0), boundTextureIndex(0), + faceCullEnabled(1), depthTestEnabled(1), alphaTestEnabled(0), + alphaReference(1.0f), depthWriteEnabled(1), fogEnabled(0), + fogNearDistance(0.0f), fogFarDistance(0.0f), fogDensity(0.0f), + fogColourRed(0.0f), fogColourBlue(0.0f), fogColourGreen(0.0f), fogMode(0), + lightingEnabled(0), lightingDirty(0), forcedLOD(0xFFFFFFFFu), + cbMatrix0(nullptr), cbMatrix1(nullptr), cbMatrix2(nullptr), + cbMatrix3(nullptr), cbVertexTexcoord(nullptr), cbFogParams(nullptr), + cbLighting(nullptr), cbTexGen(nullptr), cbAux0(nullptr), cbAux1(nullptr), + cbColour(nullptr), cbFogColour(nullptr), cbAux2(nullptr), + cbAlphaTest(nullptr), cbAux3(nullptr), cbAux4(nullptr), + dynamicVertexBase(0), dynamicVertexOffset(0), + dynamicVertexBuffer(nullptr), commandBuffer(nullptr), + recordingBufferIndex(0), recordingVertexType(0), + recordingPrimitiveType(0), deferredModeEnabled(0), deferredBuffers(), + reservedContext0(0), reservedContext1(0) { + deviceContext->QueryInterface(IID_PPV_ARGS(&userAnnotation)); + std::memset(matrixStacks, 0, sizeof(matrixStacks)); + std::memset(matrixDirty, 0, sizeof(matrixDirty)); + std::memset(matrixStackDepth, 0, sizeof(matrixStackDepth)); + std::memset(lightEnabled, 0, sizeof(lightEnabled)); + std::memset(lightDirection, 0, sizeof(lightDirection)); + std::memset(lightColour, 0, sizeof(lightColour)); + std::memset(&lightAmbientColour, 0, sizeof(lightAmbientColour)); + std::memset(texGenMatrices, 0, sizeof(texGenMatrices)); + std::memset(&blendDesc, 0, sizeof(blendDesc)); + std::memset(&depthStencilDesc, 0, sizeof(depthStencilDesc)); + std::memset(&rasterizerDesc, 0, sizeof(rasterizerDesc)); + blendFactor[0] = 0.0f; + blendFactor[1] = 0.0f; + blendFactor[2] = 0.0f; + blendFactor[3] = 0.0f; + + const DirectX::XMMATRIX identity = DirectX::XMMatrixIdentity(); + for (unsigned int i = 0; i < 4; ++i) { + matrixStacks[i][0] = identity; + matrixStackDepth[i] = 0; + } + + blendDesc.AlphaToCoverageEnable = FALSE; + blendDesc.IndependentBlendEnable = FALSE; + blendDesc.RenderTarget[0].BlendEnable = FALSE; + blendDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE; + blendDesc.RenderTarget[0].DestBlend = D3D11_BLEND_ZERO; + blendDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; + blendDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; + blendDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; + blendDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; + blendDesc.RenderTarget[0].RenderTargetWriteMask = + D3D11_COLOR_WRITE_ENABLE_ALL; + + depthStencilDesc.DepthEnable = TRUE; + depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; + depthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS; + depthStencilDesc.StencilEnable = FALSE; + depthStencilDesc.StencilReadMask = 0xFFu; + depthStencilDesc.StencilWriteMask = 0xFFu; + depthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; + depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; + depthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; + depthStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; + depthStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; + depthStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; + depthStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; + depthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; + + rasterizerDesc.FillMode = D3D11_FILL_SOLID; + rasterizerDesc.CullMode = D3D11_CULL_BACK; + rasterizerDesc.FrontCounterClockwise = TRUE; + rasterizerDesc.DepthBias = 0; + rasterizerDesc.DepthBiasClamp = 0.0f; + rasterizerDesc.SlopeScaledDepthBias = 0.0f; + rasterizerDesc.DepthClipEnable = TRUE; + rasterizerDesc.ScissorEnable = FALSE; + rasterizerDesc.MultisampleEnable = TRUE; + rasterizerDesc.AntialiasedLineEnable = FALSE; + + std::memset(lightDirection, 0, sizeof(lightDirection)); + std::memset(lightColour, 0, sizeof(lightColour)); + std::memset(&lightAmbientColour, 0, sizeof(lightAmbientColour)); + std::memset(texGenMatrices, 0, sizeof(texGenMatrices)); + + const float zero4[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + const float one4[4] = {1.0f, 1.0f, 1.0f, 1.0f}; + const float alpha4[4] = {0.0f, 0.0f, 0.0f, 1.0f}; + + D3D11_BUFFER_DESC cbDesc = {}; + cbDesc.Usage = D3D11_USAGE_DYNAMIC; + cbDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + cbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + + D3D11_SUBRESOURCE_DATA cbData = {}; + cbDesc.ByteWidth = sizeof(DirectX::XMMATRIX); + cbData.pSysMem = &identity; + device->CreateBuffer(&cbDesc, &cbData, &cbMatrix0); + device->CreateBuffer(&cbDesc, &cbData, &cbMatrix1); + device->CreateBuffer(&cbDesc, &cbData, &cbMatrix2); + device->CreateBuffer(&cbDesc, &cbData, &cbMatrix3); + + cbDesc.ByteWidth = sizeof(zero4); + cbData.pSysMem = zero4; + device->CreateBuffer(&cbDesc, &cbData, &cbVertexTexcoord); + device->CreateBuffer(&cbDesc, &cbData, &cbFogParams); + + const UINT lightingBytes = + sizeof(lightDirection) + sizeof(lightColour) + sizeof(lightAmbientColour); + cbDesc.ByteWidth = lightingBytes; + cbData.pSysMem = lightDirection; + device->CreateBuffer(&cbDesc, &cbData, &cbLighting); + + cbDesc.ByteWidth = sizeof(texGenMatrices); + cbData.pSysMem = texGenMatrices; + device->CreateBuffer(&cbDesc, &cbData, &cbTexGen); + + cbDesc.ByteWidth = sizeof(zero4); + cbData.pSysMem = zero4; + device->CreateBuffer(&cbDesc, &cbData, &cbAux0); + device->CreateBuffer(&cbDesc, &cbData, &cbAux1); + + cbDesc.ByteWidth = sizeof(one4); + cbData.pSysMem = one4; + device->CreateBuffer(&cbDesc, &cbData, &cbColour); + device->CreateBuffer(&cbDesc, &cbData, &cbFogColour); + device->CreateBuffer(&cbDesc, &cbData, &cbAux2); + + cbDesc.ByteWidth = sizeof(alpha4); + cbData.pSysMem = alpha4; + device->CreateBuffer(&cbDesc, &cbData, &cbAlphaTest); + + cbDesc.ByteWidth = sizeof(zero4); + cbData.pSysMem = zero4; + device->CreateBuffer(&cbDesc, &cbData, &cbAux3); + device->CreateBuffer(&cbDesc, &cbData, &cbAux4); + + deviceContext->VSSetConstantBuffers(0, 10, &cbMatrix0); + deviceContext->PSSetConstantBuffers(0, 6, &cbColour); + + { + void *dynamicVertexPtr = operator new[](kVertexBufferSize); + dynamicVertexBase = reinterpret_cast(dynamicVertexPtr); + } + dynamicVertexOffset = 0; + + D3D11_BUFFER_DESC vbDesc = {}; + vbDesc.ByteWidth = kVertexBufferSize; + vbDesc.Usage = D3D11_USAGE_DYNAMIC; + vbDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + vbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + device->CreateBuffer(&vbDesc, nullptr, &dynamicVertexBuffer); +} + +void Renderer::BeginConditionalRendering(int) {} + +void Renderer::BeginConditionalSurvey(int) {} + +void Renderer::CaptureScreen(ImageFileBuffer *, XSOCIAL_PREVIEWIMAGE *) {} + +void Renderer::Clear(int flags, D3D11_RECT *) { + Renderer::Context &context = this->getContext(); + + ID3D11BlendState *blendState = nullptr; + ID3D11DepthStencilState *depthState = nullptr; + ID3D11RasterizerState *rasterizerState = nullptr; + + D3D11_BLEND_DESC blendDesc = {}; + blendDesc.AlphaToCoverageEnable = FALSE; + blendDesc.IndependentBlendEnable = FALSE; + blendDesc.RenderTarget[0].BlendEnable = FALSE; + blendDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE; + blendDesc.RenderTarget[0].DestBlend = D3D11_BLEND_ZERO; + blendDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; + blendDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; + blendDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; + blendDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; + blendDesc.RenderTarget[0].RenderTargetWriteMask = + (flags & CLEAR_COLOUR_FLAG) ? D3D11_COLOR_WRITE_ENABLE_ALL : 0; + m_pDevice->CreateBlendState(&blendDesc, &blendState); + + D3D11_DEPTH_STENCIL_DESC depthDesc = {}; + depthDesc.DepthEnable = (flags & CLEAR_DEPTH_FLAG) ? TRUE : FALSE; + depthDesc.DepthWriteMask = depthDesc.DepthEnable + ? D3D11_DEPTH_WRITE_MASK_ALL + : D3D11_DEPTH_WRITE_MASK_ZERO; + depthDesc.DepthFunc = D3D11_COMPARISON_ALWAYS; + depthDesc.StencilEnable = FALSE; + depthDesc.StencilReadMask = 0xFFu; + depthDesc.StencilWriteMask = 0xFFu; + depthDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; + depthDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; + depthDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; + depthDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; + depthDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; + depthDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; + depthDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; + depthDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; + m_pDevice->CreateDepthStencilState(&depthDesc, &depthState); + + D3D11_RASTERIZER_DESC rasterDesc = {}; + rasterDesc.FillMode = D3D11_FILL_SOLID; + rasterDesc.CullMode = D3D11_CULL_NONE; + rasterDesc.DepthClipEnable = TRUE; + rasterDesc.MultisampleEnable = TRUE; + m_pDevice->CreateRasterizerState(&rasterDesc, &rasterizerState); + + context.m_pDeviceContext->VSSetShader(screenClearVertexShader, nullptr, 0); + context.m_pDeviceContext->IASetInputLayout(nullptr); + context.m_pDeviceContext->PSSetShader(screenClearPixelShader, nullptr, 0); + context.m_pDeviceContext->OMSetRenderTargets(1, &renderTargetView, + depthStencilView); + context.m_pDeviceContext->OMSetBlendState(blendState, nullptr, 0xFFFFFFFFu); + context.m_pDeviceContext->OMSetDepthStencilState(depthState, 0); + context.m_pDeviceContext->RSSetState(rasterizerState); + context.m_pDeviceContext->PSSetShaderResources(0, 0, nullptr); + context.m_pDeviceContext->IASetPrimitiveTopology( + D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + context.m_pDeviceContext->Draw(4, 0); + + if (blendState) { + blendState->Release(); + blendState = nullptr; + } + if (depthState) { + depthState->Release(); + depthState = nullptr; + } + if (rasterizerState) { + rasterizerState->Release(); + rasterizerState = nullptr; + } + + context.m_pDeviceContext->OMSetBlendState(this->GetManagedBlendState(), + context.blendFactor, 0xFFFFFFFFu); + context.m_pDeviceContext->OMSetDepthStencilState( + this->GetManagedDepthStencilState(), 0); + context.m_pDeviceContext->RSSetState(this->GetManagedRasterizerState()); + context.m_pDeviceContext->OMSetRenderTargets(1, &renderTargetView, + depthStencilView); + activeVertexType = 0xFFFFFFFFu; + activePixelType = 0xFFFFFFFFu; +} + +void Renderer::ConvertLinearToPng(ImageFileBuffer *pngOut, + unsigned char *linearData, unsigned int width, + unsigned int height) { + const size_t dataSize = size_t(width) * size_t(height) * 4u; + const size_t outputCapacity = ((dataSize * 24u) / 20u) + 256u; + const int outputCapacityInt = int(outputCapacity); + const int widthInt = int(width); + const int heightInt = int(height); + void *outputBuffer = std::malloc(outputCapacity); + int outputLength = 0; + this->SaveTextureDataToMemory(outputBuffer, outputCapacityInt, &outputLength, + widthInt, heightInt, + reinterpret_cast(linearData)); + pngOut->m_type = ImageFileBuffer::e_typePNG; + pngOut->m_pBuffer = outputBuffer; + pngOut->m_bufferSize = outputLength; +} + +void Renderer::DoScreenGrabOnNextPresent() { shouldScreenGrabNextFrame = 1; } + +void Renderer::EndConditionalRendering() {} + +void Renderer::EndConditionalSurvey() {} + +void Renderer::BeginEvent(LPCWSTR eventName) { + Renderer::Context *context = + static_cast(TlsGetValue(Renderer::tlsIdx)); + if (context && + context->m_pDeviceContext->GetType() != D3D11_DEVICE_CONTEXT_DEFERRED && + context->userAnnotation) { + context->userAnnotation->BeginEvent(eventName); + ++context->contextStateFlags; + } +} + +void Renderer::EndEvent() { + Renderer::Context *context = + static_cast(TlsGetValue(Renderer::tlsIdx)); + if (context && + context->m_pDeviceContext->GetType() != D3D11_DEVICE_CONTEXT_DEFERRED && + context->userAnnotation) { + context->userAnnotation->EndEvent(); + if (context->contextStateFlags > 0) { + --context->contextStateFlags; + } + } +} + +void Renderer::Initialise(ID3D11Device *pDevice, IDXGISwapChain *pSwapChain) { + m_pDevice = pDevice; + m_pDeviceContext = this->InitialiseContext(true); + m_pSwapChain = pSwapChain; + + reservedRendererPtr2 = operator new[](0x1000000u); + reservedRendererPtr3 = operator new[](0x1F400u); + reservedRendererPtr4 = operator new[](0xFA000u); + reservedRendererPtr5 = operator new[](0xFA00u); + reservedRendererPtr6 = operator new[](0x3E80u); + { + void *reservedPtr = operator new[](0x3E80u); + reservedRendererPtr1 = reinterpret_cast(reservedPtr); + } + + std::memset(reservedRendererPtr2, 0xFF, 0x1000000u); + std::memset(reservedRendererPtr3, 0, 0xFA00u); + std::memset(reservedRendererPtr5, 0, 0xFA00u); + std::memset(reservedRendererPtr6, 0, 0x3E80u); + { + void *reservedPtr = reinterpret_cast(reservedRendererPtr1); + std::memset(reservedPtr, 0, 0x3E80u); + } + reservedRendererDword3 = 0; + + shouldScreenGrabNextFrame = 0; + suspended = 0; + + this->SetupShaders(); + const float clearColour[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + this->SetClearColour(clearColour); + + UINT backBufferSampleCount = 1; + UINT backBufferSampleQuality = 0; + ID3D11Texture2D *backBuffer = nullptr; + pSwapChain->GetBuffer(0, IID_PPV_ARGS(&backBuffer)); + if (backBuffer) { + D3D11_TEXTURE2D_DESC backDesc = {}; + backBuffer->GetDesc(&backDesc); + backBufferWidth = backDesc.Width; + backBufferHeight = backDesc.Height; + backBufferSampleCount = backDesc.SampleDesc.Count; + backBufferSampleQuality = backDesc.SampleDesc.Quality; + m_pDevice->CreateRenderTargetView(backBuffer, nullptr, &renderTargetView); + m_pDevice->CreateShaderResourceView(backBuffer, nullptr, + &renderTargetShaderResourceView); + backBuffer->Release(); + } + + ID3D11RenderTargetView *boundRTV = nullptr; + m_pDeviceContext->OMGetRenderTargets(1, &boundRTV, &depthStencilView); + if (boundRTV) { + boundRTV->Release(); + } + + if (!depthStencilView && backBufferWidth != 0 && backBufferHeight != 0) { + D3D11_TEXTURE2D_DESC depthDesc = {}; + depthDesc.Width = backBufferWidth; + depthDesc.Height = backBufferHeight; + depthDesc.MipLevels = 1; + depthDesc.ArraySize = 1; + depthDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; + depthDesc.SampleDesc.Count = backBufferSampleCount; + depthDesc.SampleDesc.Quality = backBufferSampleQuality; + depthDesc.Usage = D3D11_USAGE_DEFAULT; + depthDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; + + ID3D11Texture2D *depthTexture = nullptr; + if (SUCCEEDED( + m_pDevice->CreateTexture2D(&depthDesc, nullptr, &depthTexture))) { + m_pDevice->CreateDepthStencilView(depthTexture, nullptr, + &depthStencilView); + depthTexture->Release(); + } + } + + for (unsigned int i = 0; i < MAX_MIP_LEVELS - 1; ++i) { + D3D11_TEXTURE2D_DESC desc = {}; + desc.Width = s_auiWidths[i + 1]; + desc.Height = s_auiHeights[i + 1]; + desc.MipLevels = 1; + desc.ArraySize = 1; + desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + desc.SampleDesc.Count = 1; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE; + + m_pDevice->CreateTexture2D(&desc, nullptr, &renderTargetTextures[i]); + m_pDevice->CreateRenderTargetView(renderTargetTextures[i], nullptr, + &renderTargetViews[i]); + m_pDevice->CreateShaderResourceView(renderTargetTextures[i], nullptr, + &renderTargetShaderResourceViews[i]); + } + + std::memset(m_textures, 0, sizeof(m_textures)); + defaultTextureIndex = this->TextureCreate(); + this->TextureBind(defaultTextureIndex); + + unsigned char *defaultTextureData = new unsigned char[0x400u]; + std::memset(defaultTextureData, 0xFF, 0x400u); + this->TextureData(16, 16, defaultTextureData, 0, + C4JRender::TEXTURE_FORMAT_RxGyBzAw); + delete[] defaultTextureData; + + presentCount = 0; + rendererFlag0 = 0; + reservedRendererWord0 = 10922; + this->StateSetViewport(C4JRender::VIEWPORT_TYPE_FULLSCREEN); + this->StateSetVertexTextureUV(0.0f, 0.0f); + this->TextureBindVertex(-1); + InitializeCriticalSection(&rtl_critical_section100); + reservedRendererDword1 = 0; + activeVertexType = 0xFFFFFFFFu; + activePixelType = 0xFFFFFFFFu; + reservedRendererByte1 = 1; + reservedRendererByte0 = 0; + + unsigned short *quadIndices = new unsigned short[0x18000u]; + for (unsigned int i = 0; i < 0x4000u; ++i) { + const unsigned short base = (unsigned short)(i * 4u); + const unsigned int offset = i * 6u; + quadIndices[offset + 0] = base; + quadIndices[offset + 1] = (unsigned short)(base + 1u); + quadIndices[offset + 2] = (unsigned short)(base + 3u); + quadIndices[offset + 3] = (unsigned short)(base + 1u); + quadIndices[offset + 4] = (unsigned short)(base + 2u); + quadIndices[offset + 5] = (unsigned short)(base + 3u); + } + D3D11_BUFFER_DESC quadIndexDesc = {}; + quadIndexDesc.ByteWidth = 0x30000u; + quadIndexDesc.Usage = D3D11_USAGE_IMMUTABLE; + quadIndexDesc.BindFlags = D3D11_BIND_INDEX_BUFFER; + D3D11_SUBRESOURCE_DATA quadIndexData = {}; + quadIndexData.pSysMem = quadIndices; + m_pDevice->CreateBuffer(&quadIndexDesc, &quadIndexData, &quadIndexBuffer); + delete[] quadIndices; + + unsigned short *fanIndices = new unsigned short[0x2FFFAu]; + for (unsigned int i = 0; i < 65534u; ++i) { + const unsigned int offset = i * 3u; + fanIndices[offset + 0] = 0u; + fanIndices[offset + 1] = (unsigned short)(i + 1u); + fanIndices[offset + 2] = (unsigned short)(i + 2u); + } + D3D11_BUFFER_DESC fanIndexDesc = {}; + fanIndexDesc.ByteWidth = 0x5FFF4u; + fanIndexDesc.Usage = D3D11_USAGE_IMMUTABLE; + fanIndexDesc.BindFlags = D3D11_BIND_INDEX_BUFFER; + D3D11_SUBRESOURCE_DATA fanIndexData = {}; + fanIndexData.pSysMem = fanIndices; + m_pDevice->CreateBuffer(&fanIndexDesc, &fanIndexData, &fanIndexBuffer); + delete[] fanIndices; + + InitializeCriticalSection(&Renderer::totalAllocCS); + m_Topologies = g_topologies; +} + +ID3D11DeviceContext *Renderer::InitialiseContext(bool fromPresent) { + ID3D11DeviceContext *deviceContext = nullptr; + if (fromPresent) { + m_pDevice->GetImmediateContext(&deviceContext); + } else { + m_pDevice->CreateDeferredContext(0, &deviceContext); + } + + Renderer::Context *context = + new (std::nothrow) Renderer::Context(m_pDevice, deviceContext); + TlsSetValue(Renderer::tlsIdx, context); + return deviceContext; +} + +bool Renderer::IsHiDef() { return true; } + +bool Renderer::IsWidescreen() { return true; } + +void Renderer::Present() { + if (shouldScreenGrabNextFrame) { + int *linearData = new int[kScreenGrabWidth * kScreenGrabHeight]; + ID3D11Texture2D *backBuffer = nullptr; + ID3D11Texture2D *stagingTexture = nullptr; + + m_pSwapChain->GetBuffer(0, IID_PPV_ARGS(&backBuffer)); + if (backBuffer) { + D3D11_TEXTURE2D_DESC desc = {}; + backBuffer->GetDesc(&desc); + desc.Usage = D3D11_USAGE_STAGING; + desc.BindFlags = 0; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; + desc.MiscFlags = 0; + m_pDevice->CreateTexture2D(&desc, nullptr, &stagingTexture); + } + + if (stagingTexture && backBuffer) { + m_pDeviceContext->CopyResource(stagingTexture, backBuffer); + D3D11_MAPPED_SUBRESOURCE mapped = {}; + if (SUCCEEDED(m_pDeviceContext->Map(stagingTexture, 0, D3D11_MAP_READ, 0, + &mapped))) { + unsigned char *dst = reinterpret_cast(linearData); + const unsigned char *src = + reinterpret_cast(mapped.pData); + for (unsigned int y = 0; y < kScreenGrabHeight; ++y) { + unsigned char *dstRow = dst + y * (kScreenGrabWidth * 4u); + const unsigned char *srcRow = src + y * mapped.RowPitch; + std::memcpy(dstRow, srcRow, kScreenGrabWidth * 4u); + for (unsigned int x = 0; x < kScreenGrabWidth; ++x) { + dstRow[x * 4u + 3u] = 0xFF; + } + } + m_pDeviceContext->Unmap(stagingTexture, 0); + } + } + + static int count = 0; + char fileName[304]; + sprintf_s(fileName, "d:\\screen%d.png", count++); + D3DXIMAGE_INFO info; + info.Width = kScreenGrabWidth; + info.Height = kScreenGrabHeight; + this->SaveTextureData(fileName, &info, linearData); + delete[] linearData; + + if (stagingTexture) { + stagingTexture->Release(); + stagingTexture = nullptr; + } + if (backBuffer) { + backBuffer->Release(); + backBuffer = nullptr; + } + shouldScreenGrabNextFrame = 0; + } + + m_pSwapChain->Present(1, 0); + ++presentCount; +} + +void Renderer::Resume() { suspended = 0; } + +void Renderer::SetClearColour(const float colourRGBA[4]) { + std::memcpy(m_fClearColor, colourRGBA, sizeof(m_fClearColor)); + + Renderer::Context *context = + static_cast(TlsGetValue(Renderer::tlsIdx)); + if (context) { + D3D11_MAPPED_SUBRESOURCE mapped = {}; + context->m_pDeviceContext->Map(context->cbAux3, 0, D3D11_MAP_WRITE_DISCARD, + 0, &mapped); + std::memcpy(mapped.pData, colourRGBA, sizeof(float) * 4); + context->m_pDeviceContext->Unmap(context->cbAux3, 0); + } +} + +void Renderer::SetupShaders() { + vertexShaderTable = new ID3D11VertexShader *[C4JRender::VERTEX_TYPE_COUNT]; + pixelShaderTable = new ID3D11PixelShader *[C4JRender::PIXEL_SHADER_COUNT]; + vertexStrideTable = new unsigned int[C4JRender::VERTEX_TYPE_COUNT]; + inputLayoutTable = new ID3D11InputLayout *[C4JRender::VERTEX_TYPE_COUNT]; + + for (unsigned int i = 0; i < C4JRender::VERTEX_TYPE_COUNT; ++i) { + vertexShaderTable[i] = nullptr; + inputLayoutTable[i] = nullptr; + vertexStrideTable[i] = g_vertexStrides[i]; + } + + for (unsigned int i = 0; i < C4JRender::PIXEL_SHADER_COUNT; ++i) { + pixelShaderTable[i] = nullptr; + } + + screenSpaceVertexShader = nullptr; + screenClearVertexShader = nullptr; + screenSpacePixelShader = nullptr; + screenClearPixelShader = nullptr; + + m_pDevice->CreateVertexShader( + VS_PF3_TF2_CB4_NB4_XW1_Data, sizeof(VS_PF3_TF2_CB4_NB4_XW1_Data), nullptr, + &vertexShaderTable[C4JRender::VERTEX_TYPE_PF3_TF2_CB4_NB4_XW1]); + m_pDevice->CreateVertexShader( + VS_Compressed_Data, sizeof(VS_Compressed_Data), nullptr, + &vertexShaderTable[C4JRender::VERTEX_TYPE_COMPRESSED]); + m_pDevice->CreateVertexShader( + VS_PF3_TF2_CB4_NB4_XW1_Lighting_Data, + sizeof(VS_PF3_TF2_CB4_NB4_XW1_Lighting_Data), nullptr, + &vertexShaderTable[C4JRender::VERTEX_TYPE_PF3_TF2_CB4_NB4_XW1_LIT]); + m_pDevice->CreateVertexShader( + VS_PF3_TF2_CB4_NB4_XW1_Texgen_Data, + sizeof(VS_PF3_TF2_CB4_NB4_XW1_Texgen_Data), nullptr, + &vertexShaderTable[C4JRender::VERTEX_TYPE_PF3_TF2_CB4_NB4_XW1_TEXGEN]); + m_pDevice->CreateVertexShader(VS_ScreenSpace_Data, + sizeof(VS_ScreenSpace_Data), nullptr, + &screenSpaceVertexShader); + m_pDevice->CreateVertexShader(VS_ScreenClear_Data, + sizeof(VS_ScreenClear_Data), nullptr, + &screenClearVertexShader); + + m_pDevice->CreatePixelShader( + PS_Standard_Data, sizeof(PS_Standard_Data), nullptr, + &pixelShaderTable[C4JRender::PIXEL_SHADER_TYPE_STANDARD]); + m_pDevice->CreatePixelShader( + PS_TextureProjection_Data, sizeof(PS_TextureProjection_Data), nullptr, + &pixelShaderTable[C4JRender::PIXEL_SHADER_TYPE_PROJECTION]); + m_pDevice->CreatePixelShader( + PS_ForceLOD_Data, sizeof(PS_ForceLOD_Data), nullptr, + &pixelShaderTable[C4JRender::PIXEL_SHADER_TYPE_FORCELOD]); + m_pDevice->CreatePixelShader(PS_ScreenSpace_Data, sizeof(PS_ScreenSpace_Data), + nullptr, &screenSpacePixelShader); + m_pDevice->CreatePixelShader(PS_ScreenClear_Data, sizeof(PS_ScreenClear_Data), + nullptr, &screenClearPixelShader); + + m_pDevice->CreateInputLayout( + g_vertex_PTN_Elements_PF3_TF2_CB4_NB4_XW1, 5, VS_PF3_TF2_CB4_NB4_XW1_Data, + sizeof(VS_PF3_TF2_CB4_NB4_XW1_Data), + &inputLayoutTable[C4JRender::VERTEX_TYPE_PF3_TF2_CB4_NB4_XW1]); + m_pDevice->CreateInputLayout( + g_vertex_PTN_Elements_Compressed, 2, VS_Compressed_Data, + sizeof(VS_Compressed_Data), + &inputLayoutTable[C4JRender::VERTEX_TYPE_COMPRESSED]); + m_pDevice->CreateInputLayout( + g_vertex_PTN_Elements_PF3_TF2_CB4_NB4_XW1, 5, + VS_PF3_TF2_CB4_NB4_XW1_Lighting_Data, + sizeof(VS_PF3_TF2_CB4_NB4_XW1_Lighting_Data), + &inputLayoutTable[C4JRender::VERTEX_TYPE_PF3_TF2_CB4_NB4_XW1_LIT]); + m_pDevice->CreateInputLayout( + g_vertex_PTN_Elements_PF3_TF2_CB4_NB4_XW1, 5, + VS_PF3_TF2_CB4_NB4_XW1_Texgen_Data, + sizeof(VS_PF3_TF2_CB4_NB4_XW1_Texgen_Data), + &inputLayoutTable[C4JRender::VERTEX_TYPE_PF3_TF2_CB4_NB4_XW1_TEXGEN]); +} + +void Renderer::StartFrame() { + Renderer::Context &context = this->getContext(); + + activeVertexType = 0xFFFFFFFFu; + activePixelType = 0xFFFFFFFFu; + + this->TextureBindVertex(-1); + this->TextureBind(-1); + this->StateSetColour(1.0f, 1.0f, 1.0f, 1.0f); + this->StateSetDepthMask(true); + this->StateSetBlendEnable(true); + this->StateSetBlendFunc(D3D11_BLEND_SRC_ALPHA, D3D11_BLEND_INV_SRC_ALPHA); + this->StateSetBlendFactor(0xFFFFFFFFu); + this->StateSetAlphaFunc(D3D11_COMPARISON_GREATER, 0.1f); + this->StateSetDepthFunc(D3D11_COMPARISON_LESS_EQUAL); + this->StateSetFaceCull(true); + this->StateSetLineWidth(1.0f); + this->StateSetWriteEnable(true, true, true, true); + this->StateSetDepthTestEnable(false); + this->StateSetAlphaTestEnable(true); + + context.m_pDeviceContext->VSSetConstantBuffers(0, 10, &context.cbMatrix0); + context.m_pDeviceContext->PSSetConstantBuffers(0, 6, &context.cbColour); + + D3D11_VIEWPORT viewport = {}; + viewport.TopLeftX = 0.0f; + viewport.TopLeftY = 0.0f; + viewport.Width = (float)backBufferWidth; + viewport.Height = (float)backBufferHeight; + viewport.MinDepth = 0.0f; + viewport.MaxDepth = 1.0f; + context.m_pDeviceContext->RSSetViewports(1, &viewport); + context.m_pDeviceContext->OMSetRenderTargets(1, &renderTargetView, + depthStencilView); +} + +void Renderer::Suspend() { suspended = 1; } + +bool Renderer::Suspended() { return suspended != 0; } + +void Renderer::UpdateGamma(unsigned short) {} + +Renderer::Context &Renderer::getContext() { + return *static_cast(TlsGetValue(Renderer::tlsIdx)); +} + +void Renderer::CaptureThumbnail(ImageFileBuffer *pngOut) { + Renderer::Context &context = this->getContext(); + + float left; + float bottom; + float right; + float top; + left = 0.0f; + bottom = 0.0f; + right = 1.0f; + top = 1.0f; + switch (m_ViewportType) { + case C4JRender::VIEWPORT_TYPE_SPLIT_TOP: + bottom = 0.5f; + break; + case C4JRender::VIEWPORT_TYPE_SPLIT_BOTTOM: + top = 0.5f; + break; + case C4JRender::VIEWPORT_TYPE_SPLIT_LEFT: + right = 0.5f; + break; + case C4JRender::VIEWPORT_TYPE_SPLIT_RIGHT: + left = 0.5f; + break; + case C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_LEFT: + right = 0.5f; + bottom = 0.5f; + break; + case C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_RIGHT: + left = 0.5f; + bottom = 0.5f; + break; + case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_LEFT: + right = 0.5f; + top = 0.5f; + break; + case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_RIGHT: + left = 0.5f; + top = 0.5f; + break; + default: + break; + } + + float leftScaled = left * kAspectRatio; + float rightScaled = right * kAspectRatio; + const float viewportHeight = top - bottom; + const float viewportScaledWidth = rightScaled - leftScaled; + + if (viewportHeight <= viewportScaledWidth) { + const float pad = (viewportScaledWidth - viewportHeight) * 0.5f; + leftScaled += pad; + rightScaled -= pad; + } else { + const float pad = (viewportHeight - viewportScaledWidth) * 0.5f; + bottom += pad; + top -= pad; + } + + const float sampleLeft = leftScaled / kAspectRatio; + const float sampleWidth = (rightScaled - leftScaled) / kAspectRatio; + const float sampleHeight = top - bottom; + + ID3D11BlendState *blendState = nullptr; + ID3D11DepthStencilState *depthState = nullptr; + ID3D11RasterizerState *rasterizerState = nullptr; + ID3D11SamplerState *samplerState = nullptr; + ID3D11Texture2D *stagingTexture = nullptr; + + D3D11_BLEND_DESC blendDesc = {}; + blendDesc.RenderTarget[0].BlendEnable = FALSE; + blendDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE; + blendDesc.RenderTarget[0].DestBlend = D3D11_BLEND_ZERO; + blendDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; + blendDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; + blendDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; + blendDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; + blendDesc.RenderTarget[0].RenderTargetWriteMask = + D3D11_COLOR_WRITE_ENABLE_ALL; + m_pDevice->CreateBlendState(&blendDesc, &blendState); + + D3D11_DEPTH_STENCIL_DESC depthDesc = {}; + depthDesc.DepthEnable = FALSE; + depthDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; + depthDesc.DepthFunc = D3D11_COMPARISON_ALWAYS; + depthDesc.StencilEnable = FALSE; + depthDesc.StencilReadMask = 0xFFu; + depthDesc.StencilWriteMask = 0xFFu; + depthDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; + depthDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; + depthDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; + depthDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; + depthDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; + depthDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; + depthDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; + depthDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; + m_pDevice->CreateDepthStencilState(&depthDesc, &depthState); + + D3D11_RASTERIZER_DESC rasterDesc = {}; + rasterDesc.FillMode = D3D11_FILL_SOLID; + rasterDesc.CullMode = D3D11_CULL_NONE; + rasterDesc.DepthClipEnable = TRUE; + rasterDesc.MultisampleEnable = TRUE; + m_pDevice->CreateRasterizerState(&rasterDesc, &rasterizerState); + + D3D11_SAMPLER_DESC samplerDesc = {}; + samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; + samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP; + samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP; + samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; + samplerDesc.MaxAnisotropy = 1; + samplerDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS; + samplerDesc.MinLOD = 0.0f; + samplerDesc.MaxLOD = (std::numeric_limits::max)(); + m_pDevice->CreateSamplerState(&samplerDesc, &samplerState); + + context.m_pDeviceContext->VSSetShader(screenSpaceVertexShader, nullptr, 0); + context.m_pDeviceContext->IASetInputLayout(nullptr); + context.m_pDeviceContext->PSSetShader(screenSpacePixelShader, nullptr, 0); + context.m_pDeviceContext->OMSetBlendState(blendState, nullptr, 0xFFFFFFFFu); + context.m_pDeviceContext->OMSetDepthStencilState(depthState, 0); + context.m_pDeviceContext->RSSetState(rasterizerState); + + for (unsigned int i = 0; i < MAX_MIP_LEVELS - 1; ++i) { + D3D11_VIEWPORT viewport = {}; + viewport.TopLeftX = 0.0f; + viewport.TopLeftY = 0.0f; + viewport.Width = (float)s_auiWidths[i + 1]; + viewport.Height = (float)s_auiHeights[i + 1]; + viewport.MinDepth = 0.0f; + viewport.MaxDepth = 1.0f; + + context.m_pDeviceContext->OMSetRenderTargets(1, &renderTargetViews[i], + nullptr); + context.m_pDeviceContext->RSSetViewports(1, &viewport); + + ID3D11ShaderResourceView *inputTexture = + (i == 0) ? renderTargetShaderResourceView + : renderTargetShaderResourceViews[i - 1]; + context.m_pDeviceContext->PSSetShaderResources(0, 1, &inputTexture); + context.m_pDeviceContext->PSSetSamplers(0, 1, &samplerState); + context.m_pDeviceContext->IASetPrimitiveTopology( + D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + + D3D11_MAPPED_SUBRESOURCE mapped = {}; + context.m_pDeviceContext->Map(context.cbAux1, 0, D3D11_MAP_WRITE_DISCARD, 0, + &mapped); + float *constants = static_cast(mapped.pData); + if (i == 0) { + constants[0] = sampleLeft; + constants[1] = bottom; + constants[2] = sampleWidth; + constants[3] = sampleHeight; + } else { + constants[0] = 0.0f; + constants[1] = 0.0f; + constants[2] = 1.0f; + constants[3] = 1.0f; + } + context.m_pDeviceContext->Unmap(context.cbAux1, 0); + context.m_pDeviceContext->Draw(4, 0); + } + + D3D11_TEXTURE2D_DESC desc = {}; + renderTargetTextures[MAX_MIP_LEVELS - 2]->GetDesc(&desc); + desc.Usage = D3D11_USAGE_STAGING; + desc.BindFlags = 0; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; + desc.MiscFlags = 0; + m_pDevice->CreateTexture2D(&desc, nullptr, &stagingTexture); + + unsigned char *linearData = + new unsigned char[kThumbnailSize * kThumbnailSize * 4u]; + if (stagingTexture) { + context.m_pDeviceContext->CopyResource( + stagingTexture, renderTargetTextures[MAX_MIP_LEVELS - 2]); + D3D11_MAPPED_SUBRESOURCE mapped = {}; + if (SUCCEEDED(context.m_pDeviceContext->Map(stagingTexture, 0, + D3D11_MAP_READ, 0, &mapped))) { + const unsigned char *src = + static_cast(mapped.pData); + unsigned char *dst = linearData; + for (unsigned int y = 0; y < kThumbnailSize; ++y) { + std::memcpy(dst, src, kThumbnailSize * 4u); + for (unsigned int x = 0; x < kThumbnailSize; ++x) { + dst[x * 4u + 3u] = 0xFF; + } + src += mapped.RowPitch; + dst += kThumbnailSize * 4u; + } + context.m_pDeviceContext->Unmap(stagingTexture, 0); + } + } + + this->ConvertLinearToPng(pngOut, linearData, kThumbnailSize, kThumbnailSize); + delete[] linearData; + + if (stagingTexture) { + stagingTexture->Release(); + stagingTexture = nullptr; + } + if (samplerState) { + samplerState->Release(); + samplerState = nullptr; + } + if (rasterizerState) { + rasterizerState->Release(); + rasterizerState = nullptr; + } + if (depthState) { + depthState->Release(); + depthState = nullptr; + } + if (blendState) { + blendState->Release(); + blendState = nullptr; + } + + context.m_pDeviceContext->OMSetBlendState(this->GetManagedBlendState(), + context.blendFactor, 0xFFFFFFFFu); + context.m_pDeviceContext->OMSetDepthStencilState( + this->GetManagedDepthStencilState(), 0); + context.m_pDeviceContext->RSSetState(this->GetManagedRasterizerState()); + + D3D11_VIEWPORT viewport = {}; + viewport.TopLeftX = 0.0f; + viewport.TopLeftY = 0.0f; + viewport.Width = (float)backBufferWidth; + viewport.Height = (float)backBufferHeight; + viewport.MinDepth = 0.0f; + viewport.MaxDepth = 1.0f; + context.m_pDeviceContext->RSSetViewports(1, &viewport); + context.m_pDeviceContext->OMSetRenderTargets(1, &renderTargetView, + depthStencilView); + activeVertexType = 0xFFFFFFFFu; + activePixelType = 0xFFFFFFFFu; +} diff --git a/Windows_Libs/Dev/Render/RendererMatrix.cpp b/Windows_Libs/Dev/Render/RendererMatrix.cpp index 6f70f09..32959c4 100644 --- a/Windows_Libs/Dev/Render/RendererMatrix.cpp +++ b/Windows_Libs/Dev/Render/RendererMatrix.cpp @@ -1 +1,111 @@ #pragma once +#include "Renderer.h" + +#include + +const float* Renderer::MatrixGet(int type) +{ + Context& context = this->getContext(); + const int depth = context.matrixStackDepth[type]; + return reinterpret_cast(&context.matrixStacks[type][depth]); +} + +void Renderer::MatrixMode(int type) +{ + Context& context = this->getContext(); + context.matrixModeType = type; +} + +void Renderer::MatrixMult(float* mat) +{ + DirectX::XMMATRIX matrix; + std::memcpy(&matrix, mat, sizeof(matrix)); + this->MultWithStack(matrix); +} + +void Renderer::MatrixOrthogonal(float left, float right, float bottom, float top, float zNear, float zFar) +{ + const DirectX::XMMATRIX matrix = DirectX::XMMatrixOrthographicOffCenterRH(left, right, bottom, top, zNear, zFar); + this->MultWithStack(matrix); +} + +void Renderer::MatrixPerspective(float fovy, float aspect, float zNear, float zFar) +{ + const float fovRadians = fovy * (3.14159274f / 180.0f); + const DirectX::XMMATRIX matrix = DirectX::XMMatrixPerspectiveFovRH(fovRadians, aspect, zNear, zFar); + this->MultWithStack(matrix); +} + +void Renderer::MatrixPop() +{ + Context& context = this->getContext(); + const int mode = context.matrixModeType; + --context.matrixStackDepth[mode]; + context.matrixDirty[mode] = true; +} + +void Renderer::MatrixPush() +{ + Context& context = this->getContext(); + const int mode = context.matrixModeType; + const int depth = context.matrixStackDepth[mode]; + context.matrixStacks[mode][depth + 1] = context.matrixStacks[mode][depth]; + ++context.matrixStackDepth[mode]; +} + +void Renderer::MatrixRotate(float angle, float x, float y, float z) +{ + const DirectX::XMVECTOR axis = DirectX::XMVectorSet(x, y, z, 0.0f); + const DirectX::XMMATRIX matrix = DirectX::XMMatrixRotationAxis(axis, angle); + this->MultWithStack(matrix); +} + +void Renderer::MatrixScale(float x, float y, float z) +{ + const DirectX::XMMATRIX matrix = DirectX::XMMatrixScaling(x, y, z); + this->MultWithStack(matrix); +} + +void Renderer::MatrixSetIdentity() +{ + Context& context = this->getContext(); + const int mode = context.matrixModeType; + const int depth = context.matrixStackDepth[mode]; + context.matrixStacks[mode][depth] = DirectX::XMMatrixIdentity(); + context.matrixDirty[mode] = true; +} + +void Renderer::MatrixTranslate(float x, float y, float z) +{ + const DirectX::XMMATRIX matrix = DirectX::XMMatrixTranslation(x, y, z); + this->MultWithStack(matrix); +} + +void Renderer::MultWithStack(DirectX::XMMATRIX matrix) +{ + Context& context = this->getContext(); + const int mode = context.matrixModeType; + const int depth = context.matrixStackDepth[mode]; + DirectX::XMMATRIX& current = context.matrixStacks[mode][depth]; + current = DirectX::XMMatrixMultiply(matrix, current); + context.matrixDirty[mode] = true; +} + +void Renderer::Set_matrixDirty() +{ + Context& context = this->getContext(); + const DirectX::XMMATRIX identity = DirectX::XMMatrixIdentity(); + + context.matrixStacks[0][0] = identity; + context.matrixStacks[1][0] = identity; + context.matrixStacks[2][0] = identity; + context.matrixStacks[3][0] = identity; + + context.matrixDirty[0] = true; + context.matrixDirty[1] = true; + context.matrixDirty[2] = true; + context.matrixDirty[3] = true; + + activeVertexType = 0xFFFFFFFFu; + activePixelType = 0xFFFFFFFFu; +} diff --git a/Windows_Libs/Dev/Render/RendererState.cpp b/Windows_Libs/Dev/Render/RendererState.cpp index 6f70f09..127ff75 100644 --- a/Windows_Libs/Dev/Render/RendererState.cpp +++ b/Windows_Libs/Dev/Render/RendererState.cpp @@ -1 +1,656 @@ #pragma once +#include "Renderer.h" + +#include +#include +#include + +ID3D11BlendState* Renderer::GetManagedBlendState() +{ + Context& context = this->getContext(); + const D3D11_RENDER_TARGET_BLEND_DESC& rtBlend = context.blendDesc.RenderTarget[0]; + + const int key = + (rtBlend.BlendEnable ? 1 : 0) | + ((static_cast(rtBlend.SrcBlend) & 0x1F) << 1) | + ((static_cast(rtBlend.DestBlend) & 0x1F) << 6) | + ((static_cast(rtBlend.RenderTargetWriteMask) & 0x0F) << 11); + + auto it = managedBlendStates.find(key); + if (it != managedBlendStates.end()) + { + return it->second; + } + + ID3D11BlendState* state = nullptr; + m_pDevice->CreateBlendState(&context.blendDesc, &state); + managedBlendStates.emplace(key, state); + return state; +} + +ID3D11DepthStencilState* Renderer::GetManagedDepthStencilState() +{ + Context& context = this->getContext(); + + const int key = + (context.depthStencilDesc.DepthEnable ? 2 : 0) | + ((static_cast(context.depthStencilDesc.DepthFunc) & 0x0F) << 2) | + (context.depthStencilDesc.DepthWriteMask == D3D11_DEPTH_WRITE_MASK_ALL ? 1 : 0); + + auto it = managedDepthStencilStates.find(key); + if (it != managedDepthStencilStates.end()) + { + return it->second; + } + + ID3D11DepthStencilState* state = nullptr; + m_pDevice->CreateDepthStencilState(&context.depthStencilDesc, &state); + managedDepthStencilStates.emplace(key, state); + return state; +} + +ID3D11RasterizerState* Renderer::GetManagedRasterizerState() +{ + Context& context = this->getContext(); + + const int key = + (static_cast(context.rasterizerDesc.DepthBias)) | + (static_cast(static_cast(context.rasterizerDesc.SlopeScaledDepthBias)) << 8) | + ((static_cast(context.rasterizerDesc.CullMode) & 0x03) << 16); + + auto it = managedRasterizerStates.find(key); + if (it != managedRasterizerStates.end()) + { + return it->second; + } + + ID3D11RasterizerState* state = nullptr; + m_pDevice->CreateRasterizerState(&context.rasterizerDesc, &state); + managedRasterizerStates.emplace(key, state); + return state; +} + +ID3D11SamplerState* Renderer::GetManagedSamplerState() +{ + Context& context = this->getContext(); + const int key = m_textures[context.boundTextureIndex].samplerParams; + + auto it = managedSamplerStates.find(key); + if (it != managedSamplerStates.end()) + { + return it->second; + } + + const bool clampU = (key & 0x01) != 0; + const bool clampV = (key & 0x02) != 0; + const bool linearFilter = (key & 0x04) != 0; + const bool mipLinear = (key & 0x08) != 0; + const int filterBits = (mipLinear ? 0x08 : 0x00) | (linearFilter ? 0x22 : 0x02); + + D3D11_SAMPLER_DESC desc = {}; + desc.Filter = static_cast(filterBits >> 1); + desc.AddressU = clampU ? D3D11_TEXTURE_ADDRESS_CLAMP : D3D11_TEXTURE_ADDRESS_WRAP; + desc.AddressV = clampV ? D3D11_TEXTURE_ADDRESS_CLAMP : D3D11_TEXTURE_ADDRESS_WRAP; + desc.AddressW = static_cast(3); + desc.MipLODBias = 0.0f; + desc.MaxAnisotropy = 16; + desc.ComparisonFunc = static_cast(1); + desc.BorderColor[0] = 0.0f; + desc.BorderColor[1] = 0.0f; + desc.BorderColor[2] = 0.0f; + desc.BorderColor[3] = 0.0f; + desc.MinLOD = -(std::numeric_limits::max)(); + desc.MaxLOD = (std::numeric_limits::max)(); + + ID3D11SamplerState* state = nullptr; + m_pDevice->CreateSamplerState(&desc, &state); + managedSamplerStates.emplace(key, state); + return state; +} + +void Renderer::StateSetFogEnable(bool enable) +{ + Context& context = this->getContext(); + context.fogEnabled = enable ? 1 : 0; +} + +void Renderer::StateSetFogMode(int mode) +{ + Context& context = this->getContext(); + context.fogMode = mode; +} + +void Renderer::StateSetFogNearDistance(float dist) +{ + Context& context = this->getContext(); + context.fogNearDistance = dist; +} + +void Renderer::StateSetFogFarDistance(float dist) +{ + Context& context = this->getContext(); + context.fogFarDistance = dist; +} + +void Renderer::StateSetFogDensity(float density) +{ + Context& context = this->getContext(); + context.fogDensity = density; +} + +void Renderer::StateSetFogColour(float red, float green, float blue) +{ + Context& context = this->getContext(); + context.fogColourRed = red; + context.fogColourBlue = blue; + context.fogColourGreen = green; +} + +void Renderer::UpdateViewportState() +{ +} + +void Renderer::StateSetLightingEnable(bool enable) +{ + Context& context = this->getContext(); + if (context.commandBuffer != nullptr && context.commandBuffer->isActive != 0) + { + context.commandBuffer->SetLightingEnable(enable); + return; + } + + context.lightingEnabled = enable ? 1 : 0; +} + +void Renderer::StateSetLightColour(int light, float red, float green, float blue) +{ + if (light >= 2) + { + return; + } + + Context& context = this->getContext(); + if (context.commandBuffer != nullptr && context.commandBuffer->isActive != 0) + { + context.commandBuffer->SetLightColour(light, red, green, blue); + return; + } + + context.lightColour[light].x = red; + context.lightColour[light].y = green; + context.lightColour[light].z = blue; + context.lightColour[light].w = 1.0f; + context.lightingDirty = 1; +} + +void Renderer::StateSetLightAmbientColour(float red, float green, float blue) +{ + Context& context = this->getContext(); + if (context.commandBuffer != nullptr && context.commandBuffer->isActive != 0) + { + context.commandBuffer->SetLightAmbientColour(red, green, blue); + return; + } + + context.lightAmbientColour.x = red; + context.lightAmbientColour.y = green; + context.lightAmbientColour.z = blue; + context.lightAmbientColour.w = 1.0f; + context.lightingDirty = 1; +} + +void Renderer::StateSetLightEnable(int light, bool enable) +{ + if (light >= 2) + { + return; + } + + Context& context = this->getContext(); + if (context.commandBuffer != nullptr && context.commandBuffer->isActive != 0) + { + context.commandBuffer->SetLightEnable(light, enable); + return; + } + + context.lightEnabled[light] = enable ? 1 : 0; + context.lightingDirty = 1; +} + +void Renderer::StateSetColour(float r, float g, float b, float a) +{ + Context& context = this->getContext(); + if (context.commandBuffer != nullptr && context.commandBuffer->isActive != 0) + { + context.commandBuffer->SetColor(r, g, b, a); + return; + } + + ID3D11DeviceContext* d3d11 = context.m_pDeviceContext; + const float colour[4] = { r, g, b, a }; + + D3D11_MAPPED_SUBRESOURCE mapped = {}; + d3d11->Map(context.cbColour, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped); + std::memcpy(mapped.pData, colour, sizeof(colour)); + d3d11->Unmap(context.cbColour, 0); +} + +void Renderer::StateSetDepthMask(bool enable) +{ + Context& context = this->getContext(); + if (context.commandBuffer != nullptr && context.commandBuffer->isActive != 0) + { + context.commandBuffer->SetDepthMask(enable); + return; + } + + context.depthStencilDesc.DepthWriteMask = enable ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO; + context.m_pDeviceContext->OMSetDepthStencilState(this->GetManagedDepthStencilState(), 0); + context.depthWriteEnabled = enable ? 1 : 0; +} + +void Renderer::StateSetBlendEnable(bool enable) +{ + Context& context = this->getContext(); + if (context.commandBuffer != nullptr && context.commandBuffer->isActive != 0) + { + context.commandBuffer->SetBlendEnable(enable); + return; + } + + context.blendDesc.RenderTarget[0].BlendEnable = enable ? TRUE : FALSE; + context.m_pDeviceContext->OMSetBlendState(this->GetManagedBlendState(), context.blendFactor, 0xFFFFFFFFu); +} + +void Renderer::StateSetBlendFunc(int src, int dst) +{ + Context& context = this->getContext(); + if (context.commandBuffer != nullptr && context.commandBuffer->isActive != 0) + { + context.commandBuffer->SetBlendFunc(src, dst); + return; + } + + context.blendDesc.RenderTarget[0].SrcBlend = static_cast(src); + context.blendDesc.RenderTarget[0].DestBlend = static_cast(dst); + context.m_pDeviceContext->OMSetBlendState(this->GetManagedBlendState(), context.blendFactor, 0xFFFFFFFFu); +} + +void Renderer::StateSetBlendFactor(unsigned int colour) +{ + Context& context = this->getContext(); + if (context.commandBuffer != nullptr && context.commandBuffer->isActive != 0) + { + context.commandBuffer->SetBlendFactor(colour); + return; + } + + const float scale = 255.0f; + context.blendFactor[0] = static_cast((colour >> 0) & 0xFFu) / scale; + context.blendFactor[1] = static_cast((colour >> 8) & 0xFFu) / scale; + context.blendFactor[2] = static_cast((colour >> 16) & 0xFFu) / scale; + context.blendFactor[3] = static_cast((colour >> 24) & 0xFFu) / scale; + context.m_pDeviceContext->OMSetBlendState(this->GetManagedBlendState(), context.blendFactor, 0xFFFFFFFFu); +} + +void Renderer::StateSetAlphaFunc(int, float param) +{ + Context& context = this->getContext(); + context.alphaReference = param; + + const float alpha[4] = { 0.0f, 0.0f, 0.0f, context.alphaTestEnabled ? context.alphaReference : 0.0f }; + D3D11_MAPPED_SUBRESOURCE mapped = {}; + context.m_pDeviceContext->Map(context.cbAlphaTest, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped); + std::memcpy(mapped.pData, alpha, sizeof(alpha)); + context.m_pDeviceContext->Unmap(context.cbAlphaTest, 0); +} + +void Renderer::StateSetDepthFunc(int func) +{ + Context& context = this->getContext(); + if (context.commandBuffer != nullptr && context.commandBuffer->isActive != 0) + { + context.commandBuffer->SetDepthFunc(func); + return; + } + + context.depthStencilDesc.DepthFunc = static_cast(func); + context.m_pDeviceContext->OMSetDepthStencilState(this->GetManagedDepthStencilState(), 0); +} + +void Renderer::StateSetFaceCull(bool enable) +{ + Context& context = this->getContext(); + if (context.commandBuffer != nullptr && context.commandBuffer->isActive != 0) + { + context.commandBuffer->SetFaceCull(enable); + return; + } + + context.rasterizerDesc.CullMode = enable ? D3D11_CULL_BACK : D3D11_CULL_NONE; + context.m_pDeviceContext->RSSetState(this->GetManagedRasterizerState()); + context.faceCullEnabled = enable ? 1 : 0; +} + +void Renderer::StateSetFaceCullCW(bool enable) +{ + Context& context = this->getContext(); + if (context.faceCullEnabled) + { + context.rasterizerDesc.CullMode = enable ? D3D11_CULL_BACK : D3D11_CULL_FRONT; + } + else + { + context.rasterizerDesc.CullMode = D3D11_CULL_NONE; + } + + context.m_pDeviceContext->RSSetState(this->GetManagedRasterizerState()); +} + +void Renderer::StateSetLineWidth(float) +{ +} + +void Renderer::StateSetWriteEnable(bool red, bool green, bool blue, bool alpha) +{ + Context& context = this->getContext(); + + std::uint8_t mask = 0; + mask |= red ? 0x1 : 0; + mask |= green ? 0x2 : 0; + mask |= blue ? 0x4 : 0; + mask |= alpha ? 0x8 : 0; + + context.blendDesc.RenderTarget[0].RenderTargetWriteMask = mask; + context.m_pDeviceContext->OMSetBlendState(this->GetManagedBlendState(), context.blendFactor, 0xFFFFFFFFu); +} + +void Renderer::StateSetDepthTestEnable(bool enable) +{ + Context& context = this->getContext(); + if (context.commandBuffer != nullptr && context.commandBuffer->isActive != 0) + { + context.commandBuffer->SetDepthTestEnable(enable); + return; + } + + context.depthStencilDesc.DepthEnable = enable ? TRUE : FALSE; + context.m_pDeviceContext->OMSetDepthStencilState(this->GetManagedDepthStencilState(), 0); + context.depthTestEnabled = enable ? 1 : 0; +} + +void Renderer::StateSetAlphaTestEnable(bool enable) +{ + Context& context = this->getContext(); + context.alphaTestEnabled = enable ? 1 : 0; + + const float alpha[4] = { 0.0f, 0.0f, 0.0f, enable ? context.alphaReference : 0.0f }; + D3D11_MAPPED_SUBRESOURCE mapped = {}; + context.m_pDeviceContext->Map(context.cbAlphaTest, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped); + std::memcpy(mapped.pData, alpha, sizeof(alpha)); + context.m_pDeviceContext->Unmap(context.cbAlphaTest, 0); +} + +void Renderer::StateSetDepthSlopeAndBias(float slope, float bias) +{ + Context& context = this->getContext(); + + const float scale = 65536.0f; + context.rasterizerDesc.DepthBias = static_cast(bias * scale); + context.rasterizerDesc.SlopeScaledDepthBias = slope * scale; + context.m_pDeviceContext->RSSetState(this->GetManagedRasterizerState()); +} + +void Renderer::UpdateFogState() +{ + Context& context = this->getContext(); + ID3D11DeviceContext* d3d11 = context.m_pDeviceContext; + + float fogParams[4] = {}; + if (context.fogEnabled) + { + if (context.fogMode == 1) + { + fogParams[0] = context.fogFarDistance; + fogParams[1] = 1.0f / (context.fogFarDistance - context.fogNearDistance); + fogParams[2] = 1.0f; + } + else + { + fogParams[0] = context.fogDensity; + fogParams[2] = 2.0f; + } + } + + const float fogColour[4] = + { + context.fogColourRed, + context.fogColourGreen, + context.fogColourBlue, + 1.0f + }; + + D3D11_MAPPED_SUBRESOURCE mapped = {}; + d3d11->Map(context.cbFogParams, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped); + std::memcpy(mapped.pData, fogParams, sizeof(fogParams)); + d3d11->Unmap(context.cbFogParams, 0); + + d3d11->Map(context.cbFogColour, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped); + std::memcpy(mapped.pData, fogColour, sizeof(fogColour)); + d3d11->Unmap(context.cbFogColour, 0); +} + +void Renderer::StateSetVertexTextureUV(float u, float v) +{ + Context& context = this->getContext(); + const float texgen[4] = { u - 1.0f, v - 1.0f, 0.0f, 0.0f }; + + D3D11_MAPPED_SUBRESOURCE mapped = {}; + context.m_pDeviceContext->Map(context.cbVertexTexcoord, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped); + std::memcpy(mapped.pData, texgen, sizeof(texgen)); + context.m_pDeviceContext->Unmap(context.cbVertexTexcoord, 0); +} + +void Renderer::UpdateTexGenState() +{ + Context& context = this->getContext(); + + D3D11_MAPPED_SUBRESOURCE mapped = {}; + context.m_pDeviceContext->Map(context.cbTexGen, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped); + std::memcpy(mapped.pData, context.texGenMatrices, sizeof(context.texGenMatrices)); + context.m_pDeviceContext->Unmap(context.cbTexGen, 0); +} + +void Renderer::UpdateLightingState() +{ + Context& context = this->getContext(); + if (!context.lightingDirty || !context.lightingEnabled) + { + return; + } + + if (!context.lightEnabled[0]) + { + std::memset(&context.lightDirection[0], 0, sizeof(context.lightDirection[0])); + std::memset(&context.lightColour[0], 0, sizeof(context.lightColour[0])); + } + + if (!context.lightEnabled[1]) + { + std::memset(&context.lightDirection[1], 0, sizeof(context.lightDirection[1])); + std::memset(&context.lightColour[1], 0, sizeof(context.lightColour[1])); + } + + const std::size_t lightingBytes = sizeof(context.lightDirection) + sizeof(context.lightColour) + sizeof(context.lightAmbientColour); + D3D11_MAPPED_SUBRESOURCE mapped = {}; + context.m_pDeviceContext->Map(context.cbLighting, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped); + std::memcpy(mapped.pData, context.lightDirection, lightingBytes); + context.m_pDeviceContext->Unmap(context.cbLighting, 0); + + context.lightingDirty = 0; +} + +void Renderer::StateSetLightDirection(int light, float x, float y, float z) +{ + if (light >= 2) + { + return; + } + + Context& context = this->getContext(); + if (context.commandBuffer != nullptr && context.commandBuffer->isActive != 0) + { + context.commandBuffer->SetLightDirection(light, x, y, z); + return; + } + + const std::uint32_t stackIndex = context.matrixStackDepth[0]; + const DirectX::XMMATRIX& modelView = context.matrixStacks[0][stackIndex]; + const DirectX::XMVECTOR direction = DirectX::XMVectorSet(x, y, z, 0.0f); + const DirectX::XMVECTOR transformed = DirectX::XMVector3TransformNormal(direction, modelView); + const DirectX::XMVECTOR normalized = DirectX::XMVector3Normalize(transformed); + + DirectX::XMStoreFloat4(&context.lightDirection[light], normalized); + context.lightingDirty = 1; +} + +void Renderer::StateSetViewport(C4JRender::eViewportType viewportType) +{ + this->getContext(); + m_ViewportType = viewportType; + + const float fullWidth = static_cast(backBufferWidth); + const float fullHeight = static_cast(backBufferHeight); + + float x = 0.0f; + float y = 0.0f; + float width = fullWidth; + float height = fullHeight; + + switch (viewportType) + { + case C4JRender::VIEWPORT_TYPE_FULLSCREEN: + break; + case C4JRender::VIEWPORT_TYPE_SPLIT_TOP: + y = fullHeight * 0.5f; + height = fullHeight * 0.5f; + break; + case C4JRender::VIEWPORT_TYPE_SPLIT_BOTTOM: + height = fullHeight * 0.5f; + break; + case C4JRender::VIEWPORT_TYPE_SPLIT_LEFT: + width = fullWidth * 0.5f; + break; + case C4JRender::VIEWPORT_TYPE_SPLIT_RIGHT: + x = fullWidth * 0.5f; + width = fullWidth * 0.5f; + break; + case C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_LEFT: + width = fullWidth * 0.5f; + height = fullHeight * 0.5f; + break; + case C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_RIGHT: + x = fullWidth * 0.5f; + width = fullWidth * 0.5f; + height = fullHeight * 0.5f; + break; + case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_LEFT: + y = fullHeight * 0.5f; + width = fullWidth * 0.5f; + height = fullHeight * 0.5f; + break; + case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_RIGHT: + x = fullWidth * 0.5f; + y = fullHeight * 0.5f; + width = fullWidth * 0.5f; + height = fullHeight * 0.5f; + break; + default: + break; + } + + D3D11_VIEWPORT viewport = {}; + viewport.TopLeftX = x; + viewport.TopLeftY = y; + viewport.Width = width; + viewport.Height = height; + viewport.MinDepth = 0.0f; + viewport.MaxDepth = 1.0f; + + m_pDeviceContext->RSSetViewports(1, &viewport); + m_pDeviceContext->OMSetRenderTargets(1, &renderTargetView, depthStencilView); +} + +void Renderer::StateSetEnableViewportClipPlanes(bool) +{ +} + +void Renderer::StateSetTexGenCol(int col, float x, float y, float z, float w, bool eyeSpace) +{ + Context& context = this->getContext(); + + DirectX::XMVECTOR plane = DirectX::XMVectorSet(x, y, z, w); + if (eyeSpace) + { + DirectX::XMFLOAT4X4 modelView; + std::memset(&modelView, 0, sizeof(modelView)); + std::memcpy(&modelView, this->MatrixGet(0), sizeof(modelView)); + + DirectX::XMVECTOR determinant = DirectX::XMVectorZero(); + const DirectX::XMMATRIX inverse = DirectX::XMMatrixInverse(&determinant, DirectX::XMLoadFloat4x4(&modelView)); + plane = DirectX::XMVector4Transform(plane, inverse); + } + + DirectX::XMFLOAT4 transformed; + DirectX::XMStoreFloat4(&transformed, plane); + + const int activeSet = eyeSpace ? 0 : 1; + const int inactiveSet = eyeSpace ? 1 : 0; + + float* active = reinterpret_cast(&context.texGenMatrices[activeSet]); + active[col + 0] = transformed.x; + active[col + 4] = transformed.y; + active[col + 8] = transformed.z; + active[col + 12] = transformed.w; + + float* inactive = reinterpret_cast(&context.texGenMatrices[inactiveSet]); + inactive[col + 0] = 0.0f; + inactive[col + 4] = 0.0f; + inactive[col + 8] = 0.0f; + inactive[col + 12] = 0.0f; +} + +void Renderer::StateSetStencil(D3D11_COMPARISON_FUNC function, uint8_t stencil_ref, uint8_t stencil_func_mask, uint8_t stencil_write_mask) +{ + Context& context = this->getContext(); + + D3D11_DEPTH_STENCIL_DESC desc = context.depthStencilDesc; + desc.StencilEnable = TRUE; + desc.StencilReadMask = stencil_func_mask; + desc.StencilWriteMask = stencil_write_mask; + desc.FrontFace.StencilFunc = function; + desc.BackFace.StencilFunc = function; + + ID3D11DepthStencilState* state = nullptr; + m_pDevice->CreateDepthStencilState(&desc, &state); + m_pDeviceContext->OMSetDepthStencilState(state, stencil_ref); + if (state != nullptr) + { + state->Release(); + } +} + +void Renderer::StateSetForceLOD(int LOD) +{ + Context& context = this->getContext(); + context.forcedLOD = LOD; +} + +void Renderer::StateUpdate() +{ + Context& context = this->getContext(); + this->StateSetFaceCull(context.faceCullEnabled != 0); + this->StateSetDepthMask(context.depthWriteEnabled != 0); + this->StateSetDepthTestEnable(context.depthTestEnabled != 0); + this->StateSetAlphaTestEnable(context.alphaTestEnabled != 0); +} diff --git a/Windows_Libs/Dev/Render/RendererTexture.cpp b/Windows_Libs/Dev/Render/RendererTexture.cpp index 6f70f09..ce5ea4e 100644 --- a/Windows_Libs/Dev/Render/RendererTexture.cpp +++ b/Windows_Libs/Dev/Render/RendererTexture.cpp @@ -1 +1,329 @@ #pragma once +#include "Renderer.h" +#include "libpng/png.h" + +#include +#include +#include +#include + +DXGI_FORMAT Renderer::textureFormats[C4JRender::MAX_TEXTURE_FORMATS] = { + DXGI_FORMAT_B8G8R8A8_UNORM, +}; + +int Renderer::TextureCreate() { + for (int i = 0; i < 512; ++i) { + Texture &texture = m_textures[i]; + if (!texture.allocated) { + texture.texture = nullptr; + texture.allocated = true; + texture.mipLevels = 1; + texture.samplerParams = 0; + return i; + } + } + + return -1; +} + +void Renderer::TextureSetTextureLevels(int levels) { + const int boundTextureIndex = this->getContext().boundTextureIndex; + m_textures[boundTextureIndex].mipLevels = levels; +} + +int Renderer::TextureGetTextureLevels() { + const int boundTextureIndex = this->getContext().boundTextureIndex; + return m_textures[boundTextureIndex].mipLevels; +} + +void Renderer::TextureSetParam(int param, int value) { + Texture &texture = m_textures[this->getContext().boundTextureIndex]; + + switch (param) { + case GL_TEXTURE_MIN_FILTER: + texture.samplerParams &= ~4u; + if (value == 1) { + texture.samplerParams |= 4u; + } + break; + case GL_TEXTURE_MAG_FILTER: + texture.samplerParams &= ~8u; + if (value == 1) { + texture.samplerParams |= 8u; + } + break; + case GL_TEXTURE_WRAP_S: + texture.samplerParams &= ~1u; + if (value == 0) { + texture.samplerParams |= 1u; + } + break; + case GL_TEXTURE_WRAP_T: + case 5: + texture.samplerParams &= ~2u; + if (value == 0) { + texture.samplerParams |= 2u; + } + break; + default: + break; + } +} + +void Renderer::TextureDynamicUpdateStart() {} + +void Renderer::TextureDynamicUpdateEnd() {} + +void Renderer::TextureData(int width, int height, void *data, int level, + C4JRender::eTextureFormat format) { + Renderer::Context &context = this->getContext(); + Texture &texture = m_textures[context.boundTextureIndex]; + texture.textureFormat = format; + + if (level == 0) { + D3D11_TEXTURE2D_DESC desc = {}; + desc.Width = width; + desc.Height = height; + desc.MipLevels = texture.mipLevels; + desc.ArraySize = 1; + desc.Format = textureFormats[format]; + desc.SampleDesc.Count = 1; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + m_pDevice->CreateTexture2D(&desc, nullptr, &texture.texture); + m_pDevice->CreateShaderResourceView(texture.texture, nullptr, + &texture.view); + } + + const UINT rowPitch = width * 4u; + const UINT depthPitch = width * height * 4u; + context.m_pDeviceContext->UpdateSubresource(texture.texture, level, nullptr, + data, rowPitch, depthPitch); +} + +void Renderer::TextureDataUpdate(int xoffset, int yoffset, int width, + int height, void *data, int level) { + Renderer::Context &context = this->getContext(); + Texture &texture = m_textures[context.boundTextureIndex]; + + D3D11_BOX box = {}; + box.left = xoffset; + box.right = xoffset + width; + box.top = yoffset; + box.bottom = yoffset + height; + box.front = 0; + box.back = 1; + + D3D11_TEXTURE2D_DESC desc = {}; + texture.texture->GetDesc(&desc); + + const UINT rowPitch = width * 4u; + const UINT depthPitch = width * height * 4u; + context.m_pDeviceContext->UpdateSubresource(texture.texture, level, &box, + data, rowPitch, depthPitch); +} + +void Renderer::TextureFree(int idx) { + Texture &texture = m_textures[idx]; + texture.texture->Release(); + texture.view->Release(); + texture.view = nullptr; + texture.allocated = false; + texture.texture = nullptr; +} + +void Renderer::TextureGetStats() {} + +ID3D11ShaderResourceView *Renderer::TextureGetTexture(int idx) { + if (idx < 0 || idx > 0x1FF) { + return nullptr; + } + + const Texture &texture = m_textures[idx]; + if (!texture.allocated) { + return nullptr; + } + + return texture.view; +} + +void Renderer::TextureBind(int idx) { + int textureIndex = idx; + if (textureIndex == -1) { + textureIndex = defaultTextureIndex; + } + + Renderer::Context &context = this->getContext(); + + if (context.commandBuffer && context.commandBuffer->isActive) { + context.commandBuffer->BindTexture(textureIndex); + } + + context.boundTextureIndex = textureIndex; + ID3D11ShaderResourceView *const view = m_textures[textureIndex].view; + context.m_pDeviceContext->PSSetShaderResources(0, 1, &view); + this->UpdateTextureState(false); +} + +void Renderer::TextureBindVertex(int idx) { + int textureIndex = idx; + if (textureIndex == -1) { + textureIndex = defaultTextureIndex; + } + + Renderer::Context &context = this->getContext(); + context.boundTextureIndex = textureIndex; + + ID3D11ShaderResourceView *const view = m_textures[textureIndex].view; + context.m_pDeviceContext->VSSetShaderResources(0, 1, &view); + this->UpdateTextureState(true); +} + +void Renderer::UpdateTextureState(bool vertexSampler) { + Renderer::Context &context = this->getContext(); + ID3D11SamplerState *sampler = this->GetManagedSamplerState(); + + if (vertexSampler) { + context.m_pDeviceContext->VSSetSamplers(0, 1, &sampler); + } else { + context.m_pDeviceContext->PSSetSamplers(0, 1, &sampler); + } +} + +HRESULT Renderer::LoadTextureData(const char *szFilename, + D3DXIMAGE_INFO *pSrcInfo, int **ppDataOut) { + if (!szFilename || !pSrcInfo || !ppDataOut) { + return -1; + } + + *ppDataOut = nullptr; + + png_image image; + std::memset(&image, 0, sizeof(image)); + image.version = PNG_IMAGE_VERSION; + if (!png_image_begin_read_from_file(&image, szFilename)) { + return -1; + } + + if (image.width == 0 || image.height == 0) { + png_image_free(&image); + return -1; + } + + image.format = PNG_FORMAT_RGBA; + const png_alloc_size_t pixelCount = + png_alloc_size_t(image.width) * png_alloc_size_t(image.height); + if (pixelCount == 0 || + pixelCount > (std::numeric_limits::max)() / sizeof(int)) { + png_image_free(&image); + return -1; + } + + int *output = new (std::nothrow) int[size_t(pixelCount)]; + + if (!output) { + png_image_free(&image); + return -1; + } + + if (!png_image_finish_read(&image, nullptr, output, 0, nullptr)) { + delete[] output; + png_image_free(&image); + return -1; + } + + *ppDataOut = output; + pSrcInfo->Width = image.width; + pSrcInfo->Height = image.height; + png_image_free(&image); + return 0; +} + +HRESULT Renderer::LoadTextureData(BYTE *pbData, DWORD dwBytes, + D3DXIMAGE_INFO *pSrcInfo, int **ppDataOut) { + if (!pbData || dwBytes == 0 || !pSrcInfo || !ppDataOut) { + return -1; + } + + *ppDataOut = nullptr; + + png_image image; + std::memset(&image, 0, sizeof(image)); + image.version = PNG_IMAGE_VERSION; + if (!png_image_begin_read_from_memory(&image, pbData, dwBytes)) { + return -1; + } + + if (image.width == 0 || image.height == 0) { + png_image_free(&image); + return -1; + } + + image.format = PNG_FORMAT_RGBA; + const png_alloc_size_t pixelCount = + png_alloc_size_t(image.width) * png_alloc_size_t(image.height); + if (pixelCount == 0 || + pixelCount > (std::numeric_limits::max)() / sizeof(int)) { + png_image_free(&image); + return -1; + } + + int *output = new (std::nothrow) int[size_t(pixelCount)]; + + if (!output) { + png_image_free(&image); + return -1; + } + + if (!png_image_finish_read(&image, nullptr, output, 0, nullptr)) { + delete[] output; + png_image_free(&image); + return -1; + } + + *ppDataOut = output; + pSrcInfo->Width = image.width; + pSrcInfo->Height = image.height; + png_image_free(&image); + return 0; +} + +HRESULT Renderer::SaveTextureData(const char *szFilename, + D3DXIMAGE_INFO *pSrcInfo, int *ppDataOut) { + png_image image = {}; + image.version = PNG_IMAGE_VERSION; + image.width = pSrcInfo->Width; + image.height = pSrcInfo->Height; + image.format = PNG_FORMAT_RGBA; + + png_image_write_to_file(&image, szFilename, 0, ppDataOut, 0, nullptr); + return 0; +} + +HRESULT Renderer::SaveTextureDataToMemory(void *pOutput, int outputCapacity, + int *outputLength, int width, + int height, int *ppDataIn) { + if (!pOutput || outputCapacity <= 0 || !outputLength || width <= 0 || + height <= 0 || !ppDataIn) { + return -1; + } + + png_image image; + std::memset(&image, 0, sizeof(image)); + image.version = PNG_IMAGE_VERSION; + image.width = width; + image.height = height; + image.format = PNG_FORMAT_RGBA; + + png_alloc_size_t memoryBytes = static_cast(outputCapacity); + if (!png_image_write_to_memory(&image, pOutput, &memoryBytes, 0, ppDataIn, 0, + nullptr)) { + *outputLength = 0; + png_image_free(&image); + return -1; + } + + *outputLength = static_cast(memoryBytes); + png_image_free(&image); + return 0; +} diff --git a/Windows_Libs/Dev/Render/RendererVertex.cpp b/Windows_Libs/Dev/Render/RendererVertex.cpp index 6f70f09..27c79c8 100644 --- a/Windows_Libs/Dev/Render/RendererVertex.cpp +++ b/Windows_Libs/Dev/Render/RendererVertex.cpp @@ -1 +1,185 @@ #pragma once +#include "Renderer.h" + +#include +#include +#include + +D3D11_PRIMITIVE_TOPOLOGY* Renderer::m_Topologies = nullptr; + +void Renderer::DrawVertexBuffer( + C4JRender::ePrimitiveType PrimitiveType, + int count, + ID3D11Buffer* buffer, + C4JRender::eVertexType vType, + C4JRender::ePixelShaderType psType) +{ + Renderer::Context& context = this->getContext(); + ID3D11DeviceContext* d3d11 = context.m_pDeviceContext; + + int drawCount = count; + bool indexed = false; + this->DrawVertexSetup(vType, psType, PrimitiveType, &drawCount, &indexed); + this->StateUpdate(); + + const UINT stride = vertexStrideTable[vType]; + const UINT offset = 0; + d3d11->IASetVertexBuffers(0, 1, &buffer, &stride, &offset); + + if (indexed) + { + d3d11->DrawIndexed(drawCount, 0, 0); + } + else + { + d3d11->Draw(count, 0); + } +} + +void Renderer::DrawVertexSetup( + C4JRender::eVertexType vType, + C4JRender::ePixelShaderType psType, + C4JRender::ePrimitiveType PrimitiveType, + int* count, + bool* indexed) +{ + Renderer::Context& context = this->getContext(); + ID3D11DeviceContext* d3d11 = context.m_pDeviceContext; + + C4JRender::eVertexType effectiveVertexType = vType; + if (effectiveVertexType == C4JRender::VERTEX_TYPE_PF3_TF2_CB4_NB4_XW1 && context.lightingEnabled) + { + effectiveVertexType = C4JRender::VERTEX_TYPE_PF3_TF2_CB4_NB4_XW1_LIT; + } + + if (effectiveVertexType != activeVertexType) + { + d3d11->VSSetShader(vertexShaderTable[effectiveVertexType], nullptr, 0); + d3d11->IASetInputLayout(inputLayoutTable[effectiveVertexType]); + activeVertexType = effectiveVertexType; + } + + if (psType != activePixelType) + { + d3d11->PSSetShader(pixelShaderTable[psType], nullptr, 0); + activePixelType = psType; + } + + D3D11_MAPPED_SUBRESOURCE mapped = {}; + + if (context.matrixDirty[0]) + { + d3d11->Map(context.cbMatrix0, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped); + std::memcpy(mapped.pData, this->MatrixGet(0), sizeof(DirectX::XMMATRIX)); + d3d11->Unmap(context.cbMatrix0, 0); + context.matrixDirty[0] = false; + } + + if (context.matrixDirty[1]) + { + d3d11->Map(context.cbMatrix2, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped); + std::memcpy(mapped.pData, this->MatrixGet(1), sizeof(DirectX::XMMATRIX)); + d3d11->Unmap(context.cbMatrix2, 0); + context.matrixDirty[1] = false; + } + + if (context.matrixDirty[2]) + { + d3d11->Map(context.cbMatrix3, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped); + std::memcpy(mapped.pData, this->MatrixGet(2), sizeof(DirectX::XMMATRIX)); + d3d11->Unmap(context.cbMatrix3, 0); + context.matrixDirty[2] = false; + } + + this->UpdateFogState(); + this->UpdateViewportState(); + this->UpdateLightingState(); + this->UpdateTexGenState(); + + d3d11->IASetPrimitiveTopology(m_Topologies[PrimitiveType]); + + if (PrimitiveType == C4JRender::PRIMITIVE_TYPE_QUAD_LIST) + { + d3d11->IASetIndexBuffer(quadIndexBuffer, DXGI_FORMAT_R16_UINT, 0); + *count = (*count * 6) / 4; + *indexed = true; + return; + } + + if (PrimitiveType == C4JRender::PRIMITIVE_TYPE_TRIANGLE_FAN) + { + d3d11->IASetIndexBuffer(fanIndexBuffer, DXGI_FORMAT_R16_UINT, 0); + *count = (*count - 2) * 3; + *indexed = true; + return; + } + + d3d11->IASetIndexBuffer(nullptr, DXGI_FORMAT_R16_UINT, 0); + *indexed = false; +} + +void Renderer::DrawVertices( + C4JRender::ePrimitiveType PrimitiveType, + int count, + void* vertices, + C4JRender::eVertexType vType, + C4JRender::ePixelShaderType psType) +{ + Renderer::Context& context = this->getContext(); + ID3D11DeviceContext* d3d11 = context.m_pDeviceContext; + Renderer::CommandBuffer* commandBuffer = context.commandBuffer; + + if (commandBuffer != nullptr) + { + C4JRender::eVertexType effectiveVertexType = vType; + if (effectiveVertexType == C4JRender::VERTEX_TYPE_PF3_TF2_CB4_NB4_XW1 && context.lightingEnabled) + { + effectiveVertexType = C4JRender::VERTEX_TYPE_PF3_TF2_CB4_NB4_XW1_LIT; + } + + context.recordingPrimitiveType = PrimitiveType; + context.recordingVertexType = effectiveVertexType; + const UINT stride = vertexStrideTable[effectiveVertexType]; + commandBuffer->AddVertices(stride, static_cast(count), vertices, context); + return; + } + + int drawCount = count; + bool indexed = false; + this->DrawVertexSetup(vType, psType, PrimitiveType, &drawCount, &indexed); + + const UINT stride = vertexStrideTable[vType]; + const UINT copySize = stride * static_cast(count); + if (context.dynamicVertexOffset + copySize > 0x100000u) + { + context.dynamicVertexOffset = 0; + } + + D3D11_MAPPED_SUBRESOURCE mapped = {}; + const D3D11_MAP mapType = context.dynamicVertexOffset == 0 ? D3D11_MAP_WRITE_DISCARD : D3D11_MAP_WRITE_NO_OVERWRITE; + const HRESULT hr = d3d11->Map(context.dynamicVertexBuffer, 0, mapType, 0, &mapped); + if (hr != 0) + { + std::printf("ERROR: 0x%x\n", static_cast(hr)); + } + + std::memcpy(static_cast(mapped.pData) + context.dynamicVertexOffset, vertices, copySize); + d3d11->Unmap(context.dynamicVertexBuffer, 0); + + this->StateUpdate(); + + ID3D11Buffer* dynamicBuffer = context.dynamicVertexBuffer; + const UINT vertexOffset = context.dynamicVertexOffset; + d3d11->IASetVertexBuffers(0, 1, &dynamicBuffer, &stride, &vertexOffset); + + if (indexed) + { + d3d11->DrawIndexed(drawCount, 0, 0); + } + else + { + d3d11->Draw(count, 0); + } + + context.dynamicVertexOffset += copySize; +} diff --git a/Windows_Libs/Dev/Storage/Storage.vcxproj b/Windows_Libs/Dev/Storage/Storage.vcxproj index 8eaa612..4b28723 100644 --- a/Windows_Libs/Dev/Storage/Storage.vcxproj +++ b/Windows_Libs/Dev/Storage/Storage.vcxproj @@ -1,178 +1,178 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - 18.0 - Win32Proj - {6ded1618-2ada-4d72-a11f-425e83c7042e} - Storage - 10.0 - - - - StaticLibrary - true - v145 - Unicode - - - StaticLibrary - false - v145 - true - Unicode - - - StaticLibrary - true - v145 - Unicode - - - StaticLibrary - false - v145 - true - Unicode - - - - - - - - - - - - - - - - - - - - - 4J_$(ProjectName) - - - 4J_$(ProjectName)_d - - - - Level3 - true - WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - true - stdcpp20 - Use - pch.h - - - - - true - - - - - Level3 - true - true - true - WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - true - stdcpp20 - Use - pch.h - - - - - true - - - - - Level3 - true - _CRT_SECURE_NO_WARNINGS;_DEBUG;_LIB;%(PreprocessorDefinitions) - true - stdcpp20 - Use - stdafx.h - true - stdafx.h - MultiThreadedDebug - - - - - true - - - - - - Level3 - true - true - true - _CRT_SECURE_NO_WARNINGS;NDEBUG;_LIB;%(PreprocessorDefinitions) - true - stdcpp20 - Use - stdafx.h - true - stdafx.h - MultiThreaded - - - - - true - - - - - - - - - - - - - - - Create - Create - Create - Create - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 18.0 + Win32Proj + {6ded1618-2ada-4d72-a11f-425e83c7042e} + Storage + 10.0 + + + + StaticLibrary + true + v145 + Unicode + + + StaticLibrary + false + v145 + true + Unicode + + + StaticLibrary + true + v145 + Unicode + + + StaticLibrary + false + v110 + true + Unicode + + + + + + + + + + + + + + + + + + + + + 4J_$(ProjectName) + + + 4J_$(ProjectName)_d + + + + Level3 + true + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + stdcpp20 + Use + pch.h + + + + + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + stdcpp20 + Use + pch.h + + + + + true + + + + + Level3 + true + _CRT_SECURE_NO_WARNINGS;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + stdcpp20 + Use + stdafx.h + true + stdafx.h + MultiThreadedDebug + + + + + true + + + + + + Level3 + true + true + true + _CRT_SECURE_NO_WARNINGS;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + stdcpp20 + Use + stdafx.h + true + stdafx.h + MultiThreaded + + + + + true + + + + + + + + + + + + + + + Create + Create + Create + Create + + + + + + + + \ No newline at end of file