Adding simple test for RT

This commit is contained in:
IlyaShurupov 2023-10-18 19:05:51 +03:00
parent 2e0d0e0050
commit 7af12ee1a0
8 changed files with 402 additions and 217 deletions

View file

@ -6,109 +6,120 @@
namespace tp { namespace tp {
template< typename tType, ualni tSizeX, ualni tSizeY > template <typename tType, ualni tSizeX, ualni tSizeY>
using ConstSizeBuffer2D = ConstSizeBuffer<ConstSizeBuffer<tType, tSizeX>, tSizeY>; using ConstSizeBuffer2D = ConstSizeBuffer<ConstSizeBuffer<tType, tSizeX>, tSizeY>;
template < template <typename tType, class tAllocator = DefaultAllocator>
typename tType, class Buffer2D {
class tAllocator = DefaultAllocator public:
> typedef ualni Index;
class Buffer2D { typedef Pair<Index, Index> Index2D;
public: typedef SelectValueOrReference<tType> tTypeArg;
typedef ualni Index;
typedef Pair<Index, Index> Index2D;
typedef SelectValueOrReference<tType> tTypeArg;
private: private:
tAllocator mAlloc; tAllocator mAlloc;
tType* mBuff = nullptr; tType* mBuff = nullptr;
Index2D mSize = { 0, 0 }; Index2D mSize = {0, 0};
void deleteBuffer() { void deleteBuffer() {
if (!mBuff) return; if (!mBuff) {
for (ualni i = 0; i < mSize.x * mSize.y; i++) mBuff[i].~tType(); return;
mAlloc.deallocate(mBuff); }
} for (ualni i = 0; i < mSize.x * mSize.y; i++) {
mBuff[i].~tType();
}
mAlloc.deallocate(mBuff);
}
void allocateBuffer(Index2D size) { void allocateBuffer(Index2D size) {
deleteBuffer(); deleteBuffer();
mBuff = (tType*) mAlloc.allocate(sizeof(tType) * size.x * size.y); mBuff = (tType*) mAlloc.allocate(sizeof(tType) * size.x * size.y);
for (ualni i = 0; i < mSize.x * mSize.y; i++) new (mBuff + i) tType(); 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() { explicit Buffer2D(Index2D aSize) { reserve(aSize); }
deleteBuffer();
mSize = { 0, 0 };
}
explicit Buffer2D(Index2D aSize) { [[nodiscard]] Index2D size() const { return {mSize.x, mSize.y}; }
reserve(aSize);
}
[[nodiscard]] Index2D size() const { tType* getBuff() const { return mBuff; }
return { mSize.x, mSize.y };
}
tType* getBuff() const { inline tType& get(const Index2D& at) {
return mBuff; 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) { 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) 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); return *(mBuff + mSize.x * at.y + at.x);
} }
inline const tType& get(const Index2D& at) const { 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) 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); *(mBuff + mSize.x * at.y + at.x) = value;
} }
inline void set(const Index2D& at, tTypeArg value) { void reserve(const Index2D& newSize) {
DEBUG_ASSERT(mBuff && at.x < mSize.x && at.y < mSize.y && at.x >= 0 && at.y >= 0) if (mSize.x != newSize.x || mSize.y != newSize.y) {
*(mBuff + mSize.x * at.y + at.x) = value; allocateBuffer(newSize);
} mSize = newSize;
}
}
void reserve(const Index2D& newSize) { void assign(tType value) {
if (mSize.x != newSize.x || mSize.y != newSize.y) { DEBUG_ASSERT(mBuff);
allocateBuffer(newSize); Index len = mSize.x * mSize.y;
mSize = newSize; for (Index i = 0; i < len; i++) {
} mBuff[i] = value;
} }
}
void assign(tType value) { bool operator==(const Buffer2D& in) const {
DEBUG_ASSERT(mBuff); if (&in == this) {
Index len = mSize.x * mSize.y; return true;
for (Index i = 0; i < len; i++) { }
mBuff[i] = value; 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: public:
template<class tArchiver> template <class tArchiver>
void archiveWrite(tArchiver& ar) const { void archiveWrite(tArchiver& ar) const {
ar << mSize; ar << mSize;
for (auto i = 0; i < mSize.x; i++) { for (auto i = 0; i < mSize.x; i++) {
for (auto j = 0; j < mSize.y; j++) { for (auto j = 0; j < mSize.y; j++) {
ar << get(i, j); ar << get(i, j);
} }
} }
} }
template<class tArchiver> template <class tArchiver>
void archiveRead(tArchiver& ar) { void archiveRead(tArchiver& ar) {
decltype(mSize) size; decltype(mSize) size;
deleteBuffer(); deleteBuffer();
ar >> size; ar >> size;
reserve(size); reserve(size);
for (auto i = 0; i < mSize.x; i++) { for (auto i = 0; i < mSize.x; i++) {
for (auto j = 0; j < mSize.y; j++) { for (auto j = 0; j < mSize.y; j++) {
ar >> get(i, j); ar >> get(i, j);
} }
} }
} }
}; };
} }

