From 7af12ee1a00279bf6b52292b7ec02cf1729ee161 Mon Sep 17 00:00:00 2001 From: IlyaShurupov Date: Wed, 18 Oct 2023 19:05:51 +0300 Subject: [PATCH] Adding simple test for RT --- Containers/public/Buffer2D.hpp | 187 +++++++++++---------- Math/public/Color.hpp | 134 ++++++++------- RayTracer/CMakeLists.txt | 3 + RayTracer/applications/SceneLoad.cpp | 2 + RayTracer/applications/rsc/cube/script.lua | 10 +- RayTracer/private/RayTracer.cpp | 3 + RayTracer/tests/Test.cpp | 124 +++++++++++++- Utils/public/Utils.hpp | 156 ++++++++++------- 8 files changed, 402 insertions(+), 217 deletions(-) diff --git a/Containers/public/Buffer2D.hpp b/Containers/public/Buffer2D.hpp index bbaa81c..a5c16ba 100644 --- a/Containers/public/Buffer2D.hpp +++ b/Containers/public/Buffer2D.hpp @@ -6,109 +6,120 @@ namespace tp { - template< typename tType, ualni tSizeX, ualni tSizeY > - using ConstSizeBuffer2D = ConstSizeBuffer, tSizeY>; + template + using ConstSizeBuffer2D = ConstSizeBuffer, tSizeY>; - template < - typename tType, - class tAllocator = DefaultAllocator - > - class Buffer2D { - public: - typedef ualni Index; - typedef Pair Index2D; - typedef SelectValueOrReference tTypeArg; + template + class Buffer2D { + public: + typedef ualni Index; + typedef Pair Index2D; + typedef SelectValueOrReference tTypeArg; - private: - tAllocator mAlloc; - tType* mBuff = nullptr; - Index2D mSize = { 0, 0 }; + private: + tAllocator mAlloc; + tType* mBuff = nullptr; + Index2D mSize = {0, 0}; - void deleteBuffer() { - if (!mBuff) return; - for (ualni i = 0; i < mSize.x * mSize.y; i++) mBuff[i].~tType(); - mAlloc.deallocate(mBuff); - } + void deleteBuffer() { + if (!mBuff) { + return; + } + for (ualni i = 0; i < mSize.x * mSize.y; i++) { + mBuff[i].~tType(); + } + mAlloc.deallocate(mBuff); + } - void allocateBuffer(Index2D size) { - deleteBuffer(); - mBuff = (tType*) mAlloc.allocate(sizeof(tType) * size.x * size.y); - for (ualni i = 0; i < mSize.x * mSize.y; i++) new (mBuff + i) tType(); - } + void allocateBuffer(Index2D size) { + deleteBuffer(); + mBuff = (tType*) mAlloc.allocate(sizeof(tType) * size.x * size.y); + for (ualni i = 0; i < mSize.x * mSize.y; i++) { + new (mBuff + i) tType(); + } + } - public: + public: + Buffer2D() = default; - Buffer2D() = default; + ~Buffer2D() { + deleteBuffer(); + mSize = {0, 0}; + } - ~Buffer2D() { - deleteBuffer(); - mSize = { 0, 0 }; - } + explicit Buffer2D(Index2D aSize) { reserve(aSize); } - explicit Buffer2D(Index2D aSize) { - reserve(aSize); - } + [[nodiscard]] Index2D size() const { return {mSize.x, mSize.y}; } - [[nodiscard]] Index2D size() const { - return { mSize.x, mSize.y }; - } + tType* getBuff() const { return mBuff; } - tType* getBuff() const { - return mBuff; - } + inline tType& get(const Index2D& at) { + DEBUG_ASSERT(mBuff && at.x < mSize.x && at.y < mSize.y && at.x >= 0 && at.y >= 0) + return *(mBuff + mSize.x * at.y + at.x); + } - inline tType& get(const Index2D& at) { - DEBUG_ASSERT(mBuff && at.x < mSize.x && at.y < mSize.y && at.x >= 0 && at.y >= 0) - return *(mBuff + mSize.x * at.y + at.x); - } + inline const tType& get(const Index2D& at) const { + DEBUG_ASSERT(mBuff && at.x < mSize.x && at.y < mSize.y && at.x >= 0 && at.y >= 0) + return *(mBuff + mSize.x * at.y + at.x); + } - inline const tType& get(const Index2D& at) const { - DEBUG_ASSERT(mBuff && at.x < mSize.x && at.y < mSize.y && at.x >= 0 && at.y >= 0) - return *(mBuff + mSize.x * at.y + at.x); - } + inline void set(const Index2D& at, tTypeArg value) { + DEBUG_ASSERT(mBuff && at.x < mSize.x && at.y < mSize.y && at.x >= 0 && at.y >= 0) + *(mBuff + mSize.x * at.y + at.x) = value; + } - inline void set(const Index2D& at, tTypeArg value) { - DEBUG_ASSERT(mBuff && at.x < mSize.x && at.y < mSize.y && at.x >= 0 && at.y >= 0) - *(mBuff + mSize.x * at.y + at.x) = value; - } + void reserve(const Index2D& newSize) { + if (mSize.x != newSize.x || mSize.y != newSize.y) { + allocateBuffer(newSize); + mSize = newSize; + } + } - void reserve(const Index2D& newSize) { - if (mSize.x != newSize.x || mSize.y != newSize.y) { - allocateBuffer(newSize); - mSize = newSize; - } - } + void assign(tType value) { + DEBUG_ASSERT(mBuff); + Index len = mSize.x * mSize.y; + for (Index i = 0; i < len; i++) { + mBuff[i] = value; + } + } - void assign(tType value) { - DEBUG_ASSERT(mBuff); - Index len = mSize.x * mSize.y; - for (Index i = 0; i < len; i++) { - mBuff[i] = value; - } - } + bool operator==(const Buffer2D& in) const { + if (&in == this) { + return true; + } + if (in.size() != size()) { + return false; + } + for (auto i = 0; i < mSize.x * mSize.y; i++) { + if (mBuff[i] != in.mBuff[i]) { + return false; + } + } + return true; + } - public: - template - void archiveWrite(tArchiver& ar) const { - ar << mSize; - for (auto i = 0; i < mSize.x; i++) { - for (auto j = 0; j < mSize.y; j++) { - ar << get(i, j); - } - } - } + public: + template + void archiveWrite(tArchiver& ar) const { + ar << mSize; + for (auto i = 0; i < mSize.x; i++) { + for (auto j = 0; j < mSize.y; j++) { + ar << get(i, j); + } + } + } - template - void archiveRead(tArchiver& ar) { - decltype(mSize) size; - deleteBuffer(); - ar >> size; - reserve(size); - for (auto i = 0; i < mSize.x; i++) { - for (auto j = 0; j < mSize.y; j++) { - ar >> get(i, j); - } - } - } - }; + template + void archiveRead(tArchiver& ar) { + decltype(mSize) size; + deleteBuffer(); + ar >> size; + reserve(size); + for (auto i = 0; i < mSize.x; i++) { + for (auto j = 0; j < mSize.y; j++) { + ar >> get(i, j); + } + } + } + }; } diff --git a/Math/public/Color.hpp b/Math/public/Color.hpp index 3387fb7..505bff9 100644 --- a/Math/public/Color.hpp +++ b/Math/public/Color.hpp @@ -4,81 +4,87 @@ namespace tp { - class RGB; - class HSV; + class RGB; + class HSV; - class RGB { - public: - RGB(); - RGB(flt4 pr, flt4 pg, flt4 pb); - RGB(flt4 val); + class RGB { + public: + RGB(); + RGB(flt4 pr, flt4 pg, flt4 pb); + RGB(flt4 val); - public: - void set(flt4 pr, flt4 pg, flt4 pb); - operator HSV() const; + public: + void set(flt4 pr, flt4 pg, flt4 pb); + operator HSV() const; - public: - halnf r, g, b; - }; + public: + halnf r, g, b; + }; - class HSV { - public: - HSV(); - HSV(flt4 ph, flt4 ps, flt4 pv); + class HSV { + public: + HSV(); + HSV(flt4 ph, flt4 ps, flt4 pv); - public: - void set(flt4 ph, flt4 ps, flt4 pv); - operator RGB() const; + public: + void set(flt4 ph, flt4 ps, flt4 pv); + operator RGB() const; - public: - halnf h, s, v; - }; + public: + halnf h, s, v; + }; - class RGBA { - public: - RGBA() : r(0), g(0), b(0), a(0) {} - RGBA(flt4 val) : rgbs(val), a(val) {} - RGBA(const RGB& RGBs, flt4 val) : rgbs(RGBs), a(val) {} - RGBA(flt4 pr, flt4 pg, flt4 pb, flt4 pa) : rgbs(pr, pg, pb), a(pa) {} + class RGBA { + public: + RGBA() : r(0), g(0), b(0), a(0) {} - public: - RGBA& operator=(const HSV& in) { - rgbs = in; - a = 1; - return *this; - } + RGBA(flt4 val) : rgbs(val), a(val) {} - RGBA operator-(const RGBA& in) const { - auto const nr = tp::clamp(r - in.r, 0.f, 1.f); - auto const ng = tp::clamp(g - in.g, 0.f, 1.f); - auto const nb = tp::clamp(b - in.b, 0.f, 1.f); - auto const na = tp::clamp(a - in.a, 0.f, 1.f); - return { nr, ng, nb, na }; - } + RGBA(const RGB& RGBs, flt4 val) : rgbs(RGBs), a(val) {} - RGBA operator+(const RGBA& in) const { - auto const nr = tp::clamp(r + in.r, 0.f, 1.f); - auto const ng = tp::clamp(g + in.g, 0.f, 1.f); - auto const nb = tp::clamp(b + in.b, 0.f, 1.f); - auto const na = tp::clamp(a + in.a, 0.f, 1.f); - return { nr, ng, nb, na }; - } + RGBA(flt4 pr, flt4 pg, flt4 pb, flt4 pa) : rgbs(pr, pg, pb), a(pa) {} - public: - flt4 a; + public: + RGBA& operator=(const HSV& in) { + rgbs = in; + a = 1; + return *this; + } - union { - RGB rgbs; - struct { - flt4 r; - flt4 g; - flt4 b; - }; - }; - }; + RGBA operator-(const RGBA& in) const { + const auto nr = tp::clamp(r - in.r, 0.f, 1.f); + const auto ng = tp::clamp(g - in.g, 0.f, 1.f); + const auto nb = tp::clamp(b - in.b, 0.f, 1.f); + const auto na = tp::clamp(a - in.a, 0.f, 1.f); + return {nr, ng, nb, na}; + } - class HSVA { - HSV rgbs; - flt4 a = 1.f; - }; + RGBA operator+(const RGBA& in) const { + const auto nr = tp::clamp(r + in.r, 0.f, 1.f); + const auto ng = tp::clamp(g + in.g, 0.f, 1.f); + const auto nb = tp::clamp(b + in.b, 0.f, 1.f); + const auto na = tp::clamp(a + in.a, 0.f, 1.f); + return {nr, ng, nb, na}; + } + + bool operator==(const RGBA& in) const { return r == in.r && g == in.g && b == in.b && a == in.a; } + + public: + flt4 a; + + union { + RGB rgbs; + + struct { + flt4 r; + flt4 g; + flt4 b; + }; + }; + }; + + class HSVA { + HSV rgbs; + flt4 a = 1.f; + }; } diff --git a/RayTracer/CMakeLists.txt b/RayTracer/CMakeLists.txt index 1357e6c..e5a299b 100644 --- a/RayTracer/CMakeLists.txt +++ b/RayTracer/CMakeLists.txt @@ -26,6 +26,9 @@ file(COPY "applications/rsc" DESTINATION "${CMAKE_BINARY_DIR}/${PROJECT_NAME}/") enable_testing() file(GLOB TEST_SOURCES "./tests/*.cpp" "./tests/*/*.cpp") add_executable(${PROJECT_NAME}Tests ${TEST_SOURCES}) + +target_include_directories(${PROJECT_NAME}Tests PUBLIC ./applications/) + target_link_libraries(${PROJECT_NAME}Tests ${PROJECT_NAME} Utils) add_test(NAME ${PROJECT_NAME}Tests COMMAND ${PROJECT_NAME}Tests) diff --git a/RayTracer/applications/SceneLoad.cpp b/RayTracer/applications/SceneLoad.cpp index 36e062c..f7996b1 100644 --- a/RayTracer/applications/SceneLoad.cpp +++ b/RayTracer/applications/SceneLoad.cpp @@ -24,6 +24,7 @@ bool loadMeshes(tp::Scene& scene, const tp::String& objetsPath) { auto object = &scene.mObjects.last(); for (auto& vertex : curMesh.Vertices) { + // printf("{ %f, %f, %f }, \n", vertex.Position.X, vertex.Position.Y, vertex.Position.Z); object->mTopology.Points.append(Vec3F {vertex.Position.X, vertex.Position.Y, vertex.Position.Z}); object->mTopology.Normals.append(Vec3F {vertex.Normal.X, vertex.Normal.Y, vertex.Normal.Z}); } @@ -32,6 +33,7 @@ bool loadMeshes(tp::Scene& scene, const tp::String& objetsPath) { int idx1 = (int) curMesh.Indices[j]; int idx2 = (int) curMesh.Indices[j + 1]; int idx3 = (int) curMesh.Indices[j + 2]; + // printf("{ %i, %i, %i },\n", idx1, idx2, idx3); object->mTopology.Indexes.append(Vec3I {idx1, idx2, idx3}); } diff --git a/RayTracer/applications/rsc/cube/script.lua b/RayTracer/applications/rsc/cube/script.lua index d4f220a..887b884 100644 --- a/RayTracer/applications/rsc/cube/script.lua +++ b/RayTracer/applications/rsc/cube/script.lua @@ -2,14 +2,14 @@ Meshes = "meshes.obj" Camera = { - pos = { 4, 4, 4 }, - size_x = 400, - size_y = 600, + pos = { 3, 3, 3 }, + size_x = 10, + size_y = 10, } Lights = { { - pos = { 4, 3, 3 }, - intensity = 4 + pos = { 4, 2, 3 }, + intensity = 5 } } \ No newline at end of file diff --git a/RayTracer/private/RayTracer.cpp b/RayTracer/private/RayTracer.cpp index ff69a4b..f97f069 100644 --- a/RayTracer/private/RayTracer.cpp +++ b/RayTracer/private/RayTracer.cpp @@ -171,6 +171,9 @@ void RayTracer::render(const Scene& scene, RayTracer::RenderBuffer& buff, const buff.set({i, j}, 0.f); } + auto tmp = buff.get({i, j}); + // printf(" %f, %f, %f, %f, ", tmp.r, tmp.g, tmp.b, tmp.a); + mProgress.percentage = (halnf) currIter / (halnf) maxIterations; currIter++; } diff --git a/RayTracer/tests/Test.cpp b/RayTracer/tests/Test.cpp index 72549a7..c5fb950 100644 --- a/RayTracer/tests/Test.cpp +++ b/RayTracer/tests/Test.cpp @@ -1,3 +1,125 @@ -int main(int argc, char* argv[]) { return 1; } +// #include "NewPlacement.hpp" +#include "RayTracer.hpp" +#include "Testing.hpp" + +#define STB_IMAGE_WRITE_IMPLEMENTATION +#include "stb_image_write.h" + +using namespace tp; + +void writeImage(const RayTracer::RenderBuffer& output) { + // Save the data to a PNG file + struct urgb { + uint1 r, g, b, a; + }; + + Buffer2D converted; + converted.reserve(output.size()); + + for (RayTracer::RenderBuffer::Index i = 0; i < output.size().x; i++) { + for (RayTracer::RenderBuffer::Index j = 0; j < output.size().y; j++) { + converted.get({i, j}).r = uint1(output.get({i, j}).r * 255); + converted.get({i, j}).g = uint1(output.get({i, j}).g * 255); + converted.get({i, j}).b = uint1(output.get({i, j}).b * 255); + converted.get({i, j}).a = uint1(output.get({i, j}).a * 255); + } + } + + stbi_write_png("output.png", converted.size().x, converted.size().y, 4, converted.getBuff(), converted.size().x * 4); +} + +bool compareCols(const RGBA& l, const RGBA& r) { + auto small = 0.0001f; + if ((l.r - r.r) > small) { + return false; + } + if ((l.g - r.g) > small) { + return false; + } + if ((l.b - r.b) > small) { + return false; + } + if ((l.a - r.a) > small) { + return false; + } + return true; +} + +void testRT() { + using namespace tp; + + Scene scene; + + scene.mCamera.lookAtPoint({0, 0, 0}, {2, 2, 2}, {0, 0, 1}); + scene.mCamera.setFOV(3.14 / 4); + + scene.mLights.append({ + {0, 0, 1.1f}, + 1.f, 0.3f + }); + + scene.mObjects.append(Object()); + auto& object = scene.mObjects.last(); + + object.mTopology.Points = { + {1.000000, 0.000000, 0.000000}, + {0.000000, 1.000000, 0.000000}, + {0.000000, 0.000000, 1.000000}, + }; + + object.mTopology.Normals = { + {1.000000, 1.000000, 1.000000}, + {1.000000, 1.000000, 1.000000}, + {1.000000, 1.000000, 1.000000}, + }; + + object.mTopology.Indexes = { + {0, 1, 2}, + }; + + object.mCache.Source = &object.mTopology; + object.mCache.updateCache(); + + RayTracer::RenderSettings settings = { + 0, + 0, + {10, 10}, + }; + + RayTracer::RenderBuffer output; + output.reserve(RayTracer::RenderBuffer::Index2D(settings.size.x, settings.size.y)); + + RayTracer rt; + rt.render(scene, output, settings); + + TEST(compareCols(output.get({6, 4}), RGBA {0.560100f, 0.560100f, 0.560100f, 1.000000f})); + TEST(compareCols(output.get({6, 5}), RGBA {0.353739f, 0.353739f, 0.353739f, 1.000000f})); + TEST(compareCols(output.get({6, 6}), RGBA {0.242577f, 0.242577f, 0.242577f, 1.000000f})); + TEST(compareCols(output.get({6, 7}), RGBA {0.176313f, 0.176313f, 0.176313f, 1.000000f})); + TEST(compareCols(output.get({6, 8}), RGBA {0.000000f, 0.000000f, 0.000000f, 0.000000f})); + + if (0) { + writeImage(output); + for (auto i = 0; i < output.size().x; i++) { + for (auto j = 0; j < output.size().y; j++) { + auto tmp = output.get({i, j}); + printf("TEST(compareCols(output.get({%i, %i}), RGBA{ %ff, %ff, %ff, %ff }));\n", i, j, tmp.r, tmp.g, tmp.b, tmp.a); + } + } + } +} + +int main(int argc, char* argv[]) { + tp::ModuleManifest* ModuleDependencies[] = {&tp::gModuleRayTracer, nullptr}; + tp::ModuleManifest TestModule("TokenizerTest", nullptr, nullptr, ModuleDependencies); + + if (!TestModule.initialize()) { + return 1; + } + + testRT(); + + TestModule.deinitialize(); +} diff --git a/Utils/public/Utils.hpp b/Utils/public/Utils.hpp index 0cef950..de49a7b 100644 --- a/Utils/public/Utils.hpp +++ b/Utils/public/Utils.hpp @@ -3,80 +3,118 @@ #include "Module.hpp" #define PTR_OFFSET(first, offset) (*((&first) + offset)) -#define MEMBER_OFFSET(s, m) (alni(&(((s*)0)->m))) +#define MEMBER_OFFSET(s, m) (alni(&(((s*) 0)->m))) namespace tp { - extern ModuleManifest gModuleUtils; + extern ModuleManifest gModuleUtils; - void memSetVal(void* p, uhalni byteSize, uint1 val); - void memCopy(void* left, const void* right, uhalni len); - int1 memCompare(const void* left, const void* right, uhalni len); - bool memEqual(const void* left, const void* right, uhalni len); - int1 memCompareVal(const void* left, uhalni len, uint1 val); + void memSetVal(void* p, uhalni byteSize, uint1 val); + void memCopy(void* left, const void* right, uhalni len); + int1 memCompare(const void* left, const void* right, uhalni len); + bool memEqual(const void* left, const void* right, uhalni len); + int1 memCompareVal(const void* left, uhalni len, uint1 val); } namespace tp { - [[nodiscard]] alnf randomFloat(); + [[nodiscard]] alnf randomFloat(); } namespace tp { - template - class Pair { - public: - Pair() = default; - Pair(T1 t1, T2 t2) : head(t1), tail(t2) {} - union { T1 t1; T1 head; T1 x; }; - union { T2 t2; T2 tail; T2 y; }; - }; + template + class Pair { + public: + Pair() = default; - template - class Bits { - Type mFlags = 0; - public: - Bits() = default; - explicit Bits(Type val) { mFlags = val; } - explicit Bits(bool val) { for (int bit = 0; bit < sizeof(Type); bit++) { set(bit, val); } } - bool get(int1 idx) { return mFlags & (1l << idx); } - void set(int1 idx, bool val) { - if (val) { - mFlags |= (1l << idx); - } else { - mFlags &= ~(1l << idx); - } - } - }; + template + Pair(U1 t1, U2 t2) : head(static_cast(t1)), + tail(static_cast(t2)) {} + union { + T1 t1; + T1 head; + T1 x; + }; - template - class Range { - public: - class Iterator { - public: - tType mIndex; - explicit Iterator(tType pStartIndex) : mIndex(pStartIndex) {} - tType index() const { return mIndex; } - inline void operator++() { mIndex++; } - inline operator tType() const { return mIndex; } - inline bool operator==(Iterator pIndex) { return mIndex == pIndex.mIndex; } - inline bool operator!=(Iterator pIndex) { return mIndex != pIndex.mIndex; } - inline const Iterator& operator*() { return *this; } - }; + union { + T2 t2; + T2 tail; + T2 y; + }; - tType mBegin = 0; - tType mEnd = 0; + bool operator==(const Pair& in) const { return in.t1 == t1 && in.t2 == t2; } - Range() = default; - explicit Range(tType pEndIndex) : mBegin(0), mEnd(pEndIndex) {} - Range(tType pStartIndex, tType pEndIndex) : mBegin(pStartIndex), mEnd(pEndIndex) {} + bool operator!=(const Pair& in) const { return !this->operator==(in); } + }; - bool valid() { return mBegin < mEnd; } + template + class Bits { + Type mFlags = 0; - tType idxBegin() const { return mBegin; } - tType idxEnd() const { return mEnd; } - tType idxDiff() const { return mEnd - mBegin; } - Iterator begin() { return Iterator(mBegin); } - Iterator end() { return Iterator(mEnd); } - }; -} \ No newline at end of file + public: + Bits() = default; + + explicit Bits(Type val) { mFlags = val; } + + explicit Bits(bool val) { + for (int bit = 0; bit < sizeof(Type); bit++) { + set(bit, val); + } + } + + bool get(int1 idx) { return mFlags & (1l << idx); } + + void set(int1 idx, bool val) { + if (val) { + mFlags |= (1l << idx); + } else { + mFlags &= ~(1l << idx); + } + } + }; + + template + class Range { + public: + class Iterator { + public: + tType mIndex; + + explicit Iterator(tType pStartIndex) : mIndex(pStartIndex) {} + + tType index() const { return mIndex; } + + inline void operator++() { mIndex++; } + + inline operator tType() const { return mIndex; } + + inline bool operator==(Iterator pIndex) { return mIndex == pIndex.mIndex; } + + inline bool operator!=(Iterator pIndex) { return mIndex != pIndex.mIndex; } + + inline const Iterator& operator*() { return *this; } + }; + + tType mBegin = 0; + tType mEnd = 0; + + Range() = default; + + explicit Range(tType pEndIndex) : mBegin(0), mEnd(pEndIndex) {} + + Range(tType pStartIndex, tType pEndIndex) : mBegin(pStartIndex), mEnd(pEndIndex) {} + + bool valid() { return mBegin < mEnd; } + + tType idxBegin() const { return mBegin; } + + tType idxEnd() const { return mEnd; } + + tType idxDiff() const { return mEnd - mBegin; } + + Iterator begin() { return Iterator(mBegin); } + + Iterator end() { return Iterator(mEnd); } + }; +}