diff --git a/src/Util.cpp b/src/Util.cpp index 3b1128e..1997c33 100644 --- a/src/Util.cpp +++ b/src/Util.cpp @@ -8,9 +8,6 @@ #include #include -#include -#include - namespace util { using std::string; @@ -105,15 +102,6 @@ namespace util return false; } - std::string getUserFolderPath() - { - wchar_t* out; - SHGetKnownFolderPath(FOLDERID_Profile, 0, 0, &out); - std::wstring wide = out; - CoTaskMemFree(out); - return wideToUtf8(wide); - } - std::string replaceExtension(const std::string_view filename, const std::string_view extension) { size_t lastdot = filename.find_last_of("."); if (lastdot == std::string::npos) { @@ -122,31 +110,6 @@ namespace util return string(filename.substr(0, lastdot)) + string(extension); } - bool handleHr(const HRESULT& hr, const std::string& message, bool throwOnError) { - bool failed = FAILED(hr); - if (failed) { - _com_error err(hr); - std::wstring errorMessageW = std::wstring(err.ErrorMessage()); - std::string errorMessage = util::wideToUtf8(errorMessageW); - - LOG(WARNING) << message; - LOG(WARNING) << errorMessage; - - if (throwOnError) { - throw std::exception((message + "\n" + errorMessage).c_str()); - } - } - return !failed; - } - - bool warnOnError(const HRESULT& hr, const std::string& message) { - return handleHr(hr, message, false); - } - - bool throwOnError(const HRESULT& hr, const std::string& message) { - return handleHr(hr, message, true); - } - void throwError(const std::string& message) { LOG(WARNING) << message; throw std::exception((message).c_str()); diff --git a/src/Util.h b/src/Util.h index c9ae97d..6a0fbfc 100644 --- a/src/Util.h +++ b/src/Util.h @@ -35,12 +35,8 @@ namespace util }; bool endsWithEither(std::string_view str, std::initializer_list extensions); - std::string getUserFolderPath(); std::string replaceExtension(const std::string_view filename, const std::string_view extension); - bool warnOnError(const HRESULT& hr, const std::string& message); - bool throwOnError(const HRESULT& hr, const std::string& message); - void throwError(const std::string& message); template diff --git a/src/Win.cpp b/src/Win.cpp new file mode 100644 index 0000000..5e1dc85 --- /dev/null +++ b/src/Win.cpp @@ -0,0 +1,44 @@ +#include "stdafx.h" +#include "Win.h" + +#include +#include + +#include "Util.h" + +namespace util +{ + bool handleHr(const HRESULT& hr, const std::string& message, bool throwOnError) { + bool failed = FAILED(hr); + if (failed) { + _com_error err(hr); + std::wstring errorMessageW = std::wstring(err.ErrorMessage()); + std::string errorMessage = util::wideToUtf8(errorMessageW); + + LOG(WARNING) << message; + LOG(WARNING) << errorMessage; + + if (throwOnError) { + throw std::exception((message + "\n" + errorMessage).c_str()); + } + } + return !failed; + } + + bool warnOnError(const HRESULT& hr, const std::string& message) { + return handleHr(hr, message, false); + } + + bool throwOnError(const HRESULT& hr, const std::string& message) { + return handleHr(hr, message, true); + } + + std::string getUserFolderPath() + { + wchar_t* out; + SHGetKnownFolderPath(FOLDERID_Profile, 0, 0, &out); + std::wstring wide = out; + CoTaskMemFree(out); + return wideToUtf8(wide); + } +} \ No newline at end of file diff --git a/src/Win.h b/src/Win.h new file mode 100644 index 0000000..bcfbc41 --- /dev/null +++ b/src/Win.h @@ -0,0 +1,14 @@ +#pragma once + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +#define NOMINMAX // Disable Windows min/max Macros overriding std::min/max + +#include + +namespace util +{ + bool warnOnError(const HRESULT& hr, const std::string& message); + bool throwOnError(const HRESULT& hr, const std::string& message); + + std::string getUserFolderPath(); +} \ No newline at end of file diff --git a/src/assets/DebugMeshes.cpp b/src/assets/DebugMeshes.cpp index 6aff900..a1e8a41 100644 --- a/src/assets/DebugMeshes.cpp +++ b/src/assets/DebugMeshes.cpp @@ -66,7 +66,7 @@ namespace assets faceNormal, UV { 0, 0 }, ARRAY_UV { 0, 0, -1 }, - D3DXCOLOR(1, 0, 0, 1) + COLOR(1, 0, 0, 1) }); } } @@ -96,7 +96,7 @@ namespace assets return result; } - void loadPointDebugVisual(VERT_CHUNKS_BY_MAT& target, const VEC3& pos, const VEC3& scale, const D3DXCOLOR& color) + void loadPointDebugVisual(VERT_CHUNKS_BY_MAT& target, const VEC3& pos, const VEC3& scale, const COLOR& color) { vector facesPos; vector facesOther; @@ -134,7 +134,7 @@ namespace assets return result; } - void loadLineDebugVisual(VERT_CHUNKS_BY_MAT& target, const VEC3& posStart, VEC3& posEnd, const D3DXCOLOR& color) + void loadLineDebugVisual(VERT_CHUNKS_BY_MAT& target, const VEC3& posStart, VEC3& posEnd, const COLOR& color) { vector facesPos; vector facesOther; diff --git a/src/assets/DebugMeshes.h b/src/assets/DebugMeshes.h index 9b3b5e9..6d34d2f 100644 --- a/src/assets/DebugMeshes.h +++ b/src/assets/DebugMeshes.h @@ -1,10 +1,10 @@ #pragma once -#include "render/Renderer.h" +#include "render/Loader.h" namespace assets { void loadInstanceMeshBboxDebugVisual(render::VERT_CHUNKS_BY_MAT& target, const render::StaticInstance& instance); - void loadPointDebugVisual(render::VERT_CHUNKS_BY_MAT& target, const VEC3& pos, const VEC3& scale = { 0.f, 0.f, 0.f }, const D3DXCOLOR& color = D3DXCOLOR(1, 0, 0, 1)); - void loadLineDebugVisual(render::VERT_CHUNKS_BY_MAT& target, const VEC3& posStart, VEC3& posEnd, const D3DXCOLOR& color = D3DXCOLOR(1, 0, 0, 1)); + void loadPointDebugVisual(render::VERT_CHUNKS_BY_MAT& target, const VEC3& pos, const VEC3& scale = { 0.f, 0.f, 0.f }, const COLOR& color = COLOR(1, 0, 0, 1)); + void loadLineDebugVisual(render::VERT_CHUNKS_BY_MAT& target, const VEC3& posStart, VEC3& posEnd, const COLOR& color = COLOR(1, 0, 0, 1)); } \ No newline at end of file diff --git a/src/assets/FindGroundFace.h b/src/assets/FindGroundFace.h index 5d61b47..97dea8a 100644 --- a/src/assets/FindGroundFace.h +++ b/src/assets/FindGroundFace.h @@ -5,7 +5,7 @@ namespace assets { - D3DXCOLOR interpolateColor(const VEC3& pos, const render::VERTEX_DATA_BY_MAT& meshData, const render::VertKey& vertKey); + COLOR interpolateColor(const VEC3& pos, const render::VERTEX_DATA_BY_MAT& meshData, const render::VertKey& vertKey); std::optional getGroundFaceAtPos(const DirectX::XMVECTOR pos, const render::VERT_CHUNKS_BY_MAT& meshData, const VertLookupTree& vertLookup); } diff --git a/src/assets/LookupTrees.h b/src/assets/LookupTrees.h index f6cd679..bffa063 100644 --- a/src/assets/LookupTrees.h +++ b/src/assets/LookupTrees.h @@ -1,6 +1,6 @@ #pragma once -#include "render/Renderer.h" +#include "render/Loader.h" #include diff --git a/src/assets/MeshFromVdfLoader.cpp b/src/assets/MeshFromVdfLoader.cpp index 58179a6..3ecc178 100644 --- a/src/assets/MeshFromVdfLoader.cpp +++ b/src/assets/MeshFromVdfLoader.cpp @@ -223,8 +223,8 @@ namespace assets VERTEX_OTHER other; other.normal = toVec3(faceNormalsXm[i]); other.uvDiffuse = from(zenVert.TexCoord); - other.colLight = fromSRGB(D3DXCOLOR(zenVert.Color)); - //other.colLight = D3DXCOLOR(1, 1, 1, 0.f); + other.colLight = fromSRGB(COLOR(zenVert.Color)); + //other.colLight = COLOR(1, 1, 1, 0.f); other.dirLight = { -100.f, -100.f, -100.f };// value that is easy to check as not normalized in shader other.lightSun = hasLightmap ? 0.f : 1.0f; diff --git a/src/assets/MeshFromVdfLoader.h b/src/assets/MeshFromVdfLoader.h index 2512493..65e3aca 100644 --- a/src/assets/MeshFromVdfLoader.h +++ b/src/assets/MeshFromVdfLoader.h @@ -1,14 +1,10 @@ #pragma once #include "AssetCache.h" -#include "render/Renderer.h" -#include "vdfs/fileIndex.h" +#include "render/Loader.h" -#include "DirectXTex.h" -#include "zenload/zTypes.h" #include "zenload/zCMesh.h" #include "zenload/zCProgMeshProto.h" -#include "zenload/zCModelMeshLib.h" namespace assets { diff --git a/src/assets/ObjLoader.cpp b/src/assets/ObjLoader.cpp index e8f0059..1e5ba99 100644 --- a/src/assets/ObjLoader.cpp +++ b/src/assets/ObjLoader.cpp @@ -102,7 +102,7 @@ namespace assets other.uvDiffuse = { 0, 0 }; } - other.colLight = D3DXCOLOR( 1, 1, 1, 1 ); + other.colLight = COLOR( 1, 1, 1, 1 ); other.uvLightmap = { 0, 0 }; // Wavefront .obj verts are stored counter-clockwise, so we switch to clockwise diff --git a/src/assets/StaticLightFromVobLights.cpp b/src/assets/StaticLightFromVobLights.cpp index 12a9c7f..a22ee5a 100644 --- a/src/assets/StaticLightFromVobLights.cpp +++ b/src/assets/StaticLightFromVobLights.cpp @@ -54,7 +54,7 @@ namespace assets auto intersectedBoxes = lightLookup.tree.RangeSearch(searchBox); int32_t contributingLightCount = 0; - D3DXCOLOR color = D3DXCOLOR(0.f, 0.f, 0.f, 1.f); + COLOR color = COLOR(0.f, 0.f, 0.f, 1.f); XMVECTOR candidateLightDir = XMVectorSet(0, 0, 0, 0);// TODO this is actually not necessary, but fixes warnings float candidateScore = 0; @@ -72,7 +72,7 @@ namespace assets contributingLightCount++; float weight = 1.f - (dist / (light.range * 1.0f)); weight = fromSRGB(weight); - color += (light.color * weight); + color = add(color, mul(light.color, weight)); float perceivedLum = (light.color.r * 0.299f + light.color.g * 0.587f + light.color.b * 0.114f); float score = weight * perceivedLum; if (score > candidateScore) { @@ -81,7 +81,7 @@ namespace assets } } if (dist < debugStaticLightRaysMaxDist) { - debugLightToVobRays.push_back({ light.pos, pos, intersectedWorld ? D3DXCOLOR(0.f, 0.f, 1.f, 0.5f) : D3DXCOLOR(1.f, 0.f, 0.f, 0.5f) }); + debugLightToVobRays.push_back({ light.pos, pos, intersectedWorld ? COLOR(0.f, 0.f, 1.f, 0.5f) : COLOR(1.f, 0.f, 0.f, 0.5f) }); } } } diff --git a/src/assets/StaticLightFromVobLights.h b/src/assets/StaticLightFromVobLights.h index a4446ac..fa26b50 100644 --- a/src/assets/StaticLightFromVobLights.h +++ b/src/assets/StaticLightFromVobLights.h @@ -6,7 +6,7 @@ namespace assets { struct DirectionalLight { - D3DXCOLOR color; + COLOR color; DirectX::XMVECTOR dirInverted; }; @@ -24,7 +24,7 @@ namespace assets struct DebugLine { VEC3 posStart; VEC3 posEnd; - D3DXCOLOR color; + COLOR color; }; extern std::vector debugLightToVobRays; } \ No newline at end of file diff --git a/src/assets/TexFromVdfLoader.h b/src/assets/TexFromVdfLoader.h index 9508306..0eea5d2 100644 --- a/src/assets/TexFromVdfLoader.h +++ b/src/assets/TexFromVdfLoader.h @@ -1,6 +1,6 @@ #pragma once -#include "render/Renderer.h" +#include "render/Loader.h" #include "vdfs/fileIndex.h" #include "zenload/zCMesh.h" diff --git a/src/assets/ZenLoader.cpp b/src/assets/ZenLoader.cpp index 3dc9f3e..a080f94 100644 --- a/src/assets/ZenLoader.cpp +++ b/src/assets/ZenLoader.cpp @@ -17,7 +17,6 @@ #include "FindGroundFace.h" #include "StaticLightFromVobLights.h" -#include "DirectXTex.h" #include "zenload/zCMesh.h" #include "zenload/zenParser.h" #include "zenload/ztex2dds.h" @@ -136,7 +135,7 @@ namespace assets if (debugInstanceMeshBboxCenter) { auto center = toVec3(bboxCenter(instance.bbox)); auto scale = toVec3(0.7f * XMVectorAbs(toXM4Pos(instance.bbox[1]) - toXM4Pos(instance.bbox[0]))); - loadPointDebugVisual(target, center, scale, D3DXCOLOR(0, 0, 1, 1)); + loadPointDebugVisual(target, center, scale, COLOR(0, 0, 1, 1)); } return true; @@ -188,7 +187,7 @@ namespace assets return flattenVobTree(vobs, target, filter); } - inline std::ostream& operator <<(std::ostream& os, const D3DXCOLOR& that) + inline std::ostream& operator <<(std::ostream& os, const COLOR& that) { return os << "[R:" << that.r << " G:" << that.g << " B:" << that.b << " A:" << that.a << "]"; } @@ -212,7 +211,7 @@ namespace assets Light light = { toVec3(toXM4Pos(vob.position) * G_ASSET_RESCALE), vob.zCVobLight.lightStatic, - fromSRGB(D3DXCOLOR(vob.zCVobLight.color)), + fromSRGB(COLOR(vob.zCVobLight.color)), vob.zCVobLight.range * G_ASSET_RESCALE, }; @@ -223,7 +222,7 @@ namespace assets return lights; } - D3DXCOLOR interpolateColor(const VEC3& pos, const VERT_CHUNKS_BY_MAT& meshData, const VertKey& vertKey) + COLOR interpolateColor(const VEC3& pos, const VERT_CHUNKS_BY_MAT& meshData, const VertKey& vertKey) { auto& vecVertData = vertKey.get(meshData); auto& vecPos = vecVertData.vecPos; @@ -236,10 +235,10 @@ namespace assets float v0Contrib = 1 - (v0Distance / totalDistance); float v1Contrib = 1 - (v1Distance / totalDistance); float v2Contrib = 1 - (v2Distance / totalDistance); - D3DXCOLOR v0Color = others[vertIndex + 0].colLight; - D3DXCOLOR v1Color = others[vertIndex + 1].colLight; - D3DXCOLOR v2Color = others[vertIndex + 2].colLight; - D3DXCOLOR colorAverage = ((v0Color * v0Contrib) + (v1Color * v1Contrib) + (v2Color * v2Contrib)) / 2.f; + COLOR v0Color = others[vertIndex + 0].colLight; + COLOR v1Color = others[vertIndex + 1].colLight; + COLOR v2Color = others[vertIndex + 2].colLight; + COLOR colorAverage = mul(add(add(mul(v0Color, v0Contrib), mul(v1Color, v1Contrib)), mul(v2Color, v2Contrib)), 0.5f); return colorAverage; } @@ -288,7 +287,7 @@ namespace assets instance.dirLightStatic = -1 * XMVectorSet(1, -0.5, -1.0, 0); - D3DXCOLOR colLight; + COLOR colLight; const XMVECTOR center = bboxCenter(instance.bbox); const std::optional vertKey = getGroundFaceAtPos(center, worldMeshData, worldFaceLookup); @@ -319,9 +318,9 @@ namespace assets instance.dirLightStatic = optLight.value().dirInverted; } else { - colLight = D3DXCOLOR(0, 0, 0, 1);// no lights reached this vob, so its black + colLight = COLOR(0, 0, 0, 1);// no lights reached this vob, so its black if (debugStaticLightRays) { - colLight = D3DXCOLOR(0, 1, 0, 1); + colLight = COLOR(0, 1, 0, 1); } } resolvedStaticLight++; @@ -340,18 +339,18 @@ namespace assets bool isVobIndoor = false; float minLight = isVobIndoor ? fromSRGB(0.2f) : fromSRGB(0.5f); - colLight = colLight * (1.f - minLight) + greyscale(minLight); + colLight = add(mul(colLight, (1.f - minLight)), greyscale(minLight)); // currently this results in light values between between 0.22 and 0.99 } } else { - colLight = fromSRGB(D3DXCOLOR(0.63f, 0.63f, 0.63f, 1));// fallback lightness of (160, 160, 160) + colLight = fromSRGB(COLOR(0.63f, 0.63f, 0.63f, 1));// fallback lightness of (160, 160, 160) } colLight.a = 1;// indicates that this VOB receives full sky light } if (debugTintVobStaticLight) { - colLight = D3DXCOLOR((colLight.r / 3.f) * 2.f, colLight.g, colLight.b, colLight.a); + colLight = COLOR((colLight.r / 3.f) * 2.f, colLight.g, colLight.b, colLight.a); } instance.colLightStatic = colLight; diff --git a/src/assets/ZenLoader.h b/src/assets/ZenLoader.h index b5af4c8..0b15385 100644 --- a/src/assets/ZenLoader.h +++ b/src/assets/ZenLoader.h @@ -1,6 +1,6 @@ #pragma once -#include "render/Renderer.h" +#include "render/Loader.h" #include "vdfs/fileIndex.h" diff --git a/src/render/Camera.h b/src/render/Camera.h index 2846fe8..664f5be 100644 --- a/src/render/Camera.h +++ b/src/render/Camera.h @@ -1,6 +1,6 @@ #pragma once -#include "Common.h" +#include "Primitives.h" namespace render::camera { diff --git a/src/render/Common.cpp b/src/render/Common.cpp index eac8df0..65a65d0 100644 --- a/src/render/Common.cpp +++ b/src/render/Common.cpp @@ -1,85 +1,5 @@ #include "stdafx.h" #include "Common.h" -#include -#include - namespace render { - - void release(IUnknown* dx11object) { - if (dx11object != nullptr) { - dx11object->Release(); - } - } - - void release(const std::vector& dx11objects) { - for (auto object : dx11objects) { - release(object); - } - } - - void initViewport(BufferSize& size, D3D11_VIEWPORT* viewport) { - ZeroMemory(viewport, sizeof(D3D11_VIEWPORT)); - - viewport->TopLeftX = 0.f; - viewport->TopLeftY = 0.f; - viewport->Width = (float) size.width; - viewport->Height = (float) size.height; - viewport->MinDepth = 0.f; - viewport->MaxDepth = 1.f; - } - - float fromSRGB(const float channel) { - return (channel <= 0.04045f) ? (channel / 12.92f) : pow((channel + 0.055f) / 1.055f, 2.4f); - } - - D3DXCOLOR fromSRGB(const D3DXCOLOR color) { - return D3DXCOLOR( - fromSRGB(color.r), - fromSRGB(color.g), - fromSRGB(color.b), - color.a); - } - - D3DXCOLOR greyscale(const float channel) { - return D3DXCOLOR(channel, channel, channel, 1); - } - - D3DXCOLOR multiplyColor(D3DXCOLOR color, const float factor) { - return D3DXCOLOR( - color.r * factor, - color.g * factor, - color.b * factor, - color.a); - } - - template - float* begin(T& t) { - return t.vec; - } - template - const float* begin(const T& t) { - return t.vec; - } - template - const float* end(const T& t) { - return t.vec + std::size(t.vec); - } - - template - T add(const T& vec1, const T& vec2) { - T result; - std::transform(begin(vec1), end(vec1), begin(vec2), begin(result), std::plus()); - return result; - } - template - T mul(const T& vec, float scalar) { - T result; - std::transform(begin(vec), end(vec), begin(result), std::bind(std::multiplies(), std::placeholders::_1, scalar)); - return result; - } - - // instantiate template functions for the types we want to support (needed because templates are not in header) - template UV add(const UV& vec1, const UV& vec2); - template UV mul(const UV& vec, float scalar); } \ No newline at end of file diff --git a/src/render/Common.h b/src/render/Common.h index b74d50c..7d2e3da 100644 --- a/src/render/Common.h +++ b/src/render/Common.h @@ -1,8 +1,8 @@ #pragma once -#include "dx11.h" #include "Primitives.h" +#include #include #include #include @@ -96,6 +96,7 @@ namespace render hash ^= hasher(value) + 0x9e3779b9 + (hash << 6) + (hash >> 2); } } + namespace std { using namespace render; @@ -164,26 +165,4 @@ namespace render return { vertData[this->vertIndex], vertData[this->vertIndex + 1], vertData[this->vertIndex + 2] }; } }; - - struct BufferSize { - uint32_t width; - uint32_t height; - - BufferSize operator*(const float scalar) const - { - return { (uint32_t)((width * scalar) + 0.5f), (uint32_t)((height * scalar) + 0.5f) }; - } - }; - - void release(IUnknown* dx11object); - void release(const std::vector& dx11objects); - void initViewport(BufferSize& size, D3D11_VIEWPORT* viewport); - - float fromSRGB(const float channel); - D3DXCOLOR fromSRGB(const D3DXCOLOR color); - D3DXCOLOR greyscale(const float channel); - D3DXCOLOR multiplyColor(D3DXCOLOR color, const float factor); - - template T add(const T& vec1, const T& vec2); - template T mul(const T& vec, float scalar); } \ No newline at end of file diff --git a/src/render/Gui.h b/src/render/Gui.h index a42ddd3..dd68945 100644 --- a/src/render/Gui.h +++ b/src/render/Gui.h @@ -1,6 +1,6 @@ #pragma once -#include "dx11.h" +#include "WinDx.h" namespace render { diff --git a/src/render/Loader.h b/src/render/Loader.h new file mode 100644 index 0000000..d27a617 --- /dev/null +++ b/src/render/Loader.h @@ -0,0 +1,37 @@ +#pragma once + +#include "Common.h" + +namespace render +{ + struct StaticInstance { + std::string meshName; + DirectX::XMMATRIX transform; + std::array bbox;// pos_min, pos_max + bool receiveLightSun; + COLOR colLightStatic; + DirectX::XMVECTOR dirLightStatic;// pre-inverted + }; + + struct Light { + // TODO falloff and type surely play a role + VEC3 pos; + bool isStatic; + COLOR color; + float range; + }; + + struct InMemoryTexFile { + int32_t width; + int32_t height; + std::vector ddsRaw; + }; + + struct RenderData { + bool isOutdoorLevel = false; + VERT_CHUNKS_BY_MAT worldMesh; + VERT_CHUNKS_BY_MAT staticMeshes; + VERTEX_DATA_BY_MAT dynamicMeshes; + std::vector worldMeshLightmaps; + }; +} \ No newline at end of file diff --git a/src/render/Primitives.cpp b/src/render/Primitives.cpp new file mode 100644 index 0000000..8ca8358 --- /dev/null +++ b/src/render/Primitives.cpp @@ -0,0 +1,82 @@ +#include "stdafx.h" +#include "Primitives.h" + +COLOR::COLOR(uint32_t argb) { + const float f = 1.0f / 255.0f; + r = f * (float)(uint8_t)(argb >> 16); + g = f * (float)(uint8_t)(argb >> 8); + b = f * (float)(uint8_t)(argb >> 0); + a = f * (float)(uint8_t)(argb >> 24); +} +COLOR::COLOR(float r_, float g_, float b_, float a_) { + r = r_; + g = g_; + b = b_; + a = a_; +} + +namespace render { + float fromSRGB(const float channel) { + return (channel <= 0.04045f) ? (channel / 12.92f) : pow((channel + 0.055f) / 1.055f, 2.4f); + } + + COLOR fromSRGB(const COLOR color) { + return COLOR( + fromSRGB(color.r), + fromSRGB(color.g), + fromSRGB(color.b), + color.a); + } + + COLOR greyscale(const float channel) { + return COLOR(channel, channel, channel, 1); + } + + COLOR multiplyColor(COLOR color, const float factor) { + return COLOR( + color.r * factor, + color.g * factor, + color.b * factor, + color.a); + } + + template + float* begin(T& t) { + return t.vec; + } + template + const float* begin(const T& t) { + return t.vec; + } + template + const float* end(const T& t) { + return t.vec + std::size(t.vec); + } + + template + T add(const T& vec1, const T& vec2) { + T result; + std::transform(begin(vec1), end(vec1), begin(vec2), begin(result), std::plus()); + return result; + } + template + T sub(const T& vec1, const T& vec2) { + T result; + std::transform(begin(vec1), end(vec1), begin(vec2), begin(result), std::minus()); + return result; + } + template + T mul(const T& vec, float scalar) { + T result; + std::transform(begin(vec), end(vec), begin(result), std::bind(std::multiplies(), std::placeholders::_1, scalar)); + return result; + } + + // instantiate template functions for the types we want to support (needed because templates are not in header) + template COLOR add(const COLOR& vec1, const COLOR& vec2); + template COLOR sub(const COLOR& vec1, const COLOR& vec2); + template COLOR mul(const COLOR& vec, float scalar); + + template UV add(const UV& vec1, const UV& vec2); + template UV mul(const UV& vec, float scalar); +} \ No newline at end of file diff --git a/src/render/Primitives.h b/src/render/Primitives.h index 1255263..1fdc20d 100644 --- a/src/render/Primitives.h +++ b/src/render/Primitives.h @@ -1,9 +1,17 @@ #pragma once -#include "dx11.h" #include -inline std::ostream& operator <<(std::ostream& os, const D3DXCOLOR& that) +struct COLOR { + union { + struct { float r, g, b, a; }; + float vec[4]; + }; + COLOR() {}; + COLOR(uint32_t argb); + COLOR(float r, float g, float b, float a); +}; +inline std::ostream& operator <<(std::ostream& os, const COLOR& that) { return os << "[R:" << that.r << " G:" << that.g << " B:" << that.b << " A:" << that.a << "]"; } @@ -63,7 +71,7 @@ inline std::ostream& operator <<(std::ostream& os, const ARRAY_UV& that) struct POS_COLOR { VEC3 position; - D3DXCOLOR color; + COLOR color; }; struct POS_UV { @@ -92,7 +100,7 @@ struct NORMAL_CL_UV_LUV_STATIC_LIGHT { VEC3 normal; UV uvDiffuse; ARRAY_UV uvLightmap; - D3DXCOLOR colLight; + COLOR colLight; VEC3 dirLight; float lightSun; }; @@ -101,4 +109,26 @@ inline std::ostream& operator <<(std::ostream& os, const NORMAL_CL_UV_LUV_STATIC return os << "[NOR:" << that.normal << " COL_LIGHT:" << that.colLight << " DIR_LIGHT:" << that.dirLight << " UV_DIFF:" << that.uvDiffuse << " UV_LM:" << that.uvLightmap << "]"; } -typedef uint32_t TEX_INDEX; \ No newline at end of file +typedef uint32_t TEX_INDEX; + +namespace render { + + struct BufferSize { + uint32_t width; + uint32_t height; + + BufferSize operator*(const float scalar) const + { + return { (uint32_t)((width * scalar) + 0.5f), (uint32_t)((height * scalar) + 0.5f) }; + } + }; + + float fromSRGB(const float channel); + COLOR fromSRGB(const COLOR color); + COLOR greyscale(const float channel); + COLOR multiplyColor(COLOR color, const float factor); + + template T add(const T& vec1, const T& vec2); + template T sub(const T& vec1, const T& vec2); + template T mul(const T& vec, float scalar); +} \ No newline at end of file diff --git a/src/render/RenderUtil.cpp b/src/render/RenderUtil.cpp index 3eca76b..01a0c25 100644 --- a/src/render/RenderUtil.cpp +++ b/src/render/RenderUtil.cpp @@ -3,6 +3,17 @@ namespace render::util { + void initViewport(BufferSize& size, D3D11_VIEWPORT* viewport) { + ZeroMemory(viewport, sizeof(D3D11_VIEWPORT)); + + viewport->TopLeftX = 0.f; + viewport->TopLeftY = 0.f; + viewport->Width = (float)size.width; + viewport->Height = (float)size.height; + viewport->MinDepth = 0.f; + viewport->MaxDepth = 1.f; + } + void dumpVerts(const std::string& matName, const std::vector& vertPos, const std::vector& vertOther) { std::ostringstream buffer; buffer << matName << std::endl; diff --git a/src/render/RenderUtil.h b/src/render/RenderUtil.h index 9ceea92..dfef904 100644 --- a/src/render/RenderUtil.h +++ b/src/render/RenderUtil.h @@ -4,6 +4,8 @@ namespace render::util { + void initViewport(BufferSize& size, D3D11_VIEWPORT* viewport); + void dumpVerts(const std::string& matName, const std::vector& vertPos, const std::vector& vertOther); std::string getVramUsage(IDXGIAdapter3* adapter); diff --git a/src/render/Renderer.h b/src/render/Renderer.h index 4f425ad..bdf92e1 100644 --- a/src/render/Renderer.h +++ b/src/render/Renderer.h @@ -1,43 +1,11 @@ #pragma once - -#include "dx11.h" +#include "WinDx.h" #include "Common.h" #include "Texture.h" namespace render { - struct StaticInstance { - std::string meshName; - DirectX::XMMATRIX transform; - std::array bbox;// pos_min, pos_max - bool receiveLightSun; - D3DXCOLOR colLightStatic; - DirectX::XMVECTOR dirLightStatic;// pre-inverted - }; - - struct Light { - // TODO falloff and type surely play a role - VEC3 pos; - bool isStatic; - D3DXCOLOR color; - float range; - }; - - struct InMemoryTexFile { - int32_t width; - int32_t height; - std::vector ddsRaw; - }; - - struct RenderData { - bool isOutdoorLevel = false; - VERT_CHUNKS_BY_MAT worldMesh; - VERT_CHUNKS_BY_MAT staticMeshes; - VERTEX_DATA_BY_MAT dynamicMeshes; - std::vector worldMeshLightmaps; - }; - struct DecalMesh { ID3D11Buffer* vertexBuffer = nullptr; diff --git a/src/render/Shader.h b/src/render/Shader.h index c72b9ec..f361a7f 100644 --- a/src/render/Shader.h +++ b/src/render/Shader.h @@ -1,7 +1,7 @@ #pragma once #include -#include "dx11.h" +#include "WinDx.h" namespace render { diff --git a/src/render/ShaderManager.h b/src/render/ShaderManager.h index 63b5330..aed22b0 100644 --- a/src/render/ShaderManager.h +++ b/src/render/ShaderManager.h @@ -1,7 +1,7 @@ #pragma once #include -#include "dx11.h" +#include "WinDx.h" #include "Shader.h" namespace render diff --git a/src/render/Sky.cpp b/src/render/Sky.cpp index e62861e..9f817dd 100644 --- a/src/render/Sky.cpp +++ b/src/render/Sky.cpp @@ -26,12 +26,12 @@ namespace render struct SkyState { float timeKey; - D3DXCOLOR lightColor;// same as polyColor - D3DXCOLOR skyColor;// same as fogColor + COLOR lightColor;// same as polyColor + COLOR skyColor;// same as fogColor }; - D3DXCOLOR fromSRGB(uint8_t r, uint8_t g, uint8_t b) { - return D3DXCOLOR( + COLOR fromSRGB(uint8_t r, uint8_t g, uint8_t b) { + return COLOR( fromSRGB(r / 256.f), fromSRGB(g / 256.f), fromSRGB(b / 256.f), @@ -45,7 +45,7 @@ namespace render // G1 defines an additional texture brightness color (domeColor1) in SkyState, however it is hardcoded to not be used by base night layer (star texture) // and it is effectively set to 255 for any time other than night time, which means it only ever affects the night overlay (night clouds texture). // G1 hardcodes re-scaling of domeColor1 to range 128 - 255. - const D3DXCOLOR nightCloudColor = fromSRGB((255 + 55) / 2, (255 + 55) / 2, (255 + 155) / 2); + const COLOR nightCloudColor = fromSRGB((255 + 55) / 2, (255 + 55) / 2, (255 + 155) / 2); // We assume that all state arrays have same length and use same timeKeys in same order as defined here. // In theory, we don't need to put time keys into every state struct, but this makes state definitions more readable. @@ -119,8 +119,8 @@ namespace render return { interpolate(last.u, next.u, delta), interpolate(last.v, next.v, delta) }; } - D3DXCOLOR interpolate(D3DXCOLOR last, D3DXCOLOR next, float delta) { - return last + (next - last) * delta; + COLOR interpolate(COLOR last, COLOR next, float delta) { + return add(last, mul(sub(next, last), delta)); } CurrentTimeKeys getTimeKeysInterpolated(float timeKey) @@ -218,13 +218,13 @@ namespace render return timeOfDay >= timekey::day_start || timeOfDay <= timekey::day_end; } - D3DXCOLOR getSkyLightFromIntensity(float intensity, float currentTime) + COLOR getSkyLightFromIntensity(float intensity, float currentTime) { SkyState sky = getSkyState(currentTime); return multiplyColor(sky.lightColor, intensity); } - D3DXCOLOR getSkyColor(float currentTime) + COLOR getSkyColor(float currentTime) { return getSkyState(currentTime).skyColor; } diff --git a/src/render/Sky.h b/src/render/Sky.h index 80efa90..6e64cff 100644 --- a/src/render/Sky.h +++ b/src/render/Sky.h @@ -1,6 +1,6 @@ #pragma once -#include "dx11.h" +#include "WinDx.h" #include #include "Common.h" @@ -20,7 +20,7 @@ namespace render SkyTex tex; float alpha; UV uvSpeed = { 0, 0 }; - D3DXCOLOR texlightColor = greyscale(1); + COLOR texlightColor = greyscale(1); }; inline std::ostream& operator <<(std::ostream& os, const SkyTexState& that) { @@ -29,7 +29,7 @@ namespace render std::array getSkyLayers(float timeOfDay); boolean getSwapLayers(float timeOfDay); - D3DXCOLOR getSkyLightFromIntensity(float intensity, float currentTime = defaultTime); - D3DXCOLOR getSkyColor(float currentTime = defaultTime); + COLOR getSkyLightFromIntensity(float intensity, float currentTime = defaultTime); + COLOR getSkyColor(float currentTime = defaultTime); } diff --git a/src/render/Texture.h b/src/render/Texture.h index dfa27a4..d4940b6 100644 --- a/src/render/Texture.h +++ b/src/render/Texture.h @@ -1,7 +1,7 @@ #pragma once #include -#include "dx11.h" +#include "WinDx.h" #include "Common.h" namespace render diff --git a/src/render/WinDx.cpp b/src/render/WinDx.cpp new file mode 100644 index 0000000..055047f --- /dev/null +++ b/src/render/WinDx.cpp @@ -0,0 +1,17 @@ +#include "stdafx.h" +#include "WinDx.h" + +namespace render { + + void release(IUnknown* dx11object) { + if (dx11object != nullptr) { + dx11object->Release(); + } + } + + void release(const std::vector& dx11objects) { + for (auto object : dx11objects) { + release(object); + } + } +} \ No newline at end of file diff --git a/src/render/dx11.h b/src/render/WinDx.h similarity index 69% rename from src/render/dx11.h rename to src/render/WinDx.h index 2d77b1a..2a225ee 100644 --- a/src/render/dx11.h +++ b/src/render/WinDx.h @@ -16,21 +16,27 @@ // $(IncludePath); $(DXSDK_DIR)Include // $(LibraryPath); $(DXSDK_DIR)Lib\x64 +#include "Win.h" + #include // This is only needed to test for hardware/software capability, otherwise it is not used #include -#include +//#include //TODO why was this here, and why in the middle, and why the "x" variant? #include #include #include -//#include -#include +//#include TODO remove +//#include +namespace render { + struct D3d { + ID3D11Device* device; + ID3D11DeviceContext* deviceContext; + ID3DUserDefinedAnnotation* annotation; + }; -struct D3d { - ID3D11Device* device; - ID3D11DeviceContext* deviceContext; - ID3DUserDefinedAnnotation* annotation; -}; \ No newline at end of file + void release(IUnknown* dx11object); + void release(const std::vector& dx11objects); +} diff --git a/src/render/pass/PassForward.cpp b/src/render/pass/PassForward.cpp index 391b6e6..d4b415f 100644 --- a/src/render/pass/PassForward.cpp +++ b/src/render/pass/PassForward.cpp @@ -5,6 +5,7 @@ #include "../Sky.h" #include "PassSky.h" #include "PassWorld.h" +#include "../RenderUtil.h" namespace render::pass::forward { @@ -13,7 +14,7 @@ namespace render::pass::forward __declspec(align(16)) struct CbGlobalSettings { // Note: smallest type for constant buffer values is 32 bit; cannot use bool or uint_16 without packing - D3DXCOLOR skyLight; + COLOR skyLight; int32_t multisampleTransparency; int32_t distantAlphaDensityFix; uint32_t outputType; @@ -106,7 +107,7 @@ namespace render::pass::forward d3d.deviceContext->RSSetViewports(1, &viewport); // clear the back buffer to background color - d3d.deviceContext->ClearRenderTargetView(targetRtv, world::getBackgroundColor()); + d3d.deviceContext->ClearRenderTargetView(targetRtv, world::getBackgroundColor().vec); // clear depth and stencil buffer const float zFar = settings.reverseZ ? 0.0f : 1.0f; @@ -206,7 +207,7 @@ namespace render::pass::forward void initViewport(BufferSize& size) { - initViewport(size, &viewport); + util::initViewport(size, &viewport); } void initDepthBuffer(D3d d3d, BufferSize& size, uint32_t multisampleCount, bool reverseZ) diff --git a/src/render/pass/PassForward.h b/src/render/pass/PassForward.h index b154571..f6952be 100644 --- a/src/render/pass/PassForward.h +++ b/src/render/pass/PassForward.h @@ -1,6 +1,6 @@ #pragma once -#include "../dx11.h" +#include "../WinDx.h" #include "../Common.h" #include "../ShaderManager.h" #include "../Settings.h" diff --git a/src/render/pass/PassPost.cpp b/src/render/pass/PassPost.cpp index 86a45c8..96035a1 100644 --- a/src/render/pass/PassPost.cpp +++ b/src/render/pass/PassPost.cpp @@ -237,7 +237,7 @@ namespace render::pass::post } void initViewport(BufferSize& size) { - initViewport(size, &viewport); + util::initViewport(size, &viewport); } void initLinearSampler(D3d d3d, bool pointSampling) diff --git a/src/render/pass/PassSky.cpp b/src/render/pass/PassSky.cpp index 3a2d93d..fb24bdd 100644 --- a/src/render/pass/PassSky.cpp +++ b/src/render/pass/PassSky.cpp @@ -33,7 +33,7 @@ namespace render::pass::sky __declspec(align(16)) struct CbSkyLayer { - D3DXCOLOR light;// original only uses values other than 1 on overlay + COLOR light;// original only uses values other than 1 on overlay float alpha; uint32_t blurDisabled; }; @@ -41,7 +41,7 @@ namespace render::pass::sky __declspec(align(16)) struct CbSkyLayerSettings { // Note: smallest type for constant buffer values is 32 bit; cannot use bool or uint_16 without packing - D3DXCOLOR colBackground; + COLOR colBackground; CbSkyLayer texLayers[2]; }; @@ -172,7 +172,7 @@ namespace render::pass::sky } } - void updateSkyLayers(D3d d3d, const array& layerStates, const D3DXCOLOR& skyBackground, float timeOfDay, bool swapLayers) + void updateSkyLayers(D3d d3d, const array& layerStates, const COLOR& skyBackground, float timeOfDay, bool swapLayers) { float delta1 = timeOfDay - lastTimeOfDay; float delta2 = timeOfDay + 1 - lastTimeOfDay; diff --git a/src/render/pass/PassSky.h b/src/render/pass/PassSky.h index c92e1c8..6686862 100644 --- a/src/render/pass/PassSky.h +++ b/src/render/pass/PassSky.h @@ -7,7 +7,7 @@ namespace render::pass::sky { void loadSky(D3d d3d); - void updateSkyLayers(D3d d3d, const std::array& layerStates, const D3DXCOLOR& skyBackground, float timeOfDay, bool swapLayers); + void updateSkyLayers(D3d d3d, const std::array& layerStates, const COLOR& skyBackground, float timeOfDay, bool swapLayers); void drawSky(D3d d3d, ShaderManager* shaders, const ShaderCbs& cbs, ID3D11SamplerState* layerSampler); void initConstantBuffers(D3d d3d); } diff --git a/src/render/pass/PassWorld.cpp b/src/render/pass/PassWorld.cpp index f42385d..6eabda3 100644 --- a/src/render/pass/PassWorld.cpp +++ b/src/render/pass/PassWorld.cpp @@ -179,12 +179,12 @@ namespace render::pass::world sky::initConstantBuffers(d3d); } - D3DXCOLOR getBackgroundColor() { + COLOR getBackgroundColor() { if (world.isOutdoorLevel) { return getSkyColor(worldSettings.timeOfDay); } else { - return D3DXCOLOR(0.0f, 0.2f, 0.4f, 1.0f);// deep blue + return COLOR(0.0f, 0.2f, 0.4f, 1.0f);// deep blue } } diff --git a/src/render/pass/PassWorld.h b/src/render/pass/PassWorld.h index d605fac..4b95a5a 100644 --- a/src/render/pass/PassWorld.h +++ b/src/render/pass/PassWorld.h @@ -1,6 +1,6 @@ #pragma once -#include "../dx11.h" +#include "../WinDx.h" #include "../Settings.h" #include "../Renderer.h" #include "../ShaderManager.h" @@ -31,7 +31,7 @@ namespace render::pass::world const WorldSettings& getWorldSettings(); void initLinearSampler(D3d d3d, RenderSettings& settings); void init(D3d d3d); - D3DXCOLOR getBackgroundColor(); + COLOR getBackgroundColor(); void drawSky(D3d d3d, ShaderManager* shaders, const ShaderCbs& cbs); void drawPrepass(D3d d3d, ShaderManager* shaders, const ShaderCbs& cbs); void drawWorld(D3d d3d, ShaderManager* shaders, const ShaderCbs& cbs); diff --git a/src/render/pass/PassWorldLoader.cpp b/src/render/pass/PassWorldLoader.cpp index 52ff208..4939c31 100644 --- a/src/render/pass/PassWorldLoader.cpp +++ b/src/render/pass/PassWorldLoader.cpp @@ -1,6 +1,7 @@ #include "stdafx.h" #include "PassWorldLoader.h" +#include "render/Loader.h" #include "PassWorldChunkGrid.h" #include "assets/AssetCache.h" @@ -10,6 +11,7 @@ #include "assets/TexFromVdfLoader.h" #include "Util.h" +#include "Win.h" #include "render/RenderUtil.h" namespace render::pass::world diff --git a/src/render/pass/PassWorldLoader.h b/src/render/pass/PassWorldLoader.h index a1f7412..6cb3485 100644 --- a/src/render/pass/PassWorldLoader.h +++ b/src/render/pass/PassWorldLoader.h @@ -1,6 +1,6 @@ #pragma once -#include "../dx11.h" +#include "../WinDx.h" #include "../Renderer.h" namespace render::pass::world diff --git a/src/stdafx.h b/src/stdafx.h index afc2f80..eb04e75 100644 --- a/src/stdafx.h +++ b/src/stdafx.h @@ -7,12 +7,10 @@ #define _SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING -#include "targetver.h" - #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers #define NOMINMAX // Disable Windows min/max Macros overriding std::min/max -// Windows Header Files: -#include + +#include "targetver.h" // C RunTime Header Files #include @@ -27,12 +25,14 @@ #include #include #include +#include // commonly used libraries #include // TODO disable SSE, measure performance so we know if this is even worth it compared to normal optimization //#define _XM_NO_INTRINSICS_ + #include #include #include \ No newline at end of file diff --git a/src/viewer/GameLoop.h b/src/viewer/GameLoop.h index 2298aff..4490271 100644 --- a/src/viewer/GameLoop.h +++ b/src/viewer/GameLoop.h @@ -1,5 +1,6 @@ #pragma once #include "Args.h" +#include "Win.h" namespace viewer { diff --git a/src/viewer/InitApp.cpp b/src/viewer/InitApp.cpp index 51c2908..d50d179 100644 --- a/src/viewer/InitApp.cpp +++ b/src/viewer/InitApp.cpp @@ -13,6 +13,7 @@ #include "Input.h" #include "g3log/logworker.hpp" +#include "Win.h" #include #include #include diff --git a/src/viewer/Input.cpp b/src/viewer/Input.cpp index 800536a..4dd24df 100644 --- a/src/viewer/Input.cpp +++ b/src/viewer/Input.cpp @@ -1,4 +1,5 @@ #include "stdafx.h" + #include "Input.h" #include "Util.h" diff --git a/src/viewer/Input.h b/src/viewer/Input.h index 277de22..7ccaca6 100644 --- a/src/viewer/Input.h +++ b/src/viewer/Input.h @@ -1,5 +1,7 @@ #pragma once +#include "Win.h" + namespace viewer::input { #define MK_AXIS_X 0x8000