View file

@ -4,81 +4,87 @@
namespace tp { namespace tp {
class RGB; class RGB;
class HSV; class HSV;
class RGB { class RGB {
public: public:
RGB(); RGB();
RGB(flt4 pr, flt4 pg, flt4 pb); RGB(flt4 pr, flt4 pg, flt4 pb);
RGB(flt4 val); RGB(flt4 val);
public: public:
void set(flt4 pr, flt4 pg, flt4 pb); void set(flt4 pr, flt4 pg, flt4 pb);
operator HSV() const; operator HSV() const;
public: public:
halnf r, g, b; halnf r, g, b;
}; };
class HSV { class HSV {
public: public:
HSV(); HSV();
HSV(flt4 ph, flt4 ps, flt4 pv); HSV(flt4 ph, flt4 ps, flt4 pv);
public: public:
void set(flt4 ph, flt4 ps, flt4 pv); void set(flt4 ph, flt4 ps, flt4 pv);
operator RGB() const; operator RGB() const;
public: public:
halnf h, s, v; halnf h, s, v;
}; };
class RGBA { class RGBA {
public: public:
RGBA() : r(0), g(0), b(0), a(0) {} 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) {}
public: RGBA(flt4 val) : rgbs(val), a(val) {}
RGBA& operator=(const HSV& in) {
rgbs = in;
a = 1;
return *this;
}
RGBA operator-(const RGBA& in) const { RGBA(const RGB& RGBs, flt4 val) : rgbs(RGBs), a(val) {}
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 operator+(const RGBA& in) const { RGBA(flt4 pr, flt4 pg, flt4 pb, flt4 pa) : rgbs(pr, pg, pb), a(pa) {}
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 };
}
public: public:
flt4 a; RGBA& operator=(const HSV& in) {
rgbs = in;
a = 1;
return *this;
}
union { RGBA operator-(const RGBA& in) const {
RGB rgbs; const auto nr = tp::clamp(r - in.r, 0.f, 1.f);
struct { const auto ng = tp::clamp(g - in.g, 0.f, 1.f);
flt4 r; const auto nb = tp::clamp(b - in.b, 0.f, 1.f);
flt4 g; const auto na = tp::clamp(a - in.a, 0.f, 1.f);
flt4 b; return {nr, ng, nb, na};
}; }
};
};
class HSVA { RGBA operator+(const RGBA& in) const {
HSV rgbs; const auto nr = tp::clamp(r + in.r, 0.f, 1.f);
flt4 a = 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;
};
} }

View file

@ -26,6 +26,9 @@ file(COPY "applications/rsc" DESTINATION "${CMAKE_BINARY_DIR}/${PROJECT_NAME}/")
enable_testing() enable_testing()
file(GLOB TEST_SOURCES "./tests/*.cpp" "./tests/*/*.cpp") file(GLOB TEST_SOURCES "./tests/*.cpp" "./tests/*/*.cpp")
add_executable(${PROJECT_NAME}Tests ${TEST_SOURCES}) add_executable(${PROJECT_NAME}Tests ${TEST_SOURCES})
target_include_directories(${PROJECT_NAME}Tests PUBLIC ./applications/)
target_link_libraries(${PROJECT_NAME}Tests ${PROJECT_NAME} Utils) target_link_libraries(${PROJECT_NAME}Tests ${PROJECT_NAME} Utils)
add_test(NAME ${PROJECT_NAME}Tests COMMAND ${PROJECT_NAME}Tests) add_test(NAME ${PROJECT_NAME}Tests COMMAND ${PROJECT_NAME}Tests)

View file

@ -24,6 +24,7 @@ bool loadMeshes(tp::Scene& scene, const tp::String& objetsPath) {
auto object = &scene.mObjects.last(); auto object = &scene.mObjects.last();
for (auto& vertex : curMesh.Vertices) { 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.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}); 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 idx1 = (int) curMesh.Indices[j];
int idx2 = (int) curMesh.Indices[j + 1]; int idx2 = (int) curMesh.Indices[j + 1];
int idx3 = (int) curMesh.Indices[j + 2]; int idx3 = (int) curMesh.Indices[j + 2];
// printf("{ %i, %i, %i },\n", idx1, idx2, idx3);
object->mTopology.Indexes.append(Vec3I {idx1, idx2, idx3}); object->mTopology.Indexes.append(Vec3I {idx1, idx2, idx3});
} }

