Final Version

main
Brett 2022-12-13 17:36:01 -05:00
parent 213ad18210
commit c91c62faad
76 changed files with 730 additions and 13225 deletions

Binary file not shown.

View File

@ -28,3 +28,38 @@
2810 5053 1670877426654992640 CMakeFiles/Step_3.dir/src/opencl/cl.cpp.o a2b56fe5c1c9fba8
2 2015 1670877423614914525 CMakeFiles/Step_3.dir/src/engine/util/parser.cpp.o 98940b44ed977a44
2 2331 1670877423930922646 CMakeFiles/Step_3.dir/src/engine/util/loaders.cpp.o 7aeb3d1871cf6703
1 1407 1670960345747290482 CMakeFiles/Step_3.dir/src/engine/mpi.cpp.o 5d24537a85ed8416
1 1711 1670960346051298638 CMakeFiles/Step_3.dir/src/engine/math/colliders.cpp.o e1cb3573834144bf
2 1917 1670960346259304217 CMakeFiles/Step_3.dir/src/engine/util/parser.cpp.o 98940b44ed977a44
2 2258 1670960346599313338 CMakeFiles/Step_3.dir/src/engine/util/loaders.cpp.o 7aeb3d1871cf6703
4 2288 1670960350651422031 CMakeFiles/Step_3.dir/src/graphics/gl/shader.cpp.o 2a1ad2717bf993ad
2 2392 1670960350755424821 CMakeFiles/Step_3.dir/src/engine/globals.cpp.o ef21dad2d7d55f95
3 2515 1670960350879428148 CMakeFiles/Step_3.dir/src/graphics/gl/gl.cpp.o 60ee6de1376d9db2
3 2550 1670960350915429113 CMakeFiles/Step_3.dir/src/engine/util/debug.cpp.o 6a4e11c94bba7102
3 2848 1670960351207436946 CMakeFiles/Step_3.dir/src/graphics/debug_gui.cpp.o db185e4c05df35c6
2288 2852 1670960351219437269 CMakeFiles/Step_3.dir/src/graphics/imgui/imgui_impl_x11.cpp.o affde06b41e3251b
3 2878 1670960351239437805 CMakeFiles/Step_3.dir/src/engine/util/models.cpp.o a3c3944da9146668
3 3106 1670960351467443920 CMakeFiles/Step_3.dir/src/engine/math/bvh.cpp.o bfaa9112c6c83140
4 3169 1670960351531445638 CMakeFiles/Step_3.dir/src/graphics/graphics.cpp.o 3e9ee255e3b079b6
3 3304 1670960351667449284 CMakeFiles/Step_3.dir/src/engine/world.cpp.o c64baeb5ba601bb4
3 3399 1670960351763451861 CMakeFiles/Step_3.dir/src/engine/raytracing.cpp.o f1ea987e58fdb6e
2392 3574 1670960351939456581 CMakeFiles/Step_3.dir/src/graphics/input.cpp.o 78c22cd6c124c15f
2 3831 1670960352195463448 CMakeFiles/Step_3.dir/src/engine/main.cpp.o 9aae8e577719f01
2 3876 1670960352239464628 CMakeFiles/Step_3.dir/src/engine/image/image.cpp.o 27aa2206b4129a91
2515 4586 1670960352951483727 CMakeFiles/Step_3.dir/src/opencl/cl.cpp.o a2b56fe5c1c9fba8
2550 4727 1670960353091487481 CMakeFiles/Step_3.dir/src/opencl/open_ray_tracing.cpp.o 1e13ffe3688667ce
4727 5011 1670960353375495099 Step_3 cf178136bfdaf811
1 1721 1670960421349317469 CMakeFiles/Step_3.dir/src/graphics/debug_gui.cpp.o db185e4c05df35c6
1721 1963 1670960421589323900 Step_3 cf178136bfdaf811
2 1727 1670960455302227154 CMakeFiles/Step_3.dir/src/graphics/debug_gui.cpp.o db185e4c05df35c6
1727 1984 1670960455558234011 Step_3 cf178136bfdaf811
2 2064 1670970951528565494 CMakeFiles/Step_3.dir/src/graphics/debug_gui.cpp.o db185e4c05df35c6
1 2092 1670970951556566258 CMakeFiles/Step_3.dir/src/engine/globals.cpp.o ef21dad2d7d55f95
2 2286 1670970951748571480 CMakeFiles/Step_3.dir/src/engine/world.cpp.o c64baeb5ba601bb4
2 2340 1670970951804573004 CMakeFiles/Step_3.dir/src/opencl/open_ray_tracing.cpp.o 1e13ffe3688667ce
2 2351 1670970951816573331 CMakeFiles/Step_3.dir/src/engine/util/debug.cpp.o 6a4e11c94bba7102
2 2450 1670970951916576052 CMakeFiles/Step_3.dir/src/graphics/graphics.cpp.o 3e9ee255e3b079b6
1 2594 1670970952056579862 CMakeFiles/Step_3.dir/src/engine/math/bvh.cpp.o bfaa9112c6c83140
1 3033 1670970952496591836 CMakeFiles/Step_3.dir/src/engine/main.cpp.o 9aae8e577719f01
1 3072 1670970952536592922 CMakeFiles/Step_3.dir/src/engine/raytracing.cpp.o f1ea987e58fdb6e
3072 3394 1670970952856601632 Step_3 cf178136bfdaf811

Binary file not shown.

View File

@ -1,3 +1,3 @@
Start testing: Dec 12 17:44 EST
Start testing: Dec 13 17:35 EST
----------------------------------------------------------
End testing: Dec 12 17:44 EST
End testing: Dec 13 17:35 EST

View File

@ -1,22 +1,31 @@
# ninja log v5
2 2190 1670912286882657204 CMakeFiles/Step_3.dir/src/engine/mpi.cpp.o 6e3ab647b4170cd7
2 2095 1670912286786654661 CMakeFiles/Step_3.dir/src/engine/world.cpp.o c4fd93f3ffca4556
1 1753 1670950149095202989 CMakeFiles/Step_3.dir/src/engine/mpi.cpp.o 6e3ab647b4170cd7
1 1602 1670950119422464294 CMakeFiles/Step_3.dir/src/engine/world.cpp.o c4fd93f3ffca4556
2 1592 1670912286282641308 CMakeFiles/Step_3.dir/src/engine/util/debug.cpp.o d5362da8222b5a91
1 8038 1670912292726812046 CMakeFiles/Step_3.dir/src/engine/image/image.cpp.o 16af2923d66aa3dc
1 1265 1670912285954632616 CMakeFiles/Step_3.dir/src/engine/globals.cpp.o d84683b57cabd9e2
1 1310 1670912285998633783 CMakeFiles/Step_3.dir/src/engine/math/colliders.cpp.o 69b8991a5a16265f
2 1754 1670912286446645652 CMakeFiles/Step_3.dir/src/engine/util/models.cpp.o f5a3601ffc57f560
8038 8105 1670912292794813848 Step_3 b99522ee7272b43c
2 2646 1670912287334669180 CMakeFiles/Step_3.dir/src/engine/raytracing.cpp.o 7cb473c21d72e8b4
3147 3231 1670950150571239776 Step_3 b99522ee7272b43c
1 2321 1670950149659217046 CMakeFiles/Step_3.dir/src/engine/raytracing.cpp.o 7cb473c21d72e8b4
1 2407 1670912287098662928 CMakeFiles/Step_3.dir/src/engine/math/bvh.cpp.o 1c9c19bd37115c1f
1 3623 1670912288314695146 CMakeFiles/Step_3.dir/src/engine/main.cpp.o fc9aafb6de653876
1 3146 1670950150487237682 CMakeFiles/Step_3.dir/src/engine/main.cpp.o fc9aafb6de653876
2 2015 1670912286706652541 CMakeFiles/Step_3.dir/src/engine/util/parser.cpp.o 5e496bc6e41e11aa
2 2180 1670912286870656887 CMakeFiles/Step_3.dir/src/engine/util/loaders.cpp.o 8bd5e7f27c69483d
1 1563 1670912412297758676 CMakeFiles/Step_3.dir/src/engine/mpi.cpp.o 6e3ab647b4170cd7
1 2057 1670912412789770209 CMakeFiles/Step_3.dir/src/engine/raytracing.cpp.o 7cb473c21d72e8b4
1 2823 1670912413553788123 CMakeFiles/Step_3.dir/src/engine/main.cpp.o fc9aafb6de653876
2823 2892 1670912413621789718 Step_3 b99522ee7272b43c
1 1595 1670912466371033890 CMakeFiles/Step_3.dir/src/engine/mpi.cpp.o 6e3ab647b4170cd7
1 2115 1670912466895046320 CMakeFiles/Step_3.dir/src/engine/raytracing.cpp.o 7cb473c21d72e8b4
1 2870 1670912467647064160 CMakeFiles/Step_3.dir/src/engine/main.cpp.o fc9aafb6de653876
2870 2924 1670912467703065488 Step_3 b99522ee7272b43c
1 1607 1670959878054685975 CMakeFiles/Step_3.dir/src/engine/util/models.cpp.o f5a3601ffc57f560
1 1695 1670959878142688360 CMakeFiles/Step_3.dir/src/engine/mpi.cpp.o 6e3ab647b4170cd7
1 1727 1670959878174689228 CMakeFiles/Step_3.dir/src/engine/world.cpp.o c4fd93f3ffca4556
1 1761 1670959878206690096 CMakeFiles/Step_3.dir/src/engine/util/loaders.cpp.o 8bd5e7f27c69483d
1 2284 1670959878730704308 CMakeFiles/Step_3.dir/src/engine/raytracing.cpp.o 7cb473c21d72e8b4
1 2331 1670959878778705608 CMakeFiles/Step_3.dir/src/engine/math/bvh.cpp.o 1c9c19bd37115c1f
1 3276 1670959879722731209 CMakeFiles/Step_3.dir/src/engine/main.cpp.o fc9aafb6de653876
0 7926 1670959884374857358 CMakeFiles/Step_3.dir/src/engine/image/image.cpp.o 16af2923d66aa3dc
7926 7993 1670959884438859092 Step_3 b99522ee7272b43c
1 2076 1670960039171044175 CMakeFiles/Step_3.dir/src/engine/raytracing.cpp.o 7cb473c21d72e8b4
2076 2139 1670960039235045902 Step_3 b99522ee7272b43c
1 1585 1670970906903350397 CMakeFiles/Step_3.dir/src/engine/mpi.cpp.o 6e3ab647b4170cd7
1 1739 1670970907059354649 CMakeFiles/Step_3.dir/src/engine/math/bvh.cpp.o 1c9c19bd37115c1f
2 2273 1670970907591369144 CMakeFiles/Step_3.dir/src/engine/raytracing.cpp.o 7cb473c21d72e8b4
1 3026 1670970908347389745 CMakeFiles/Step_3.dir/src/engine/main.cpp.o fc9aafb6de653876
1 1404 1670970928791946611 CMakeFiles/Step_3.dir/src/engine/world.cpp.o c4fd93f3ffca4556
1404 1483 1670970928867948677 Step_3 b99522ee7272b43c

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

View File

@ -1,3 +1,3 @@
Start testing: Dec 13 01:21 EST
Start testing: Dec 13 17:35 EST
----------------------------------------------------------
End testing: Dec 13 01:21 EST
End testing: Dec 13 17:35 EST

