Jackalope / jen (public) (License: GPLv3 or later version) (since 2018-10-24) (hash sha1)
----> ABOUT:

3D rendering and computing framework based on Vulkan API.

Libraries:
- simdcpp submodule (see my simdcpp repo)
- jmath submodule (see my jmath repo)
- mesh (constexpr generation of cubes, spheres, icosahedrons subdivisions)
- atlas (1D lines and 2D rectangles cutting)
- jlib submodule (see my jlib repo)
- jrf submodule (see my jrf repo)
- vkw (Vulkan API C++ wrapper)
Modules:
- compute (run compute shaders on gpu)
- graphics (draw models with clustered forward rendering and onscreen text)
- resource manager (load meshes, models, textures, scene data from
files and create related objects in graphics module)

----> INSTALLING:

To download all the parts of this framework it's enough to launch
git clone with recursive flag:

$ git clone —recursive ssh://rocketgit@ssh.rocketgit.com/user/Jackalope/jen

After this look at git tags:

$ git tag

It is recommended to use a tagged version instead of the latest commit,
because the first commit after the tagged one mostly includes incompatible
parts of future changes for the next version.

$ git checkout v0.1.0

----> DEPENDENCIES:

To use JEN as CMake subdirectory and successfully build programs with it
you need to make sure you have all of its dependencies:
- compiler: Clang or GCC, support for C++17. Clang 10+ or GCC 9+ is recommended,
compiling on Windows OS is tricky and requires something like MinGW with MSYS,
there are also some complications to go through to make dependencies work;
- GLFW3 library, supported version is 3.2.1;
- FreeType library, if graphics module will be used;
- Vulkan API headers, and optional validation layers to debug sneaky problems,
you also need Vulkan support in your graphics driver to run compiled programs;
- LibZip can be necessary, if JRF is used to read zip files;
- CMake, for obvious reasons;
- glslangValidator to compile shader for the graphics module.

CMake must be able to find GLFW3, Vulkan and FreeType (for graphics)
with find_package().

----> HOW TO USE IT:

To use JEN, you need to add it as a subdirectory:

add_subdirecroty(${PATH_TO_JEN})

There are several configuration options:
- JEN_MODULE_COMPUTE - turn compute module on for compiling and including;
- JEN_MODULE_GRAPHICS - turn graphics module on ...;
- JEN_MULTITHREADED_DRAW_FRAME - draw_frame function will use thread pool queue
instead of linear executing;
- JEN_MODULE_RESOURCE_MANAGER - resource manager module ON, if graphics is ON;
- JEN_VLK_VALIDATION - enable Vulkan Validation Layers to debug some errors
related to JEN. This will often produce false-positive,
as well as true-positive errors.

Look in CMakeLists.txt at JenExamples repo for details on how to use and
configure JEN automatically:

$ git clone ssh://rocketgit@ssh.rocketgit.com/user/Jackalope/JenExamples

Also I recommend to compile and run examples to make sure it works correctly.

----> SUPPORTED HARDWARE:

JEN has not been tested well, because it requires running it on large amount of
different hardware to do so. It must work with mesa driver and modern
Intel i965 GPUs as well as AMD GPUs.


----> DOCUMENTATION:

You can generate Doxygen documentation, to do so
turn on any of JEN_DOXYGEN_* options and run documentation target in cmake:

$ cmake -G %1 -DJEN_DOXYGEN_HTML=ON -DJEN_DOXYGEN_LATEX=ON
$ cmake —build —target documentation