View file

@ -2,14 +2,14 @@
Meshes = "meshes.obj" Meshes = "meshes.obj"
Camera = { Camera = {
pos = { 4, 4, 4 }, pos = { 3, 3, 3 },
size_x = 400, size_x = 10,
size_y = 600, size_y = 10,
} }
Lights = { Lights = {
{ {
pos = { 4, 3, 3 }, pos = { 4, 2, 3 },
intensity = 4 intensity = 5
} }
} }

View file

@ -171,6 +171,9 @@ void RayTracer::render(const Scene& scene, RayTracer::RenderBuffer& buff, const
buff.set({i, j}, 0.f); 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; mProgress.percentage = (halnf) currIter / (halnf) maxIterations;
currIter++; currIter++;
} }

View file

@ -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<urgb> 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();
}

View file

@ -3,80 +3,118 @@
#include "Module.hpp" #include "Module.hpp"
#define PTR_OFFSET(first, offset) (*((&first) + offset)) #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 { namespace tp {
extern ModuleManifest gModuleUtils; extern ModuleManifest gModuleUtils;
void memSetVal(void* p, uhalni byteSize, uint1 val); void memSetVal(void* p, uhalni byteSize, uint1 val);
void memCopy(void* left, const void* right, uhalni len); void memCopy(void* left, const void* right, uhalni len);
int1 memCompare(const 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); bool memEqual(const void* left, const void* right, uhalni len);
int1 memCompareVal(const void* left, uhalni len, uint1 val); int1 memCompareVal(const void* left, uhalni len, uint1 val);
} }
namespace tp { namespace tp {
[[nodiscard]] alnf randomFloat(); [[nodiscard]] alnf randomFloat();
} }
namespace tp { namespace tp {
template <typename T1, typename T2> template <typename T1, typename T2>
class Pair { class Pair {
public: public:
Pair() = default; 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 <typename Type = alni> template <typename U1, typename U2>
class Bits { Pair(U1 t1, U2 t2) : head(static_cast<T1>(t1)),
Type mFlags = 0; tail(static_cast<T2>(t2)) {}
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);
}
}
};
union {
T1 t1;
T1 head;
T1 x;
};
template<typename tType = ualni> union {
class Range { T2 t2;
public: T2 tail;
class Iterator { T2 y;
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; bool operator==(const Pair& in) const { return in.t1 == t1 && in.t2 == t2; }
tType mEnd = 0;
Range() = default; bool operator!=(const Pair& in) const { return !this->operator==(in); }
explicit Range(tType pEndIndex) : mBegin(0), mEnd(pEndIndex) {} };
Range(tType pStartIndex, tType pEndIndex) : mBegin(pStartIndex), mEnd(pEndIndex) {}
bool valid() { return mBegin < mEnd; } template <typename Type = alni>
class Bits {
Type mFlags = 0;
tType idxBegin() const { return mBegin; } public:
tType idxEnd() const { return mEnd; } Bits() = default;
tType idxDiff() const { return mEnd - mBegin; }
Iterator begin() { return Iterator(mBegin); } explicit Bits(Type val) { mFlags = val; }
Iterator end() { return Iterator(mEnd); }
}; 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 <typename tType = ualni>
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); }
};
}