View File

@ -2,27 +2,43 @@
2919 4318 1670876125585573954 CMakeFiles/Step_3.dir/src/graphics/imgui/imgui_tables.cpp.o 271e64dad1661800
1602 2411 1670876123653524365 CMakeFiles/Step_3.dir/src/graphics/gl/gl.c.o 46d0a39d744d39fa
2411 3737 1670876125005559067 CMakeFiles/Step_3.dir/src/graphics/imgui/imgui_demo.cpp.o b196cf080fdfa359
4 1515 1670876122781501987 CMakeFiles/Step_3.dir/src/engine/mpi.cpp.o 178ad7d143bf4643
44 2919 1670876124185538021 CMakeFiles/Step_3.dir/src/engine/world.cpp.o 29ff1a38503c06b0
5 2411 1670876123673524879 CMakeFiles/Step_3.dir/src/engine/util/debug.cpp.o c94ada31065dd0f4
2 2742 1670876124009533505 CMakeFiles/Step_3.dir/src/engine/image/image.cpp.o d267b51f3c38b1c8
1515 3632 1670876124897556296 CMakeFiles/Step_3.dir/src/graphics/debug_gui.cpp.o 645211f1ad0dfed4
2 1623 1670950157527413190 CMakeFiles/Step_3.dir/src/engine/mpi.cpp.o 178ad7d143bf4643
3 2805 1670950158647441121 CMakeFiles/Step_3.dir/src/engine/world.cpp.o 29ff1a38503c06b0
3 2424 1670950158327433142 CMakeFiles/Step_3.dir/src/engine/util/debug.cpp.o c94ada31065dd0f4
2 3224 1670950159087452093 CMakeFiles/Step_3.dir/src/engine/image/image.cpp.o d267b51f3c38b1c8
1613 3806 1670950159711467656 CMakeFiles/Step_3.dir/src/graphics/debug_gui.cpp.o 645211f1ad0dfed4
2682 3288 1670876124557547570 CMakeFiles/Step_3.dir/src/graphics/imgui/imgui_impl_x11.cpp.o f90197c7146e69c3
2 2225 1670876123493520259 CMakeFiles/Step_3.dir/src/engine/globals.cpp.o 1fb6828ece7be9ea
3 1602 1670876122869504246 CMakeFiles/Step_3.dir/src/engine/math/colliders.cpp.o 37dd8fbf58fdf4fd
21 2136 1670876123397517797 CMakeFiles/Step_3.dir/src/engine/util/models.cpp.o 3cb2f1649f5ebcd1
2 2038 1670950157943423564 CMakeFiles/Step_3.dir/src/engine/globals.cpp.o 1fb6828ece7be9ea
2 1613 1670950157511412791 CMakeFiles/Step_3.dir/src/engine/math/colliders.cpp.o 37dd8fbf58fdf4fd
3 2439 1670950158343433540 CMakeFiles/Step_3.dir/src/engine/util/models.cpp.o 3cb2f1649f5ebcd1
2301 4670 1670876125937582989 CMakeFiles/Step_3.dir/src/graphics/imgui/imgui.cpp.o 600c76317c1bef84
4860 4991 1670876126257591201 Step_3 6bc0df4fa69a503b
1521 1659 1670950169111702166 Step_3 6bc0df4fa69a503b
2468 2682 1670876123949531963 CMakeFiles/Step_3.dir/src/graphics/imgui/imgui_impl_glfw.cpp.o 2dac773db2e2a2df
4 2942 1670876124205538535 CMakeFiles/Step_3.dir/src/engine/raytracing.cpp.o 78a5cc225017e748
3001 4211 1670876125477571180 CMakeFiles/Step_3.dir/src/graphics/input.cpp.o 2b898ab4a04b8bdb
2 1520 1670950168971698675 CMakeFiles/Step_3.dir/src/engine/raytracing.cpp.o 78a5cc225017e748
2346 3695 1670950159599464863 CMakeFiles/Step_3.dir/src/graphics/input.cpp.o 2b898ab4a04b8bdb
2411 4203 1670876125469570977 CMakeFiles/Step_3.dir/src/graphics/imgui/imgui_draw.cpp.o b0031a10ecd07f54
2225 4231 1670876125497571694 CMakeFiles/Step_3.dir/src/graphics/graphics.cpp.o 6b1a12e1042d4a97
2166 4104 1670950160007475038 CMakeFiles/Step_3.dir/src/graphics/graphics.cpp.o 6b1a12e1042d4a97
2942 4860 1670876126129587917 CMakeFiles/Step_3.dir/src/graphics/imgui/imgui_widgets.cpp.o ddde7e88dcff6d6e
2136 3754 1670876125021559476 CMakeFiles/Step_3.dir/src/graphics/gl/gl.cpp.o 6fdeee2b4621ca7d
1624 3590 1670950159495462268 CMakeFiles/Step_3.dir/src/graphics/gl/gl.cpp.o 6fdeee2b4621ca7d
2743 3001 1670876124269540176 CMakeFiles/Step_3.dir/src/graphics/imgui/imgui_impl_opengl3.cpp.o 980c5261fd9c0f5b
2217 3906 1670876125173563380 CMakeFiles/Step_3.dir/src/graphics/gl/shader.cpp.o aeff19da56485422
2 2301 1670876123565522109 CMakeFiles/Step_3.dir/src/engine/math/bvh.cpp.o aff69ce8ec561f55
2 3624 1670876124889556091 CMakeFiles/Step_3.dir/src/engine/main.cpp.o a198afd6f0365ccf
25 2468 1670876123733526419 CMakeFiles/Step_3.dir/src/engine/util/parser.cpp.o 71d47ce5f4e22904
6 2217 1670876123485520056 CMakeFiles/Step_3.dir/src/engine/util/loaders.cpp.o 5e8760f6994ede45
2038 3559 1670950159463461471 CMakeFiles/Step_3.dir/src/graphics/gl/shader.cpp.o aeff19da56485422
2 2346 1670950158247431146 CMakeFiles/Step_3.dir/src/engine/math/bvh.cpp.o aff69ce8ec561f55
2 3263 1670950159163453989 CMakeFiles/Step_3.dir/src/engine/main.cpp.o a198afd6f0365ccf
3 2165 1670950158067426657 CMakeFiles/Step_3.dir/src/engine/util/parser.cpp.o 71d47ce5f4e22904
3 2358 1670950158255431344 CMakeFiles/Step_3.dir/src/engine/util/loaders.cpp.o 5e8760f6994ede45
3 1466 1670970936704162025 CMakeFiles/Step_3.dir/src/graphics/gl/shader.cpp.o aeff19da56485422
3 1518 1670970936756163440 CMakeFiles/Step_3.dir/src/graphics/gl/gl.cpp.o 6fdeee2b4621ca7d
3 1610 1670970936848165948 CMakeFiles/Step_3.dir/src/graphics/debug_gui.cpp.o 645211f1ad0dfed4
2 1657 1670970936896167252 CMakeFiles/Step_3.dir/src/engine/globals.cpp.o 1fb6828ece7be9ea
3 1675 1670970936912167688 CMakeFiles/Step_3.dir/src/engine/util/models.cpp.o 3cb2f1649f5ebcd1
3 1739 1670970936976169430 CMakeFiles/Step_3.dir/src/engine/util/loaders.cpp.o 5e8760f6994ede45
2 1758 1670970936996169975 CMakeFiles/Step_3.dir/src/engine/math/bvh.cpp.o aff69ce8ec561f55
2 1817 1670970937056171607 CMakeFiles/Step_3.dir/src/engine/util/debug.cpp.o c94ada31065dd0f4
1518 1965 1670970937204175639 CMakeFiles/Step_3.dir/src/graphics/imgui/imgui_impl_x11.cpp.o f90197c7146e69c3
3 2030 1670970937268177379 CMakeFiles/Step_3.dir/src/engine/world.cpp.o 29ff1a38503c06b0
2 2045 1670970937284177817 CMakeFiles/Step_3.dir/src/engine/raytracing.cpp.o 78a5cc225017e748
2 2254 1670970937492183476 CMakeFiles/Step_3.dir/src/engine/image/image.cpp.o d267b51f3c38b1c8
2 2422 1670970937660188050 CMakeFiles/Step_3.dir/src/engine/main.cpp.o a198afd6f0365ccf
1611 2502 1670970937740190228 CMakeFiles/Step_3.dir/src/graphics/input.cpp.o 2b898ab4a04b8bdb
1466 2953 1670970938192202535 CMakeFiles/Step_3.dir/src/graphics/graphics.cpp.o 6b1a12e1042d4a97
2953 3126 1670970938364207215 Step_3 6bc0df4fa69a503b

View File

@ -1,3 +1,3 @@
Start testing: Dec 12 15:15 EST
Start testing: Dec 13 17:35 EST
----------------------------------------------------------
End testing: Dec 12 15:15 EST
End testing: Dec 13 17:35 EST

View File

@ -30,7 +30,7 @@ namespace Raytracing {
/**
* @return the queue of image bounds which this process needs to do work on
*/
static std::queue<RaycasterImageBounds> getCurrentImageRegionAssociation(RayCaster& raycaster);
static std::queue<RayCasterImageBounds> getCurrentImageRegionAssociation(RayCaster& raycaster);
};
}
#endif

View File