Resource manager is not documented because it still requires large enhancements.
List of commits:
Subject Hash Author Date (UTC)
Window improvements. scroll_diff and cursor_diff members. Update noclip screen. 8d659590a0fb52e1e24683305a7ee8699bdff6da Jackalope 2020-06-01 01:30:50
Update jlib 0.4.1 Update jrf 0.2.2 d36e5263523a9b0443476b2db8d856e86086af81 Jackalope 2020-05-31 23:58:41
Update jmath 0.1.2. 8d3566336ef87f73318e84cde87bdf841240dcdc Jackalope 2020-05-31 23:57:25
Use scanf instead of fgets for interactive device selection. fd7ff8b61ef1e21852d6c0a15ab0d17d09c5cccc Jackalope 2020-05-31 23:56:34
Include FreeType as system library to prevent warnings. dc92c7f8acdaa90b25cf272f1730d338111780fc Jackalope 2020-05-31 23:54:37
Add glfw required version. 3.3.1 is not working. ee727d7efda88af1e8a227b542f5b79d0ba6f301 Jackalope 2020-05-31 23:53:33
GCC Compatibility. c828a38456627d0383d431165b802f97fd303349 Jackalope 2020-05-29 16:48:24
Solved clang compiler warnings from compute module. b9416237761f8648bbddb7e7ba59e833a7879528 Jackalope 2020-05-28 11:09:55
CMake: two shaders targets, instead of single target per shader. a708650319e44c7b98056f3bc85a896dd65d96f3 Jackalope 2020-05-28 11:06:13
Reduced amount of warnings. 18bf33ca4e0e7f0369f6b5fdc59b81a8420dde8e Jackalope 2020-05-27 15:11:37
Replace jl::rarray with generic structure in shader header file. 1cedb5886becc0f70c19d1c649e96f7eac5e0037 Jackalope 2020-05-27 13:07:31
Embedding shaders in obj library. e877e7a688ee4a899480c12acba55c340622f993 Jackalope 2020-05-27 12:40:34
Update jlib 0.3.0 (refactoring of threads, new thread pool). 1c713a320ced91d0ad5f1606c39f1187871d28e5 Jackalope 2020-05-26 14:44:35
Update graphics after change of "wait for monitor" flag. 29d9b749c803646006b9b0071b54256bd3c08ca8 Jackalope 2020-05-26 14:40:34
reduced number of -Wno* warnings bf3ec94ce3020715e246107a47efc9a8772db382 Jackalope 2020-05-25 01:48:40
Disable "find_package(jlib 0.2.0 REQUIRED)" in jrf b4903e20d9128227163119fe73e32cda5050cb67 Jackalope 2020-05-24 16:40:26
Update jrf-0.2.1 3518adb37045d4e4eb4488c8c07e3f674f5fbac3 Jackalope 2020-05-24 14:33:14
Update jrf-0.2.0 8720e50ca5f692a96ba764cab1a250683c6a0c59 Jackalope 2020-05-24 13:42:55
Update jlib-0.2.0 98c73665c12797a530d12e34dc764e72a8767ad1 Jackalope 2020-05-24 00:32:02
Mistake in CMake option 112275a2e0bc8619612ab49d808daeeeb599b8de Jackalope 2020-05-24 00:11:04
Commit 8d659590a0fb52e1e24683305a7ee8699bdff6da - Window improvements. scroll_diff and cursor_diff members. Update noclip screen.
Author: Jackalope
Author date (UTC): 2020-06-01 01:30
Committer name: Jackalope
Committer date (UTC): 2020-06-01 01:31
Parent(s): d36e5263523a9b0443476b2db8d856e86086af81
Signing key:
Tree: 62e7c3b6328f15e9d134280b40825219d542b8c3
File Lines added Lines deleted
include/jen/screen.h 18 20
include/jen/window.h 14 7
src/instance/instance.cpp 11 2
File include/jen/screen.h changed (mode: 100644) (index ff80850..e60d4d6)
... ... struct jen::screen::Noclip
43 43 /// @param move_spd Initial movement speed per second /// @param move_spd Initial movement speed per second
44 44 /// @param window Used to access user input /// @param window Used to access user input
45 45 void init(const Window &window, float view_sens, float move_spd) { void init(const Window &window, float view_sens, float move_spd) {
46 this->cursor_pos = window.cursor;
47 46 camera.position = {}; camera.position = {};
48 47 camera.pos_offset = {}; camera.pos_offset = {};
49 48 camera.offset_shift = {}; camera.offset_shift = {};
 
... ... struct jen::screen::Noclip
53 52 frustum.zNear = 0.5; frustum.zNear = 0.5;
54 53 frustum.zFar = 32000; frustum.zFar = 32000;
55 54 view_sensitivity = view_sens; view_sensitivity = view_sens;
55 speed_sensitivity = 0.05f;
56 56 move_speed = move_spd; move_speed = move_spd;
57 57 } }
58 58 /// @brief Update camera state from user input and also aspect ratio. /// @brief Update camera state from user input and also aspect ratio.
59 59 /// Controls: /// Controls:
60 60 /// - 'Q' and 'E' rotate camera around lookat vector /// - 'Q' and 'E' rotate camera around lookat vector
61 61 /// - 'W'A'S'D' to move forward, left, back and right /// - 'W'A'S'D' to move forward, left, back and right
62 /// - '=' to increase moving speed
63 /// - '-' to decrease moving speed
62 /// - scroll to modify moving speed
64 63 /// - 'z' to multiply the clipping plane /// - 'z' to multiply the clipping plane
65 64 /// - 'x' to divide clipping plane /// - 'x' to divide clipping plane
66 65 /// - horizontal mouse movement to rotate the camera left or right, /// - horizontal mouse movement to rotate the camera left or right,
 
... ... struct jen::screen::Noclip
85 84 sign = get_sign(window.is_on(Key::A), window.is_on(Key::D)); sign = get_sign(window.is_on(Key::A), window.is_on(Key::D));
86 85 if (sign != 0) if (sign != 0)
87 86 camera.position -= camera.axis.x * elapsed_secs * move_speed * sign; camera.position -= camera.axis.x * elapsed_secs * move_speed * sign;
88 if (window.is_on(Key::kEQUAL))
89 move_speed *= 1 + (3.5f * elapsed_secs);
90 if (window.is_on(Key::kMINUS))
91 move_speed /= 1 + (3.5f * elapsed_secs);
87
92 88 if (window.is_on(Key::Z)) { if (window.is_on(Key::Z)) {
93 89 frustum.zNear *= 1 + (1.4f * elapsed_secs); frustum.zNear *= 1 + (1.4f * elapsed_secs);
94 90 frustum.zFar *= 1 + (1.4f * elapsed_secs); frustum.zFar *= 1 + (1.4f * elapsed_secs);
 
... ... struct jen::screen::Noclip
97 93 frustum.zNear /= 1 + (1.4f * elapsed_secs); frustum.zNear /= 1 + (1.4f * elapsed_secs);
98 94 frustum.zFar /= 1 + (1.4f * elapsed_secs); frustum.zFar /= 1 + (1.4f * elapsed_secs);
99 95 } }
96
100 97 frustum.set_aspect(window.extent.x, window.extent.y); frustum.set_aspect(window.extent.x, window.extent.y);
101 if (window.cursor != cursor_pos) {
102 auto cursor_diff = jm::v2f::from(window.cursor - cursor_pos);
103 cursor_diff *= view_sensitivity;
104 camera.axis.z = jm::rotation(camera.axis.y, cursor_diff.x)
105 * camera.axis.z;
106 camera.axis.x = jm::cross(camera.axis.y, camera.axis.z).normalized();
107 98
108 camera.axis.y = jm::rotation(camera.axis.x, -cursor_diff.y)
109 * camera.axis.y;
110 camera.axis.z = jm::cross(camera.axis.x, camera.axis.y).normalized();
99 move_speed += std::numeric_limits<double>::epsilon();
100 move_speed *= 1 + (speed_sensitivity * -window.scroll_diff.y);
101
102 auto cursor_diff = jm::v2f::from(window.cursor_diff);
103 cursor_diff *= view_sensitivity;
104 camera.axis.z = jm::rotation(camera.axis.y, cursor_diff.x)
105 * camera.axis.z;
106 camera.axis.x = jm::cross(camera.axis.y, camera.axis.z).normalized();
107
108 camera.axis.y = jm::rotation(camera.axis.x, -cursor_diff.y)
109 * camera.axis.y;
110 camera.axis.z = jm::cross(camera.axis.x, camera.axis.y).normalized();
111 111
112 cursor_pos = window.cursor;
113 }
114 112 camera.stash_to_shift(); camera.stash_to_shift();
115 113 } }
116 /// Last known cursor position
117 jm::v2f64 cursor_pos;
118 114 /// Rotation radians per second per cursor pixel /// Rotation radians per second per cursor pixel
119 115 float view_sensitivity; float view_sensitivity;
116 /// Speed multiplier per scroll "tick"
117 float speed_sensitivity;
120 118 /// Movement speed per second /// Movement speed per second
121 119 float move_speed; float move_speed;
122 120 /// @see Camera /// @see Camera
File include/jen/window.h changed (mode: 100644) (index a938b96..c4f3d0e)
... ... struct jen::Window
37 37 HIDDEN = GLFW_CURSOR_HIDDEN, HIDDEN = GLFW_CURSOR_HIDDEN,
38 38 DISABLED = GLFW_CURSOR_DISABLED DISABLED = GLFW_CURSOR_DISABLED
39 39 }; };
40 /// @brief Cursor is just a 2D position vector.
41 using Cursor = jm::v2f64;
42 40 /// @brief Extent is 2D size vector. /// @brief Extent is 2D size vector.
43 using Extent = jm::vec2<int>;
41 using Extent = jm::v2i32;
44 42 /// @brief "I DON'T CARE SIZE". /// @brief "I DON'T CARE SIZE".
45 43 constexpr static const Extent ExtentAny = { GLFW_DONT_CARE, GLFW_DONT_CARE }; constexpr static const Extent ExtentAny = { GLFW_DONT_CARE, GLFW_DONT_CARE };
46 44 /// @brief Set Window visible or invisible. /// @brief Set Window visible or invisible.
 