@ -69,22 +69,30 @@ namespace Raytracing {
}
/**
* Projects an xy coord into world space
* @param x image x coord
* @param y image y coord
* @return a Ray projected from camera position out into the world based on the relative position in the image.
*/
Ray projectRay(PRECISION_TYPE x, PRECISION_TYPE y);
void setPosition(const Vec4& pos) { this->position = pos; }
// the follow utility functions are actually taking forever to get right
// I can't tell if my projection calculation is off or the view calc?
// got to install GLM to test which function works and which does. Maybe they are both bad. or Maybe it's my matrix impl
// or maybe the whole rendering stack sucks
[[nodiscard]] Mat4x4 project() const {
/**
* Creates a projection matrix for use in the OpenGL pipeline.
* @return Mat4x4 containing a standard perspective projection matrix
*/
[[nodiscard]] inline Mat4x4 project() const {
Mat4x4 project{emptyMatrix};
// this should be all it takes to create a mostly correct projection matrix
// the values are transposed because my matrix implementation is terrible.
// This is set up in such a way that it is 1:1 with the CPU ray projection. Meaning when you move the camera in "Debug" mode,
// the rays will be projected from that position and camera look direction.
project.m00(float(1.0 / (aspectRatio * tanFovHalf)));
project.m11(float(1.0 / tanFovHalf));
project.m22(float(-((FAR_PLANE + NEAR_PLANE) / frustumLength)));
// this has been transposed
project.m32(-1);
project.m23(float(-((2 * NEAR_PLANE * FAR_PLANE) / frustumLength)));
//project.m33(0);
@ -95,6 +103,15 @@ namespace Raytracing {
//return Mat4x4{projectG};
}
/**
* Creates a view matrix containing the camera rotation and inverse position.
* the view matrix is used to transform world coordinates into camera space,
* which can than be transformed into screen space using the projection matrix.
* @param yaw yaw of the camera
* @param pitch pitch of the camera
* @param roll NOT SUPPORTED
* @return Mat4x4 containing rotation in the first 3x3 values and -position in the last column
*/
Mat4x4 view(PRECISION_TYPE yaw, PRECISION_TYPE pitch);
[[nodiscard]] inline Vec4 getPosition() const { return position; };
@ -108,55 +125,79 @@ namespace Raytracing {
// the camera's position must be set with setPosition(Vec4);
// uses an internal up vector, assumed to be {0, 1, 0}
// will make the camera look at provided position with respects to the current camera position.
// TODO: update the view matrix. Requires that the view matrix be stored in the camera.
void lookAt(const Vec4& lookAtPos);
};
static Random rnd{-1.0, 1.0};
struct RaycasterImageBounds {
struct RayCasterImageBounds {
int width, height, x, y;
};
class RayCaster {
private:
int maxBounceDepth = 50;
int raysPerPixel = 50;
const unsigned int system_threads = std::thread::hardware_concurrency();
int maxBounceDepth;
int raysPerPixel;
unsigned int finishedThreads = 0;
Camera& camera;
Image& image;
World& world;
std::vector<std::unique_ptr<std::thread>> executors{};
// is the raytracer still running?
bool stillRunning = true;
unsigned int finishedThreads = 0;
unsigned int system_threads = std::thread::hardware_concurrency();
// yes this is actually the only sync we need between the threads
// and compared to the actual runtime of the raytracing it's very small!
std::mutex queueSync;
std::queue<RaycasterImageBounds>* unprocessedQuads = nullptr;
Vec4 raycasti(const Ray& ray, int depth);
// the queue containing the image bounds to be rendered.
std::queue<RayCasterImageBounds>* unprocessedQuads = nullptr;
std::vector<std::unique_ptr<std::thread>> executors{};
/**
* Does the actual ray casting algorithm. Simulates up to maxBounceDepth ray depth.
* @param ray ray to begin with
* @return the overall average color of the ray
*/
Vec4 raycast(const Ray& ray);
void runRaycastingAlgorithm(RaycasterImageBounds imageBounds, int loopX, int loopY);
/**
*
* @param imageBounds bounds to work on
* @param loopX the current x position to work on, between 0 and imageBounds.width
* @param loopY the current y position to work on, between 0 and imageBounds.height
*/
void runRaycastingAlgorithm(RayCasterImageBounds imageBounds, int loopX, int loopY);
void setupQueue(const std::vector<RaycasterImageBounds>& bounds);
/**
* Creates the queue with the provided bounds
*/
void setupQueue(const std::vector<RayCasterImageBounds>& bounds);
public:
RayCaster(Camera& c, Image& i, World& world, Parser& p):
camera(c), image(i), world(world) {
world.generateBVH();
maxBounceDepth = std::stoi(p.getOptionValue("--maxRayDepth"));
raysPerPixel = std::stoi(p.getOptionValue("--raysPerPixel"));
}
inline void updateRayInfo(int maxBounce, int perPixel) {
raysPerPixel = perPixel;
maxBounceDepth = maxBounce;
}
inline void resetRayInfo() {
raysPerPixel = 50;
maxBounceDepth = 50;
}
std::vector<RaycasterImageBounds> partitionScreen(int threads = -1);
/**
* divides the screen into image bounds
* @param threads number of threads that will determine how many cuts to the screen is required
* @return a list of bounds
*/
std::vector<RayCasterImageBounds> partitionScreen(int threads = -1);
/**
* Updates the thread value based on conditions, used for setting up the actual threads for execution.
* @param threads reference to the value which will be updated.
*/
inline void updateThreadValue(int& threads) const {
if (threads < 0 || threads == 1)
threads = 1;
@ -166,28 +207,42 @@ namespace Raytracing {
}
}
/**
* Creates a random vector in the unit sphere.
*/
inline static Vec4 randomUnitVector() {
return Vec4(rnd.getDouble(), rnd.getDouble(), rnd.getDouble()).normalize();
}
RayCaster(Camera& c, Image& i, World& world, const Parser& p):
camera(c), image(i), world(world) {
world.generateBVH();
}
/**
* Runs the std::thread implementation
* @param threads number of threads to use
*/
void runSTDThread(int threads = -1);
/**
* Runs the OpenMP implementation
* @param threads number of threads to use
*/
void runOpenMP(int threads = -1);
void runMPI(std::queue<RaycasterImageBounds> bounds);
[[nodiscard]] inline bool areThreadsStillRunning() const { return finishedThreads == executors.size(); }
/**
* ran by MPI
* @param bounds bounds that get processed by this process
*/
void runMPI(std::queue<RayCasterImageBounds> bounds);
/**
* Blocking call that waits for all the threads to finish exeuction
*/
inline void join() {
for (auto& p : executors)
p->join();
}
/**
* Joins all joinable threads and clears the thread list.
*/
void deleteThreads() {
for (auto& p : executors) {
// wait for all threads to exit before trying to delete them.

View File

@ -11,7 +11,9 @@
#include <config.h>
#ifdef COMPILE_GUI
#include <graphics/gl/gl.h>
#endif
@ -22,7 +24,7 @@
// so I moved them here.
namespace Raytracing {
struct HitData {
// all the other values only matter if this is true
bool hit{false};
@ -35,7 +37,7 @@ namespace Raytracing {
// Texture UV Coords.
PRECISION_TYPE u, v;
};
struct ScatterResults {
// returns true to recast the ray with the provided ray
bool scattered;
@ -44,54 +46,67 @@ namespace Raytracing {
// the color of the material
Vec4 attenuationColor;
};
class Material {
protected:
// most materials will need an albedo
Vec4 baseColor;
public:
explicit Material(const Vec4& baseColor): baseColor(baseColor) {}
// returns true if the ray was scattered along with the scattered ray, otherwise will return false with empty ray.
// the returned vec4 is the attenuation color
[[nodiscard]] virtual ScatterResults scatter(const Ray& ray, const HitData& hitData) const = 0;
// emission value for this material
// this allows for a material to glow slightly or emit full on light
// the light can of course be of any color
// and the UV coords along with the actual hit point are provided for your convince
[[nodiscard]] virtual Vec4 emission(PRECISION_TYPE u, PRECISION_TYPE v, const Vec4& hitPoint) const { return {}; }
[[nodiscard]] Vec4 getBaseColor() const { return baseColor; }
virtual ~Material() = default;
};
struct DebugBVHData {
void* bvhTree;
// I actually currently have no idea what this means
// I suspect it's legacy code from when I was debugging the BVHs
bool isRegular;
};
class Object {
protected:
AABB aabb;
Vec4 position;
Material* material;
#ifdef COMPILE_GUI
VAO* vao = nullptr;
#endif
#ifdef COMPILE_GUI
VAO* vao = nullptr;
#endif
public:
Object(Material* material, const Vec4& position): material(material), position(position), aabb({}) {};
// return true if the ray intersects with this object, only between min and max
[[nodiscard]] virtual HitData checkIfHit(const Ray& ray, PRECISION_TYPE min, PRECISION_TYPE max) const = 0;
[[nodiscard]] Material* getMaterial() const { return material; }
[[nodiscard]] virtual AABB& getAABB() { return aabb; }
// FIXME: Use of void* is inadvisable. Although this is only for debug consider another method.
[[nodiscard]] virtual DebugBVHData getBVHTree(){ return {nullptr, false}; }
[[nodiscard]] virtual DebugBVHData getBVHTree() { return {nullptr, false}; }
[[nodiscard]] Vec4 getPosition() const { return position; }
virtual void setAABB(const AABB& ab) { this->aabb = ab; }
#ifdef COMPILE_GUI
[[nodiscard]] inline VAO* getVAO(){return vao;}
#endif
#ifdef COMPILE_GUI
[[nodiscard]] inline VAO* getVAO() { return vao; }
#endif
virtual ~Object() = default;
};
}

View File

@ -47,6 +47,8 @@ namespace Raytracing {
TriangulatedModel model{data};
this->triangles = model.triangles;
this->aabb = std::move(model.aabb);
// a required step to generate a BVH however we aren't using the triangle bvh due to issues with it
// so ignore this and sequential triangle BVH nonsense.
std::vector<TriangleBVHObject> triangulatedObjects;
for (const auto& tri : triangles) {
TriangleBVHObject triangleObject;
@ -152,8 +154,10 @@ namespace Raytracing {
inline void add(Object* object) {
objects.push_back(object);
#ifdef COMPILE_GUI
if (object->getBVHTree().bvhTree != nullptr && !object->getBVHTree().isRegular)
new DebugBVH{(TriangleBVHTree*) object->getBVHTree().bvhTree, m_config.worldShader};
// this will show up in the debug mode
// disabled because we aren't using object local BVHs
//if (object->getBVHTree().bvhTree != nullptr && !object->getBVHTree().isRegular)
// new DebugBVH{(TriangleBVHTree*) object->getBVHTree().bvhTree, m_config.worldShader};
#endif
}
@ -165,6 +169,13 @@ namespace Raytracing {
[[nodiscard]] inline std::vector<Object*> getObjectsInWorld() { return objects; }
/**
* goes through the entire world using the BVH to determine if the ray has hit anything
* @param ray ray to check
* @param min min of the ray
* @param max max of the ray
* @return HitData about the closest object that was hit.
*/
[[nodiscard]] virtual std::pair<HitData, Object*> checkIfHit(const Ray& ray, PRECISION_TYPE min, PRECISION_TYPE max) const;
~World();

View File

@ -11,10 +11,14 @@
#include <string>
#include <engine/math/bvh.h>
/**
* This stuff can safely be ignored as it is purely for me to debug
*/
namespace Raytracing {
class DebugUI {
public:
static void render(const std::function<void()>& generalTab);
static void registerTab(const std::string& name, const std::function<void()>& tabFunc);
};
@ -22,21 +26,28 @@ namespace Raytracing {
public:
virtual void render() = 0;
};
class DebugMenus {
public:
static void add(const std::shared_ptr<DebugObject>& object);
static void remove(DebugObject* object);
static void render();
};
class DebugBVH : public DebugObject {
private:
BVHTree* m_bvhTree;
TriangleBVHTree* m_triangleBVHTree;
BVHTree* m_bvhTree = nullptr;
TriangleBVHTree* m_triangleBVHTree = nullptr;
Shader& m_shader;
public:
explicit DebugBVH(BVHTree* bvhTree, Shader& shader);
explicit DebugBVH(TriangleBVHTree* bvhTree, Shader& shader);
void render();
~DebugBVH();
};
}

View File

@ -40,45 +40,45 @@ class Shapes {
std::vector<float> cubeVerticesRaw = {
-0.5f, -0.5f, -0.5f,
0.5f, -0.5f, -0.5f,
0.5f, 0.5f, -0.5f,
0.5f, 0.5f, -0.5f,
-0.5f, 0.5f, -0.5f,
0.5f, 0.5f, -0.5f,
0.5f, 0.5f, -0.5f,
-0.5f, 0.5f, -0.5f,
-0.5f, -0.5f, -0.5f,
-0.5f, -0.5f, 0.5f,
0.5f, -0.5f, 0.5f,
0.5f, 0.5f, 0.5f,
0.5f, 0.5f, 0.5f,
-0.5f, 0.5f, 0.5f,
-0.5f, -0.5f, 0.5f,
-0.5f, -0.5f, 0.5f,
0.5f, -0.5f, 0.5f,
0.5f, 0.5f, 0.5f,
0.5f, 0.5f, 0.5f,
-0.5f, 0.5f, 0.5f,
-0.5f, -0.5f, 0.5f,
-0.5f, 0.5f, 0.5f,
-0.5f, 0.5f, -0.5f,
-0.5f, 0.5f, 0.5f,
-0.5f, 0.5f, -0.5f,
-0.5f, -0.5f, -0.5f,
-0.5f, -0.5f, -0.5f,
-0.5f, -0.5f, 0.5f,
-0.5f, 0.5f, 0.5f,
-0.5f, -0.5f, 0.5f,
-0.5f, 0.5f, 0.5f,
0.5f, 0.5f, 0.5f,
0.5f, 0.5f, -0.5f,
0.5f, 0.5f, 0.5f,
0.5f, 0.5f, -0.5f,
0.5f, -0.5f, -0.5f,
0.5f, -0.5f, -0.5f,
0.5f, -0.5f, 0.5f,
0.5f, 0.5f, 0.5f,
0.5f, -0.5f, 0.5f,
0.5f, 0.5f, 0.5f,
-0.5f, -0.5f, -0.5f,
0.5f, -0.5f, -0.5f,
0.5f, -0.5f, 0.5f,
0.5f, -0.5f, 0.5f,
-0.5f, -0.5f, 0.5f,
0.5f, -0.5f, 0.5f,
0.5f, -0.5f, 0.5f,
-0.5f, -0.5f, 0.5f,
-0.5f, -0.5f, -0.5f,
-0.5f, 0.5f, -0.5f,
0.5f, 0.5f, -0.5f,
0.5f, 0.5f, 0.5f,
0.5f, 0.5f, 0.5f,
-0.5f, 0.5f, 0.5f,
-0.5f, 0.5f, -0.5f,
-0.5f, 0.5f, -0.5f,
0.5f, 0.5f, -0.5f,
0.5f, 0.5f, 0.5f,
0.5f, 0.5f, 0.5f,
-0.5f, 0.5f, 0.5f,
-0.5f, 0.5f, -0.5f,
};
std::vector<float> cubeUVs = {
0.0f, 0.0f,
@ -87,35 +87,35 @@ class Shapes {
1.0f, 1.0f,
0.0f, 1.0f,
0.0f, 0.0f,
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f,
1.0f, 1.0f,
0.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 1.0f,
0.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 1.0f,
0.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
0.0f, 1.0f,
1.0f, 1.0f,
1.0f, 0.0f,
1.0f, 0.0f,
0.0f, 0.0f,
0.0f, 1.0f,
0.0f, 1.0f,
1.0f, 1.0f,
1.0f, 0.0f,
@ -123,53 +123,54 @@ class Shapes {
0.0f, 0.0f,
0.0f, 1.0f
};
static cubeVertexBuilder getCubeExtends(float xRadius, float yRadius, float zRadius) {
cubeVertexBuilder builder {};
cubeVertexBuilder builder{};
// Can we use the transformation matrix? Yes.
// Are we going to? No.
// Why? No good reason. Perhaps a TODO:?
builder.cubeVerticesRaw = {
-xRadius, -yRadius, -zRadius,
xRadius, -yRadius, -zRadius,
xRadius, yRadius, -zRadius,
xRadius, yRadius, -zRadius,
-xRadius, yRadius, -zRadius,
xRadius, yRadius, -zRadius,
xRadius, yRadius, -zRadius,
-xRadius, yRadius, -zRadius,
-xRadius, -yRadius, -zRadius,
-xRadius, -yRadius, zRadius,
xRadius, -yRadius, zRadius,
xRadius, yRadius, zRadius,
xRadius, yRadius, zRadius,
-xRadius, yRadius, zRadius,
-xRadius, -yRadius, zRadius,
-xRadius, -yRadius, zRadius,
xRadius, -yRadius, zRadius,
xRadius, yRadius, zRadius,
xRadius, yRadius, zRadius,
-xRadius, yRadius, zRadius,
-xRadius, -yRadius, zRadius,
-xRadius, yRadius, zRadius,
-xRadius, yRadius, -zRadius,
-xRadius, yRadius, zRadius,
-xRadius, yRadius, -zRadius,
-xRadius, -yRadius, -zRadius,
-xRadius, -yRadius, -zRadius,
-xRadius, -yRadius, zRadius,
-xRadius, yRadius, zRadius,
-xRadius, -yRadius, zRadius,
-xRadius, yRadius, zRadius,
xRadius, yRadius, zRadius,
xRadius, yRadius, -zRadius,
xRadius, yRadius, zRadius,
xRadius, yRadius, -zRadius,
xRadius, -yRadius, -zRadius,
xRadius, -yRadius, -zRadius,
xRadius, -yRadius, zRadius,
xRadius, yRadius, zRadius,
xRadius, -yRadius, zRadius,
xRadius, yRadius, zRadius,
-xRadius, -yRadius, -zRadius,
xRadius, -yRadius, -zRadius,
xRadius, -yRadius, zRadius,
xRadius, -yRadius, zRadius,
-xRadius, -yRadius, zRadius,
xRadius, -yRadius, zRadius,
xRadius, -yRadius, zRadius,
-xRadius, -yRadius, zRadius,
-xRadius, -yRadius, -zRadius,
-xRadius, yRadius, -zRadius,
xRadius, yRadius, -zRadius,
xRadius, yRadius, zRadius,
xRadius, yRadius, zRadius,
-xRadius, yRadius, zRadius,
-xRadius, yRadius, -zRadius,
-xRadius, yRadius, -zRadius,
xRadius, yRadius, -zRadius,
xRadius, yRadius, zRadius,
xRadius, yRadius, zRadius,
-xRadius, yRadius, zRadius,
-xRadius, yRadius, -zRadius,
};
return builder;
}
@ -186,6 +187,7 @@ class Texture {
protected:
unsigned int textureID;
int width, height, channels;
unsigned char* loadTexture(const std::string& path);
Raytracing::Image* _image = nullptr;
@ -195,13 +197,22 @@ class Texture {
Texture(Texture&&) noexcept = delete; // Disable move constructor.
Texture& operator=(Texture&&) noexcept = delete; // Disable Move Assignment
Texture();
explicit Texture(const std::string& path);
explicit Texture(Raytracing::Image* image);
~Texture();
// updates the texture on the GPU using the image pointer stored in the texture class. Does nothing if not using image
void updateImage();
void bind() const;
void unbind();
void enableGlTextures(int textureCount);
[[nodiscard]] inline unsigned int getTextureID() const { return textureID; }
};
@ -210,18 +221,24 @@ class VAO {
unsigned int VaoID, instanceVBO;
std::vector<unsigned int> VBOs;
int drawCount = -1, currentTransforms = -1;
// vertex data
unsigned int storeData(int attrNumber, int coordSize, int stride, long offset, int length, const float* data);
// element data (indices)
unsigned int storeData(int length, const unsigned int* data);
// instance data
unsigned int createInstanceVBO(int count, int bytePerInstance);
// used much in the same way that store data sets an attribute where the data is expected
// except this sets based on the master instance vbo, telling the GPU where to use the data and when.
void addInstancedAttribute(int attribute, int dataSize, int dataLengthBytes, int offset) const;
// disable bad constructors
// we can't just make copies of GPU objects like we can on the CPU. It's stupidly expensive.
VAO() = default;
VAO(const VAO& that); // Disable Copy Constructor
VAO& operator=(const VAO& that); // Disable Copy Assignment
public:
@ -229,17 +246,25 @@ class VAO {
VAO& operator=(VAO&&) noexcept = delete; // Disable Move Assignment
explicit VAO(const std::vector<Raytracing::Triangle>& triangles);
explicit VAO(const std::vector<std::shared_ptr<Raytracing::Triangle>>& triangles);
VAO(const std::vector<float>& verts, const std::vector<float>& uvs, const std::vector<unsigned int>& indices);
VAO(const std::vector<float>& verts, const std::vector<float>& uvs);
void bind() const;
void unbind();
// draws as if it where a fullscreen quad (literally used for that)
void draw() const;
// draw as if it's a box that we need to bulk draw.
void draw(Raytracing::Shader& shader, const std::vector<Raytracing::Vec4>& positions) const;
void draw(Raytracing::Shader& shader);
~VAO();
};

File diff suppressed because it is too large Load Diff

View File

@ -9,13 +9,16 @@
#include "engine/util/std.h"
#include "engine/math/vectors.h"
#include <config.h>
#ifndef USE_GLFW
#include <GL/gl.h>
#include <GLES3/gl32.h>
#include <GL/glx.h>
#include <GL/glu.h>
#else
#include <graphics/gl/glad/gl.h>
#endif
@ -37,29 +40,46 @@ namespace Raytracing {
unsigned int geometryShaderID = 0;
unsigned int tessalationShaderID = 0;
std::unordered_map<std::string, IntDefaultedToMinusOne> uniformVars;
static unsigned int loadShader(const std::string &file, int type);
static unsigned int loadShader(const std::string& file, int type);
// loads from a string rather than a file!
static unsigned int loadShaderString(const std::string &str, int type);
GLint getUniformLocation(const std::string &name);
static void checkCompileErrors(unsigned int shader, const std::string& type, const std::string& shaderPath);
static unsigned int loadShaderString(const std::string& str, int type);
GLint getUniformLocation(const std::string& name);
public:
Shader(const std::string& vertex, const std::string& fragment, bool loadString = false);
Shader(const std::string& vertex, const std::string& geometry, const std::string& fragment, bool loadString = false);
// used to set the location of VAOs to the in variables in opengl shaders.
// used to set the location of VAOs to the in variables in opengl shaders. (using layouts instead)
void bindAttribute(int attribute, const std::string& name);
// used to set location of shared UBOs
// used to set location of shared UBOs (unused)
void setUniformBlockLocation(const std::string& name, int location);
// set various data-types.
void setBool(const std::string &name, bool value);
void setInt(const std::string &name, int value);
void setFloat(const std::string &name, float value);
void setMatrix(const std::string &name, Mat4x4& matrix);
void setVec4(const std::string &name, const Vec4& vec);
void setVec3(const std::string &name, const Vec4& vec);
void setVec2(const std::string &name, float x, float y);
void setVec3(const std::string &name, float x, float y, float z);
void setVec4(const std::string &name, float x, float y, float z, float w);
void setBool(const std::string& name, bool value);
void setInt(const std::string& name, int value);
void setFloat(const std::string& name, float value);
void setMatrix(const std::string& name, Mat4x4& matrix);
void setVec4(const std::string& name, const Vec4& vec);
void setVec3(const std::string& name, const Vec4& vec);
void setVec2(const std::string& name, float x, float y);
void setVec3(const std::string& name, float x, float y, float z);
void setVec4(const std::string& name, float x, float y, float z, float w);
void use();
~Shader();
};

View File

@ -41,10 +41,14 @@
namespace Raytracing {
void drawQuad();
void deleteQuad();
#ifdef USE_GLFW
/**
* The class used to create and handle window management.
*/
class XWindow {
private:
GLFWwindow* window;
@ -56,23 +60,41 @@ namespace Raytracing {
PRECISION_TYPE fps{};
public:
XWindow(int width, int height);
// runs X11 event processing and some GL commands used for window drawing
void beginUpdate();
void endUpdate();
[[nodiscard]] inline bool shouldWindowClose() const { return isCloseRequested; }
/**
* @return time between frames in milliseconds
*/
[[nodiscard]] inline PRECISION_TYPE getFrameTimeMillis() const { return frameTimeMs; }
/**
* @return time between frames in seconds
*/
[[nodiscard]] inline PRECISION_TYPE getFrameTimeSeconds() const { return frameTimeS; }
/**
* @return the number of frames in the last second
*/
[[nodiscard]] inline PRECISION_TYPE getFPS() const { return fps; }
void setMouseGrabbed(bool grabbed);
bool isMouseGrabbed();
[[nodiscard]] inline int displayWidth() const { return m_displayWidth; }
[[nodiscard]] inline int displayHeight() const { return m_displayHeight; }
[[nodiscard]] inline GLFWwindow* getWindow() const { return window; }
void closeWindow();
~XWindow();
};
@ -142,18 +164,25 @@ namespace Raytracing {
Parser& m_parser;
Camera& m_camera;
public:
DisplayRenderer(XWindow& mWindow,
Texture& mMainImage,
World& world,
Shader& mImageShader,
Shader& mWorldShader,
RayCaster& mRaycaster,
Parser& mParser,
Camera& mCamera)
DisplayRenderer(
XWindow& mWindow,
Texture& mMainImage,
World& world,
Shader& mImageShader,
Shader& mWorldShader,
RayCaster& mRaycaster,
Parser& mParser,
Camera& mCamera
)
:
m_window(mWindow), m_mainImage(mMainImage), m_imageShader(mImageShader), m_worldShader(mWorldShader), m_raycaster(mRaycaster),
m_parser(mParser), m_camera(mCamera), m_world(world) {}
std::pair<Mat4x4, Mat4x4> getCameraMatrices();
/**
* Handles all the drawing nonsense, call from the main update loop once per frame.
*/
void draw();
};
}

View File

@ -8,6 +8,7 @@
#define XK_LATIN1
#define XK_MISCELLANY
#include <graphics/keys.h>
#include <engine/util/std.h>
@ -41,39 +42,60 @@ namespace Raytracing {
struct MouseMovementData {
double x, y;
MouseMovementData(double x, double y): x(x), y(y) {}
};
extern InputState* _inputState;
/**
* GLFW Keys / Mouse buttons are what are used.
*/
class Input {
public:
static inline void keyPressed(int key){_inputState->keysDown[key] = true; _inputState->state[key] = true;}
static inline void keyReleased(int key){_inputState->keysDown[key] = false;}
static inline void mousePressed(int button){_inputState->mouseDown[button] = true; *_inputState->mouseState=true;}
static inline void mouseReleased(int button){_inputState->mouseDown[button] = false;}
static inline void moveMove(double x, double y) {
_inputState->mousePos[0] = x; _inputState->mousePos[1] = y;
static inline void keyPressed(int key) {
_inputState->keysDown[key] = true;
_inputState->state[key] = true;
}
static inline bool isKeyDown(int key){return _inputState->keysDown[key];}
static inline void state(){
static inline void keyReleased(int key) { _inputState->keysDown[key] = false; }
static inline void mousePressed(int button) {
_inputState->mouseDown[button] = true;
*_inputState->mouseState = true;
}
static inline void mouseReleased(int button) { _inputState->mouseDown[button] = false; }
static inline void moveMove(double x, double y) {
_inputState->mousePos[0] = x;
_inputState->mousePos[1] = y;
}
static inline bool isKeyDown(int key) { return _inputState->keysDown[key]; }
static inline void state() {
// update the state used in single keypress events and the change in mouse position
for (int i = 0; i < 0xffff; i++)
_inputState->state[i]=false;
*_inputState->mouseState=false;
_inputState->state[i] = false;
*_inputState->mouseState = false;
_inputState->mouseDelta[0] = _inputState->mousePosLast[0] - _inputState->mousePos[0];
_inputState->mouseDelta[1] = _inputState->mousePosLast[1] - _inputState->mousePos[1];
_inputState->mousePosLast[0] = _inputState->mousePos[0];
_inputState->mousePosLast[1] = _inputState->mousePos[1];
}
static inline bool isState(int key){return _inputState->state[key];}
static inline bool isMouseState(){return *_inputState->mouseState;}
static inline MouseMovementData getMousePosition(){return {_inputState->mousePos[0], _inputState->mousePos[1]};}
static inline MouseMovementData getMouseDelta(){return {_inputState->mouseDelta[0], _inputState->mouseDelta[1]};}
static inline bool isState(int key) { return _inputState->state[key]; }
static inline bool isMouseState() { return *_inputState->mouseState; }
static inline MouseMovementData getMousePosition() { return {_inputState->mousePos[0], _inputState->mousePos[1]}; }
static inline MouseMovementData getMouseDelta() { return {_inputState->mouseDelta[0], _inputState->mouseDelta[1]}; }
};
static void deleteKeys(){
static void deleteKeys() {
delete[](_inputState->keysDown);
delete[](_inputState->mouseDown);
delete[](_inputState->mouseDelta);

View File

@ -1,8 +1,3 @@
/*
* Created by Brett Terpstra 6920201 on 22/10/22.
* Copyright (c) 2022 Brett Terpstra. All Rights Reserved.
*/
#ifndef STEP_3_KEYS_H
#define STEP_3_KEYS_H

View File

@ -5,24 +5,30 @@
#include "engine/image/image.h"
#include <ios>
#include <fstream>
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "engine/image/stb_image_write.h"
#include "engine/image/stb/stb_image_write.h"
#define STB_IMAGE_IMPLEMENTATION
#include "engine/image/stb_image.h"
#include "engine/image/stb/stb_image.h"
#define STB_IMAGE_RESIZE_IMPLEMENTATION
#include "engine/image/stb_image_resize.h"
#include "engine/image/stb/stb_image_resize.h"
#include <config.h>
namespace Raytracing {
Image::Image(unsigned long width, unsigned long height) : width(width), height(height), _width(width-1), _height(height-1) {
Image::Image(unsigned long width, unsigned long height): width(width), height(height), _width(width - 1), _height(height - 1) {
pixelData = new Vec4[(width + 1) * (height + 1)];
for (int i = 0; i < (width + 1) * (height + 1); i++){
pixelData[i] = Vec4{0,0,0,0};
for (int i = 0; i < (width + 1) * (height + 1); i++) {
pixelData[i] = Vec4{0, 0, 0, 0};
}
}
Image::Image(const Image& image) : width(image.width), height(image.height), _width(image._width), _height(image._height) {
Image::Image(const Image& image): width(image.width), height(image.height), _width(image._width), _height(image._height) {
pixelData = new Vec4[(image.width + 1) * (image.height + 1)];
for (int i = 0; i < image.width; i++) {
for (int j = 0; j < image.height; j++) {
@ -30,11 +36,11 @@ namespace Raytracing {
}
}
}
Image::~Image() {
delete[](pixelData);
}
std::vector<double> Image::toArray() {
std::vector<double> doublin;
for (int i = 0; i < (width + 1) * (height + 1); i++) {
@ -46,36 +52,36 @@ namespace Raytracing {
}
return doublin;
}
void Image::fromArray(double *array, int size, int id) {
for (int i = 0; i < size; i+=4){
void Image::fromArray(double* array, int size, int id) {
for (int i = 0; i < size; i += 4) {
// this is the one case where we can use the alpha value.
// Data which has been set in the image has an alpha of 1 while the rest has 0
if (array[i+3] == 0)
if (array[i + 3] == 0)
continue;
// if it was set and if the processes are properly isolated there should be no issue with overriding the pixel
pixelData[i/4] = Vec4{array[i], array[i+1], array[i+2], array[i+3]};
pixelData[i / 4] = Vec4{array[i], array[i + 1], array[i + 2], array[i + 3]};
}
}
void ImageOutput::write(const std::string& file, const std::string& formatExtension) {
if (!image.modified())
return;
auto lowerExtension = Raytracing::String::toLowerCase(formatExtension);
auto fullFile = file + "." + lowerExtension;
if (!lowerExtension.ends_with("hdr")) {
// unfortunately we do have to put the data into a format that STB can read
auto* data = new unsigned char[(unsigned long)(image.getWidth()) * (unsigned long)image.getHeight() * 3];
auto* data = new unsigned char[(unsigned long) (image.getWidth()) * (unsigned long) image.getHeight() * 3];
int pixelIndex = 0;
for (int j = image.getHeight()-1; j >= 0; j--) {
for (int j = image.getHeight() - 1; j >= 0; j--) {
for (int i = 0; i < image.getWidth(); i++) {
data[pixelIndex++] = image.getPixelR(i, j);
data[pixelIndex++] = image.getPixelG(i, j);
data[pixelIndex++] = image.getPixelB(i, j);
}
}
// Writing a PPM was giving me issues, so I switched to using STB Image Write
// It's a single threaded, public domain header only image writing library
// I didn't want to use an external lib for this, however since it is public domain
@ -106,10 +112,16 @@ namespace Raytracing {
delete[](data);
}
}
ImageInput::ImageInput(const std::string& image) {
data = stbi_load(image.c_str(), &width, &height, &channels, 4);
}
unsigned long* ImageInput::getImageAsIconBuffer() {
// I don't think this mess works
// and I could never figure out why it wasn't
// was meant for X11.
// which is part of why I switched to GLFW.
const int size = 32;
unsigned char newData[size * size * channels];
auto* returnData = new unsigned long[size * size + 2];
@ -117,14 +129,15 @@ namespace Raytracing {
int charPoint = 0;
returnData[charPoint++] = size;
returnData[charPoint++] = size;
for (int i = 0; i < size; i++){
for (int j = 0; j < size; j++){
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
unsigned long dtr = (((const unsigned long*) data)[i + j * size]);
returnData[i + j * size + 2] = (dtr >> 48) | (dtr << ((sizeof(unsigned long)*8) - 48));
returnData[i + j * size + 2] = (dtr >> 48) | (dtr << ((sizeof(unsigned long) * 8) - 48));
}
}
return returnData;
}
ImageInput::~ImageInput() {
stbi_image_free(data);
}

View File

@ -62,6 +62,15 @@ int main(int argc, char** args) {
"\tSet the max threads the ray tracer will attempt to use.\n"
"\tDefaults to all cores of your cpu.\n", "0"
);
parser.addOption(
"--maxRayDepth", "Maximum depth a Ray can Traverse\n"
"\tSets the max depth a ray is allowed to bounce\n", "50"
);
parser.addOption(
"--raysPerPixel", "Number of Rays to Cast per Pixel\n"
"\tEvery pixel will generate this number of rays.\n"
"\tHigher number = clearer image, longer compute times.\n", "50"
);
// not implemented yet
parser.addOption(
{{"--gui"},
@ -298,7 +307,9 @@ int main(int argc, char** args) {
Raytracing::RayCaster rayCaster{camera, image, world, parser};
ilog << "Running RayCaster (NO_GUI)!\n";
// we don't actually have to check for --single since it's implied to be default true.
int threads = std::stoi(parser.getOptionValue("--threads"));
int threads = 1;
if (parser.hasOption("--multi"))
threads = std::stoi(parser.getOptionValue("--threads"));
if (parser.hasOption("--mpi")) {
// We need to make sure that if the user requests that MPI be run while not having MPI compiled, they get a helpful error warning.
#ifdef USE_MPI

View File

@ -17,8 +17,8 @@ namespace Raytracing {
dlog << "Number of processes: " << numberOfProcesses << "\n";
}
std::queue<RaycasterImageBounds> Raytracing::MPI::getCurrentImageRegionAssociation(RayCaster& raycaster) {
std::queue<RaycasterImageBounds> bounders{};
std::queue<RayCasterImageBounds> Raytracing::MPI::getCurrentImageRegionAssociation(RayCaster& raycaster) {
std::queue<RayCasterImageBounds> bounders{};
auto bounds = raycaster.partitionScreen(numberOfProcesses);
auto regionSize = bounds.size() / numberOfProcesses;

View File

@ -16,7 +16,9 @@
#else
#ifdef USE_OPENMP
#include <omp.h>
#endif
#endif
@ -96,17 +98,13 @@ namespace Raytracing {
Vec4 color;
};
Vec4 RayCaster::raycasti(const Ray& ray, int depth) {
return {};
}
Vec4 RayCaster::raycast(const Ray& ray) {
Ray localRay = ray;
Vec4 color{1.0, 1.0, 1.0};
for (int CURRENT_BOUNCE = 0; CURRENT_BOUNCE < maxBounceDepth; CURRENT_BOUNCE++) {
if (RTSignal->haltExecution || RTSignal->haltRaytracing)
return color;
while (RTSignal->pauseRaytracing) // sleep for 1/60th of a second, or about 1 frame.
while (RTSignal->pauseRaytracing) // sleep for 1/60th of a second, or about 1 frame. Helps prevent busy waiting and using all system resources.
std::this_thread::sleep_for(std::chrono::milliseconds(16));
auto hit = world.checkIfHit(localRay, 0.001, infinity);
@ -138,7 +136,7 @@ namespace Raytracing {
return color;
}
void RayCaster::runRaycastingAlgorithm(RaycasterImageBounds imageBounds, int loopX, int loopY) {
void RayCaster::runRaycastingAlgorithm(RayCasterImageBounds imageBounds, int loopX, int loopY) {
try {
int x = imageBounds.x + loopX;
int y = imageBounds.y + loopY;
@ -175,7 +173,7 @@ namespace Raytracing {
str << (i + 1);
profiler::start("Raytracer Results", str.str());
while (unprocessedQuads != nullptr) {
RaycasterImageBounds imageBoundingData{};
RayCasterImageBounds imageBoundingData{};
// get the function for the quadrant
queueSync.lock();
if (unprocessedQuads->empty()) {
@ -217,7 +215,7 @@ namespace Raytracing {
// run through all the quadrants
bool running = true;
while (running) {
RaycasterImageBounds imageBoundingData{};
RayCasterImageBounds imageBoundingData{};
#pragma omp critical
{
if (unprocessedQuads->empty())
@ -228,6 +226,8 @@ namespace Raytracing {
}
}
if (running) {
// the loops here could be made parallel however it is much slower than the current way
// unless you have 1440*720=1,036,800 cores.
for (int kx = 0; kx <= imageBoundingData.width; kx++) {
for (int ky = 0; ky < imageBoundingData.height; ky++) {
runRaycastingAlgorithm(imageBoundingData, kx, ky);
@ -247,10 +247,11 @@ namespace Raytracing {
#endif
}
void RayCaster::runMPI(std::queue<RaycasterImageBounds> bounds) {
void RayCaster::runMPI(std::queue<RayCasterImageBounds> bounds) {
#ifdef USE_MPI
ilog << "Running MPI\n";
dlog << "We have " << bounds.size() << " bounds currently pending!\n";
profiler::start("Raytracer Results", ("Process Rank: " + std::to_string(currentProcessID)));
while (!bounds.empty()) {
auto region = bounds.front();
for (int kx = 0; kx <= region.width; kx++) {
@ -260,13 +261,14 @@ namespace Raytracing {
}
bounds.pop();
}
profiler::end("Raytracer Results", ("Process Rank: " + std::to_string(currentProcessID)));
dlog << "Finished running MPI on " << currentProcessID << "\n";
#else
flog << "Not compiled with MPI!\n";
#endif
}
std::vector<RaycasterImageBounds> RayCaster::partitionScreen(int threads) {
std::vector<RayCasterImageBounds> RayCaster::partitionScreen(int threads) {
// if we are running single threaded, disable everything special
// the reason we run single threaded in a seperate thread is because the GUI requires its own set of updating commands
// which cannot be blocked by the raytracer, otherwise it would become unresponsive.
@ -287,9 +289,9 @@ namespace Raytracing {
ilog << "Generating multithreaded raytracer with " << threads << " threads and " << divs << " divisions! \n";
std::vector<RaycasterImageBounds> bounds;
std::vector<RayCasterImageBounds> bounds;
// we need to subdivide the image for the threads, since this is really quick it's fine to due sequentially
// we need to subdivide the image for the threads, since this is really quick it's fine to do sequentially
for (int dx = 0; dx < divs; dx++) {
for (int dy = 0; dy < divs; dy++) {
bounds.push_back(
@ -305,9 +307,9 @@ namespace Raytracing {
return bounds;
}
void RayCaster::setupQueue(const std::vector<RaycasterImageBounds>& bounds) {
void RayCaster::setupQueue(const std::vector<RayCasterImageBounds>& bounds) {
delete (unprocessedQuads);
unprocessedQuads = new std::queue<RaycasterImageBounds>();
unprocessedQuads = new std::queue<RayCasterImageBounds>();
for (auto& b : bounds)
unprocessedQuads->push(b);
}

View File

@ -73,12 +73,12 @@ namespace Raytracing {
std::vector<std::string> returnLines;
// now combine all the loaded files while respecing the include's position in the file.
// now combine all the loaded files while respecting the include's position in the file.
for (int i = 0; i < mainLines.size(); i++) {
if (includes.contains(i)) {
auto includedFileLines = includes[i];
for (const auto& line: includedFileLines)
for (const auto& line : includedFileLines)
returnLines.push_back(line);
} else
returnLines.push_back(mainLines[i]);
@ -91,7 +91,7 @@ namespace Raytracing {
auto lines = includeDescent(path);
for (const auto& line: lines) {
for (const auto& line : lines) {
// now process the defines, if they exist
if (line.starts_with("#define")) {
auto defineParts = String::split(line, " ");

View File

@ -25,7 +25,7 @@ Raytracing::ModelData Raytracing::OBJLoader::loadModel(const std::string& file)
ModelData data;
for (const auto& line: lines) {
for (const auto& line : lines) {
auto spaces = String::split(line, " ");
if (line.starts_with("v ")) { // vertex
data.vertices.emplace_back(std::stof(spaces[1]), std::stof(spaces[2]), std::stof(spaces[3]));
@ -63,6 +63,7 @@ Raytracing::ModelData Raytracing::OBJLoader::loadModel(const std::string& file)
ilog << "Completed extracting vertex data from model file " << file << "!\n";
return data;
}
Raytracing::TriangulatedModel::TriangulatedModel(const Raytracing::ModelData& data) {
auto faces = data.faces;
auto vertices = data.vertices;
@ -71,11 +72,13 @@ Raytracing::TriangulatedModel::TriangulatedModel(const Raytracing::ModelData& da
PRECISION_TYPE minX = infinity, minY = infinity, minZ = infinity, maxX = ninfinity, maxY = ninfinity, maxZ = ninfinity;
for (face f: faces) {
// create triangles from the faces
for (face f : faces) {
auto t = std::make_shared<Triangle>(
vertices[f.v1], vertices[f.v2], vertices[f.v3],
uvs[f.uv1], uvs[f.uv2], uvs[f.uv3],
normals[f.n1], normals[f.n2], normals[f.n3]);
normals[f.n1], normals[f.n2], normals[f.n3]
);
PRECISION_TYPE tMinX = infinity, tMinY = infinity, tMinZ = infinity, tMaxX = ninfinity, tMaxY = ninfinity, tMaxZ = ninfinity;
// find the min and max of all the triangles

View File

@ -4,7 +4,7 @@
*/
#include "engine/world.h"
#include "engine/raytracing.h"
#include "engine/image/stb_image.h"
#include "engine/image/stb/stb_image.h"
namespace Raytracing {
@ -109,6 +109,9 @@ namespace Raytracing {
void World::generateBVH() {
bvhObjects = std::make_unique<BVHTree>(objects);
#ifdef COMPILE_GUI
new DebugBVH(bvhObjects.get(), m_config.worldShader);
#endif
}
ScatterResults DiffuseMaterial::scatter(const Ray& ray, const HitData& hitData) const {

View File

@ -9,6 +9,7 @@
#include <utility>
// this file is only included if the compile gui setting is enabled in CMake
// Feel free to ignore this file, I'm not going to explain it. Purely for debugging the BVH
namespace Raytracing {
std::vector<std::pair<std::string, std::function<void()>>> tabs;
@ -257,8 +258,8 @@ namespace Raytracing {
m_shader.setInt("useWhite", 1);
m_shader.setVec3("color", {1.0, 1.0, 1.0});
{
ImGui::BeginChild("left pane", ImVec2(180, 0), true);
//guiNodesRecur(m_bvhTree->getRoot());
ImGui::BeginChild("left pane", ImVec2(250, 0), true);
guiNodesRecur(m_bvhTree->getRoot());
ImGui::EndChild();
}
ImGui::SameLine();
@ -270,8 +271,7 @@ namespace Raytracing {
true,
ImGuiWindowFlags_AlwaysAutoResize
); // Leave room for 1 line below us
tlog << m_bvhTree << "\n";
//drawNodesRecur(m_shader, m_bvhTree->getRoot());
drawNodesRecur(m_shader, m_bvhTree->getRoot());
ImGui::EndChild();
ImGui::EndGroup();
}

View File

@ -5,7 +5,7 @@
#include <graphics/gl/gl.h>
#include <GL/glx.h>
#include "engine/image/stb_image.h"
#include "engine/image/stb/stb_image.h"
#ifndef USE_GLFW
PFNGLCREATEVERTEXARRAYSPROC glCreateVertexArrays;
@ -47,12 +47,13 @@ unsigned int VAO::storeData(int attrNumber, int coordSize, int stride, long offs
glBindBuffer(GL_ARRAY_BUFFER, vboID);
// 4 bytes / float
glBufferData(GL_ARRAY_BUFFER, length << 2, data, GL_STATIC_DRAW);
glVertexAttribPointer(attrNumber,coordSize,GL_FLOAT,false,stride, (void *) offset);
glVertexAttribPointer(attrNumber, coordSize, GL_FLOAT, false, stride, (void*) offset);
glBindBuffer(GL_ARRAY_BUFFER, 0);
return vboID;
}
unsigned int VAO::storeData(int length, const unsigned int *data) {
unsigned int VAO::storeData(int length, const unsigned int* data) {
unsigned int eboID;
glGenBuffers(1, &eboID);
@ -64,21 +65,22 @@ unsigned int VAO::storeData(int length, const unsigned int *data) {
return eboID;
}
unsigned int VAO::createInstanceVBO(int count, int bytePerInstance) {
if (currentTransforms < 0) {
unsigned int vboID;
glGenBuffers(1, &vboID);
instanceVBO = vboID;
currentTransforms = count;
glBindBuffer(GL_ARRAY_BUFFER, vboID);
glBufferData(GL_ARRAY_BUFFER, (long) count * bytePerInstance, NULL, GL_STREAM_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
return vboID;
}
if (currentTransforms < count){
if (currentTransforms < count) {
// double as to be more efficient. (prevents constant allocations when adding data per frame)
// n -> log n
currentTransforms = count * 2;
@ -90,34 +92,37 @@ unsigned int VAO::createInstanceVBO(int count, int bytePerInstance) {
// otherwise do nothing.
return instanceVBO;
}
void VAO::addInstancedAttribute(int attribute, int dataSize, int dataLengthBytes, int offset) const {
// bind buffer like normal
glBindBuffer(GL_ARRAY_BUFFER, instanceVBO);
glBindVertexArray(VaoID);
glEnableVertexAttribArray(attribute);
// tell opengl how large this attribute is expected to be
glVertexAttribPointer(attribute, dataSize, GL_FLOAT, GL_FALSE, dataLengthBytes, (void *) (long)offset);
glVertexAttribPointer(attribute, dataSize, GL_FLOAT, GL_FALSE, dataLengthBytes, (void*) (long) offset);
// how many per instance. 1 mean every triangle gets one copy of the data specified by ^
glVertexAttribDivisor(attribute, 1);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
VAO::VAO(const std::vector<float>& verts, const std::vector<float>& uvs, const std::vector<unsigned int>& indices): VaoID(createVAO()) {
this->drawCount = (int)indices.size();
this->drawCount = (int) indices.size();
glBindVertexArray(VaoID);
// enable the attributes, prevents us from having to do this later.
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
// store index data
storeData((int)indices.size(), indices.data());
storeData((int) indices.size(), indices.data());
// store vertex data
storeData(0, 3, 3 * sizeof(float), 0, (int)verts.size(), verts.data());
storeData(0, 3, 3 * sizeof(float), 0, (int) verts.size(), verts.data());
// store texture UV data
storeData(1, 2, 2 * sizeof(float), 0, (int)uvs.size(), uvs.data());
storeData(1, 2, 2 * sizeof(float), 0, (int) uvs.size(), uvs.data());
unbind();
}
VAO::VAO(const std::vector<Raytracing::Triangle>& triangles): VaoID(createVAO()) {
this->drawCount = (int)triangles.size() * 3;
this->drawCount = (int) triangles.size() * 3;
glBindVertexArray(VaoID);
// enable the attributes, prevents us from having to do this later.
glEnableVertexAttribArray(0);
@ -127,7 +132,8 @@ VAO::VAO(const std::vector<Raytracing::Triangle>& triangles): VaoID(createVAO())
std::vector<float> verts;
std::vector<float> uvs;
std::vector<float> normals;
for (const Raytracing::Triangle& t : triangles){
// convert our triangles into GPU triangles.
for (const Raytracing::Triangle& t : triangles) {
verts.push_back(float(t.vertex1.x()));
verts.push_back(float(t.vertex1.y()));
verts.push_back(float(t.vertex1.z()));
@ -138,35 +144,35 @@ VAO::VAO(const std::vector<Raytracing::Triangle>& triangles): VaoID(createVAO())
normals.push_back(float(t.normal1.x()));
normals.push_back(float(t.normal1.y()));
normals.push_back(float(t.normal1.z()));
verts.push_back(float(t.vertex2.x()));
verts.push_back(float(t.vertex2.y()));
verts.push_back(float(t.vertex2.z()));
uvs.push_back(float(t.uv2.x()));
uvs.push_back(float(t.uv2.y()));
normals.push_back(float(t.normal2.x()));
normals.push_back(float(t.normal2.y()));
normals.push_back(float(t.normal2.z()));
verts.push_back(float(t.vertex3.x()));
verts.push_back(float(t.vertex3.y()));
verts.push_back(float(t.vertex3.z()));
uvs.push_back(float(t.uv3.x()));
uvs.push_back(float(t.uv3.y()));
normals.push_back(float(t.normal3.x()));
normals.push_back(float(t.normal3.y()));
normals.push_back(float(t.normal3.z()));
}
// store vertex data
storeData(0, 3, 3 * sizeof(float), 0, (int)verts.size(), verts.data());
storeData(0, 3, 3 * sizeof(float), 0, (int) verts.size(), verts.data());
// store texture UV data
storeData(1, 2, 2 * sizeof(float), 0, (int)uvs.size(), uvs.data());
storeData(1, 2, 2 * sizeof(float), 0, (int) uvs.size(), uvs.data());
// store normal data
storeData(2, 3, 3 * sizeof(float), 0, (int)normals.size(), normals.data());
storeData(2, 3, 3 * sizeof(float), 0, (int) normals.size(), normals.data());
// create an instance buffer with a large number of positions (stored in matrices)
// this way we don't have to expand it later, since I don't think I'll use 1k
// createInstanceVBO(1000, sizeof(Raytracing::Mat4x4));
@ -177,8 +183,9 @@ VAO::VAO(const std::vector<Raytracing::Triangle>& triangles): VaoID(createVAO())
// addInstancedAttribute(6, 4, sizeof(Raytracing::Mat4x4), 48);
unbind();
}
VAO::VAO(const std::vector<std::shared_ptr<Raytracing::Triangle>>& triangles): VaoID(createVAO()) {
this->drawCount = (int)triangles.size() * 3;
this->drawCount = (int) triangles.size() * 3;
glBindVertexArray(VaoID);
// enable the attributes, prevents us from having to do this later.
glEnableVertexAttribArray(0);
@ -188,7 +195,8 @@ VAO::VAO(const std::vector<std::shared_ptr<Raytracing::Triangle>>& triangles): V
std::vector<float> verts;
std::vector<float> uvs;
std::vector<float> normals;
for (const auto& t : triangles){
// convert our triangles into GPU triangles.
for (const auto& t : triangles) {
verts.push_back(float(t->vertex1.x()));
verts.push_back(float(t->vertex1.y()));
verts.push_back(float(t->vertex1.z()));
@ -223,20 +231,23 @@ VAO::VAO(const std::vector<std::shared_ptr<Raytracing::Triangle>>& triangles): V
normals.push_back(float(t->normal3.z()));
}
// store vertex data
storeData(0, 3, 3 * sizeof(float), 0, (int)verts.size(), verts.data());
storeData(0, 3, 3 * sizeof(float), 0, (int) verts.size(), verts.data());
// store texture UV data
storeData(1, 2, 2 * sizeof(float), 0, (int)uvs.size(), uvs.data());
storeData(1, 2, 2 * sizeof(float), 0, (int) uvs.size(), uvs.data());
// store normal data
storeData(2, 3, 3 * sizeof(float), 0, (int)normals.size(), normals.data());
storeData(2, 3, 3 * sizeof(float), 0, (int) normals.size(), normals.data());
unbind();
}
void VAO::bind() const {
glBindVertexArray(VaoID);
}
void VAO::unbind() {
glBindVertexArray(0);
VaoID;
}
void VAO::draw(Raytracing::Shader& shader, const std::vector<Raytracing::Vec4>& positions) const {
// this should only update if we are drawing with more positions than we already have allocated.
// createInstanceVBO((int)positions.size(), sizeof(Raytracing::Mat4x4));
@ -256,63 +267,69 @@ void VAO::draw(Raytracing::Shader& shader, const std::vector<Raytracing::Vec4>&
// // then finally draw
//glDrawArraysInstanced(GL_TRIANGLES, 0, drawCount * 3, (int)positions.size());
for (const auto& v : positions) {
Raytracing::Mat4x4 transform {};
Raytracing::Mat4x4 transform{};
transform.translate(v);
shader.setMatrix("transform", transform);
glDrawArrays(GL_TRIANGLES, 0, drawCount);
}
}
void VAO::draw(Raytracing::Shader& shader) {
glDrawArrays(GL_TRIANGLES, 0, drawCount);
}
void VAO::draw() const {
if (drawCount < 0)
return;
else
glDrawElements(GL_TRIANGLES, drawCount, GL_UNSIGNED_INT, 0);
}
VAO::~VAO() {
const unsigned int vao = VaoID;
glDeleteVertexArrays(1, &vao);
for (const unsigned int vbo : VBOs){
for (const unsigned int vbo : VBOs) {
glDeleteBuffers(1, &vbo);
}
glDeleteBuffers(1, &instanceVBO);
}
VAO::VAO(const std::vector<float>& verts, const std::vector<float>& uvs): VaoID(createVAO()) {
this->drawCount = (int)verts.size();
this->drawCount = (int) verts.size();
glBindVertexArray(VaoID);
// enable the attributes, prevents us from having to do this later.
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
// store vertex data
storeData(0, 3, 3 * sizeof(float), 0, (int)verts.size(), verts.data());
storeData(0, 3, 3 * sizeof(float), 0, (int) verts.size(), verts.data());
// store texture UV data
storeData(1, 2, 2 * sizeof(float), 0, (int)uvs.size(), uvs.data());
storeData(1, 2, 2 * sizeof(float), 0, (int) uvs.size(), uvs.data());
// store normal data
//storeData(2, 3, 3 * sizeof(float), 0, (int)normals.size(), normals.data());
unbind();
}
Texture::Texture(){
Texture::Texture() {
}
Texture::Texture(const std::string& path) {
data = loadTexture(path);
if (data == nullptr){
if (data == nullptr) {
flog << "There was an error loading the image file " << path;
throw std::runtime_error("Error loading image from file!");
}
glGenTextures(1, &textureID);
glBindTexture(GL_TEXTURE_2D, textureID);
// setup gl texture info
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// dynamically change storage settings based on channels in the file
int GL_RGB_SETTING = channels == 3 ? GL_RGB : GL_RGBA;
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB_SETTING, width, height, 0, GL_RGB_SETTING, GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D);
@ -325,6 +342,7 @@ Texture::Texture(Raytracing::Image* image): _image(image), width(image->getWidth
glGenTextures(1, &textureID);
glBindTexture(GL_TEXTURE_2D, textureID);
// setup gl texture info
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
@ -336,16 +354,17 @@ Texture::Texture(Raytracing::Image* image): _image(image), width(image->getWidth
// no sense sending data now since this texture is likely all black.
}
unsigned char *Texture::loadTexture(const std::string& path) {
unsigned char* Texture::loadTexture(const std::string& path) {
// TODO: add more image processing options
stbi_set_flip_vertically_on_load(true);
unsigned char *dta = stbi_load(path.c_str(), &width, &height, &channels, 0);
unsigned char* dta = stbi_load(path.c_str(), &width, &height, &channels, 0);
//if (stbi__g_failure_reason) {
// flog << "STB Error Reason: ";
// flog << stbi__g_failure_reason;
//}
return dta;
}
Texture::~Texture() {
tlog << "Deleting Texture {" << textureID << "}\n";
glDeleteTextures(1, &textureID);
@ -366,10 +385,13 @@ void Texture::enableGlTextures(int textureCount) {
glActiveTexture(GL_TEXTURE0 + i);
textureID;
}
void Texture::updateImage() {
if (_image == nullptr)
return;
glBindTexture(GL_TEXTURE_2D, textureID);
// unfortunately we do have to put the data into a format that OpenGL can read. This is a TODO:?
data = new unsigned char[(unsigned long)(width) * (unsigned long)height * 3];
// unfortunately we have to put the data into a format that OpenGL can read. This is a TODO:?
data = new unsigned char[(unsigned long) (width) * (unsigned long) height * 3];
int pixelIndex = 0;
// slightly different order from STBi
for (int j = 0; j < height; j++) {

View File

@ -5,7 +5,7 @@
#include <graphics/graphics.h>
#include <chrono>
#include <graphics/gl/gl.h>
#include "engine/image/stb_image.h"
#include "engine/image/stb/stb_image.h"
#include "graphics/debug_gui.h"
#include <engine/util/std.h>
@ -62,6 +62,7 @@ namespace Raytracing {
}
#ifdef USE_GLFW
XWindow::XWindow(int width, int height):
m_displayWidth(width), m_displayHeight(height) {
// OpenGL 4.6 is like 5 years old at this point and most systems support it
@ -75,9 +76,11 @@ namespace Raytracing {
glfwWindowHint(GLFW_DECORATED, GL_TRUE);
glfwWindowHint(GLFW_FOCUSED, GL_TRUE);
glfwSetErrorCallback([](int error_code, const char* description) -> void {
elog << "GLFW Error: " << error_code << "\n\t" << description << "\n";
});
glfwSetErrorCallback(
[](int error_code, const char* description) -> void {
elog << "GLFW Error: " << error_code << "\n\t" << description << "\n";
}
);
if (!glfwInit())
throw std::runtime_error("Unable to init GLFW!\n");
@ -102,23 +105,29 @@ namespace Raytracing {
stbi_image_free(imageData32.pixels);
glfwSetKeyCallback(window, [](GLFWwindow* _window, int key, int scancode, int action, int mods) -> void {
if (action == GLFW_PRESS)
Input::keyPressed(key);
else if (action == GLFW_RELEASE)
Input::keyReleased(key);
});
glfwSetKeyCallback(
window, [](GLFWwindow* _window, int key, int scancode, int action, int mods) -> void {
if (action == GLFW_PRESS)
Input::keyPressed(key);
else if (action == GLFW_RELEASE)
Input::keyReleased(key);
}
);
glfwSetMouseButtonCallback(window, [](GLFWwindow* _window, int button, int action, int mods) -> void {
if (action == GLFW_PRESS)
Input::mousePressed(button);
else if (action == GLFW_RELEASE)
Input::mouseReleased(button);
});
glfwSetMouseButtonCallback(
window, [](GLFWwindow* _window, int button, int action, int mods) -> void {
if (action == GLFW_PRESS)
Input::mousePressed(button);
else if (action == GLFW_RELEASE)
Input::mouseReleased(button);
}
);
glfwSetCursorPosCallback(window, [](GLFWwindow* _window, double x, double y) -> void {
Input::moveMove(x, y);
});
glfwSetCursorPosCallback(
window, [](GLFWwindow* _window, double x, double y) -> void {
Input::moveMove(x, y);
}
);
IMGUI_CHECKVERSION();
ImGui::CreateContext();
@ -137,6 +146,7 @@ namespace Raytracing {
glfwShowWindow(window);
ilog << "Loaded GL" << GLAD_VERSION_MAJOR(version) << "." << GLAD_VERSION_MINOR(version) << "!\n";
}
void XWindow::closeWindow() {
if (isCloseRequested)
return;
@ -149,6 +159,7 @@ namespace Raytracing {
glfwDestroyWindow(window);
glfwTerminate();
}
void XWindow::beginUpdate() {
// check for window events
isCloseRequested = glfwWindowShouldClose(window);
@ -168,6 +179,7 @@ namespace Raytracing {
ImGui::ShowDemoWindow(nullptr);
}
void XWindow::endUpdate() {
// Render ImGUI
ImGui::Render();
@ -183,6 +195,7 @@ namespace Raytracing {
frameTimeS = delta / 1000000000.0;
fps = 1000 / frameTimeMs;
}
#else
XWindow::XWindow(int width, int height): m_width(width), m_height(height) {
// open the DEFAULT display. We don't want to open a specific screen as that is annoying.
@ -466,13 +479,16 @@ namespace Raytracing {
XCloseDisplay(display);
}
#endif
XWindow::~XWindow() {
closeWindow();
deleteKeys();
}
void XWindow::setMouseGrabbed(bool grabbed) {
glfwSetInputMode(window, GLFW_CURSOR, grabbed ? GLFW_CURSOR_DISABLED : GLFW_CURSOR_NORMAL);
}
bool XWindow::isMouseGrabbed() {
return glfwGetInputMode(window, GLFW_CURSOR) == GLFW_CURSOR_DISABLED;
}
@ -539,33 +555,37 @@ namespace Raytracing {
if (Input::isKeyDown(GLFW_KEY_ESCAPE) && Input::isState(GLFW_KEY_ESCAPE))
m_window.setMouseGrabbed(!m_window.isMouseGrabbed());
DebugUI::render([this]() -> void {
if (ImGui::Button("Start") && !started) {
started = true;
RTSignal->haltRaytracing = false;
ilog << "Running raycaster!\n";
// we don't actually have to check for --single since it's implied to be default true.
int threads = std::stoi(m_parser.getOptionValue("--threads"));
if (m_parser.hasOption("--mpi")) {
//m_raycaster.runMPI(raycaster.partitionScreen());
} else if (m_parser.hasOption("--openmp")) {
m_raycaster.runOpenMP(threads);
} else {
m_raycaster.runSTDThread(threads);
DebugUI::render(
[this]() -> void {
if (ImGui::Button("Start") && !started) {
started = true;
RTSignal->haltRaytracing = false;
ilog << "Running raycaster!\n";
// we don't actually have to check for --single since it's implied to be default true.
int threads = 1;
if (m_parser.hasOption("--multi"))
threads = std::stoi(m_parser.getOptionValue("--threads"));
if (m_parser.hasOption("--mpi")) {
//m_raycaster.runMPI(raycaster.partitionScreen());
} else if (m_parser.hasOption("--openmp")) {
m_raycaster.runOpenMP(threads);
} else {
m_raycaster.runSTDThread(threads);
}
}
if (ImGui::Checkbox("Pause", &RTSignal->pauseRaytracing)) {}
if (ImGui::Button("Stop") && started) {
RTSignal->haltRaytracing = true;
started = false;
m_raycaster.deleteThreads();
}
ImGui::NewLine();
ImGui::InputInt("Max Ray Bounce", &maxRayBounce);
ImGui::InputInt("Rays Per Pixel", &raysPerPixel);
m_raycaster.updateRayInfo(maxRayBounce, raysPerPixel);
ImGui::Checkbox("Debug", &debug);
}
}
if (ImGui::Checkbox("Pause", &RTSignal->pauseRaytracing)) {}
if (ImGui::Button("Stop") && started) {
RTSignal->haltRaytracing = true;
started = false;
m_raycaster.deleteThreads();
}
ImGui::NewLine();
ImGui::InputInt("Max Ray Bounce", &maxRayBounce);
ImGui::InputInt("Rays Per Pixel", &raysPerPixel);
m_raycaster.updateRayInfo(maxRayBounce, raysPerPixel);
ImGui::Checkbox("Debug", &debug);
});
);
// we want to be able to move around, and the camera matrix functions automatically recalculate image region & projection data.
if (m_parser.hasOption("--gpu")) {
@ -594,7 +614,7 @@ namespace Raytracing {
m_worldShader.setMatrix("viewMatrix", matrices.second);
m_worldShader.use();
auto objs = m_world.getObjectsInWorld();
for (auto obj: objs) {
for (auto obj : objs) {
if (obj->getVAO() != nullptr) {
obj->getVAO()->bind();
obj->getVAO()->draw(m_worldShader, {obj->getPosition()});

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

44
test.txt Normal file
View File

@ -0,0 +1,44 @@
Step 3/include/engine/config.h.in
Step 3/include/engine/image/image.h
Step 3/include/engine/math/bvh.h
Step 3/include/engine/math/colliders.h
Step 3/include/engine/math/vectors.h
Step 3/include/engine/mpi.h
Step 3/include/engine/raytracing.h
Step 3/include/engine/types.h
Step 3/include/engine/util/debug.h
Step 3/include/engine/util/loaders.h
Step 3/include/engine/util/logging.h
Step 3/include/engine/util/memory_util.h
Step 3/include/engine/util/models.h
Step 3/include/engine/util/parser.h
Step 3/include/engine/util/std.h
Step 3/include/engine/world.h
Step 3/include/graphics/debug_gui.h
Step 3/include/graphics/gl/gl.h
Step 3/include/graphics/gl/shader.h
Step 3/include/graphics/graphics.h
Step 3/include/graphics/input.h
Step 3/include/graphics/keys.h
Step 3/include/opencl/cl.h
Step 3/include/opencl/open_ray_tracing.h
Step 3/src/engine/globals.cpp
Step 3/src/engine/image/image.cpp
Step 3/src/engine/main.cpp
Step 3/src/engine/math/bvh.cpp
Step 3/src/engine/math/colliders.cpp
Step 3/src/engine/mpi.cpp
Step 3/src/engine/raytracing.cpp
Step 3/src/engine/util/debug.cpp
Step 3/src/engine/util/loaders.cpp
Step 3/src/engine/util/models.cpp
Step 3/src/engine/util/parser.cpp
Step 3/src/engine/world.cpp
Step 3/src/graphics/debug_gui.cpp
Step 3/src/graphics/gl/gl.c
Step 3/src/graphics/gl/gl.cpp
Step 3/src/graphics/gl/shader.cpp
Step 3/src/graphics/graphics.cpp
Step 3/src/graphics/input.cpp
Step 3/src/opencl/cl.cpp
Step 3/src/opencl/open_ray_tracing.cpp

42
test2.txt Normal file
View File

@ -0,0 +1,42 @@
Step 3/include/engine/image/image.h
Step 3/include/engine/math/bvh.h
Step 3/include/engine/math/colliders.h
Step 3/include/engine/math/vectors.h
Step 3/include/engine/mpi.h
Step 3/include/engine/raytracing.h
Step 3/include/engine/types.h
Step 3/include/engine/util/debug.h
Step 3/include/engine/util/loaders.h
Step 3/include/engine/util/logging.h
Step 3/include/engine/util/memory_util.h
Step 3/include/engine/util/models.h
Step 3/include/engine/util/parser.h
Step 3/include/engine/util/std.h
Step 3/include/engine/world.h
Step 3/include/graphics/debug_gui.h
Step 3/include/graphics/gl/gl.h
Step 3/include/graphics/gl/shader.h
Step 3/include/graphics/graphics.h
Step 3/include/graphics/input.h
Step 3/include/graphics/keys.h
Step 3/include/opencl/cl.h
Step 3/include/opencl/open_ray_tracing.h
Step 3/src/engine/globals.cpp
Step 3/src/engine/image/image.cpp
Step 3/src/engine/main.cpp
Step 3/src/engine/math/bvh.cpp
Step 3/src/engine/math/colliders.cpp
Step 3/src/engine/mpi.cpp
Step 3/src/engine/raytracing.cpp
Step 3/src/engine/util/debug.cpp
Step 3/src/engine/util/loaders.cpp
Step 3/src/engine/util/models.cpp
Step 3/src/engine/util/parser.cpp
Step 3/src/engine/world.cpp
Step 3/src/graphics/debug_gui.cpp
Step 3/src/graphics/gl/gl.cpp
Step 3/src/graphics/gl/shader.cpp
Step 3/src/graphics/graphics.cpp
Step 3/src/graphics/input.cpp
Step 3/src/opencl/cl.cpp
Step 3/src/opencl/open_ray_tracing.cpp