... ... struct jen::Window
82 80 /// @brief Update user input and window state. /// @brief Update user input and window state.
83 81 /// Recommended for realtime application /// Recommended for realtime application
84 82 /// @see glfwPollEvents /// @see glfwPollEvents
85 static void poll() {
83 void poll() {
84 scroll_diff = {};
85 cursor_diff = {};
86 86 glfwPollEvents(); glfwPollEvents();
87 87 } }
88 88 /// @brief Wait untill user input or window state will be changed. /// @brief Wait untill user input or window state will be changed.
89 89 /// Same as glfwPollEvents, but it will wait for something to update. /// Same as glfwPollEvents, but it will wait for something to update.
90 90 /// Recommended for interactive window usage /// Recommended for interactive window usage
91 91 /// @see glfwWaitEvents /// @see glfwWaitEvents
92 static void wait() {
92 void wait() {
93 scroll_diff = {};
94 cursor_diff = {};
93 95 glfwWaitEvents(); glfwWaitEvents();
94 96 } }
95 97 /// @brief Check if user wants to close the window. /// @brief Check if user wants to close the window.
 
... ... struct jen::Window
183 185 /// and framebuffer must be drawn again /// and framebuffer must be drawn again
184 186 bool is_damaged; bool is_damaged;
185 187 /// User cursor position /// User cursor position
186 Cursor cursor;
188 jm::v2f64 cursor;
189 // Cursor offset between event polls
190 jm::v2f64 cursor_diff;
191 // Scroll offset between event polls
192 jm::v2f64 scroll_diff;
187 193 }; };
188 194 /// @brief Button state helper. /// @brief Button state helper.
189 195 struct jen::Button { struct jen::Button {
 
... ... struct jen::Button {
192 198 /// @param w window handle to get input from /// @param w window handle to get input from
193 199 /// @return If button is pressed, it returns true. If button was not released /// @return If button is pressed, it returns true. If button was not released
194 200 /// and this function is called again than it will return false. /// and this function is called again than it will return false.
195 [[nodiscard]] bool is_fired(Key::Board key, const Window &w) {
201 template<typename K>
202 [[nodiscard]] bool is_fired(K key, const Window &w) {
196 203 Key::State new_state = w.state(key); Key::State new_state = w.state(key);
197 204 if (new_state != state) { if (new_state != state) {
198 205 bool is_fired = new_state == Key::State::ON; bool is_fired = new_state == Key::State::ON;
File src/instance/instance.cpp changed (mode: 100644) (index 7ea62aa..b9fcffa)
... ... using Window = jen::Window;
47 47 init_window(Window *p, Window::Extent extent, init_window(Window *p, Window::Extent extent,
48 48 const char* title, bool is_visible) { const char* title, bool is_visible) {
49 49 p->is_visible = is_visible; p->is_visible = is_visible;
50 p->extent = extent;
50 p->extent = extent;
51 p->cursor = {};
52 p->scroll_diff = {};
53 p->cursor_diff = {};
51 54
52 55 p->is_iconified = false; p->is_iconified = false;
53 56 p->is_visible = true; p->is_visible = true;
 
... ... init_window(Window *p, Window::Extent extent,
94 97 }); });
95 98 glfwSetCursorPosCallback(p->p_window, [](GLFWwindow *p_w, double x, double y){ glfwSetCursorPosCallback(p->p_window, [](GLFWwindow *p_w, double x, double y){
96 99 auto &win = *reinterpret_cast<Window*>(glfwGetWindowUserPointer(p_w)); auto &win = *reinterpret_cast<Window*>(glfwGetWindowUserPointer(p_w));
97 win.cursor = {x, y};
100 jm::v2f64 pos = {x, y};
101 win.cursor_diff = pos - win.cursor;
102 win.cursor = pos;
103 });
104 glfwSetScrollCallback(p->p_window, [](GLFWwindow *p_w, double x, double y){
105 auto &win = *reinterpret_cast<Window*>(glfwGetWindowUserPointer(p_w));
106 win.scroll_diff = jm::v2f64{x, y};
98 107 }); });
99 108
100 109 glfwGetCursorPos(p->p_window, &p->cursor.x, &p->cursor.y); glfwGetCursorPos(p->p_window, &p->cursor.x, &p->cursor.y);
Hints:
Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://rocketgit.com/user/Jackalope/jen

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@ssh.rocketgit.com/user/Jackalope/jen

Clone this repository using git:
git clone git://git.rocketgit.com/user/Jackalope/jen

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a merge request:
... clone the repository ...
... make some changes and some commits ...
git push origin main