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)
moved window to jen namespace, moved settings update to settings member function 1541c40679cfc28f2d0f173499196f458a11f952 Jackalope 2020-05-09 17:07:23
more configuration options b4e5770306ccb9c49fa4c348a670c901a7c98047 Jackalope 2020-05-09 16:14:40
libs update 7caad27c596db2e8d84e44cdc5c0ddeb1730c20d Jackalope 2020-05-08 23:37:50
compute wait flags bug fix f13273d79b899ee717b69f6d4a745c33f7589bbe Jackalope 2020-05-08 23:37:39
improvements for previous commit changes 994a9c60c1598862b80e0480ca65a8f527e07a07 Jackalope 2020-05-08 22:40:36
huge jen interface refactoring, added configuration options fabb80119c23c204118af1f4f697e74e8cbd61b8 Jackalope 2020-05-08 21:59:31
added settings, changed some namespaces and type names f0766a6b35304740cb39f93e601447ad7be7e143 Jackalope 2020-05-07 23:48:11
compute storage image support eaffc4ea4768fb67f063102793ca5d781bafb0c8 Jackalope 2020-05-04 17:48:33
get size of vkFormat pixel function 41e309467955bc2e1361a1f9689367f961040bf7 Jackalope 2020-05-04 17:48:08
vkw image to buffer copy 57234d0007df737094aef5b6bab4177ca39bb347 Jackalope 2020-05-04 17:47:08
added flag to wait events instead of polling for interactive apps b9cfe8faa84e5bfc00aa842b16819b28f5e2be10 Jackalope 2020-05-04 17:45:34
added compute info validation 7cd15af2afd064302703eccd1094f4353da35c4f Jackalope 2020-04-26 08:05:18
fixed uninitialized value 8313a622987f51e74b068231cddde3ff34a93625 Jackalope 2020-04-26 08:04:48
disable checking present support when graphics module not loaded b2ff208cef191444cd995c40989c6b9414c1fb9f Jackalope 2020-04-26 02:35:19
added debug extension loading when graphics module is disabled 54bc7c5eff1353559ec29e560a4095cfa9ef33d8 Jackalope 2020-04-26 02:32:45
Noise library: removed excess commentary lines 6b518ad33508161bd0cc8790eb13f4d03d827acc TheArtOfGriefing 2020-04-23 20:56:55
Noise library: added forgotten hash function use in gradient computation. bfce031f8de0410107aaf33009b46e455acd5095 TheArtOfGriefing 2020-04-23 18:40:05
Noise library update: +6 hash functions +1D,2D,3D,4D highly optimized simplex noise +1D,2D,3D,4D white noise 731cba496cf3c253ad365355faae9df45e1e714e TheArtOfGriefing 2020-04-23 17:37:19
simd library moved to simdcpp submodule, also updates to match new version 36fa65052847fbb258e0ceaf2a2c3fab40e5c3a7 Jackalope 2020-04-21 23:19:24
jlib update d7d711f8b289b2a84e58c66d20c0871c21d17350 Jackalope 2020-04-15 09:54:57
Commit 1541c40679cfc28f2d0f173499196f458a11f952 - moved window to jen namespace, moved settings update to settings member function
Author: Jackalope
Author date (UTC): 2020-05-09 17:07
Committer name: Jackalope
Committer date (UTC): 2020-05-09 17:07
Parent(s): b4e5770306ccb9c49fa4c348a670c901a7c98047
Signer:
Signing key:
Signing status: N
Tree: 109952fd92b4c95c3023d4a6b6c367f99417955d
File Lines added Lines deleted
include/jen/graphics.h 3 2
include/jen/settings.h 35 24
include/jen/window.h 2 1
src/framework.cpp 1 1
src/graphics/graphics_interface.cpp 24 22
File include/jen/graphics.h changed (mode: 100644) (index 67bdb8f..c102cf1)
7 7 #include "light.h" #include "light.h"
8 8 #include "resources.h" #include "resources.h"
9 9 #include "result.h" #include "result.h"
10 #include "settings.h"
10 11 #include <jlib/time.h> #include <jlib/time.h>
11 12 #include <jrf/image.h> #include <jrf/image.h>
12 13
 
... ... namespace jen {
17 18 } }
18 19 struct jen::ModuleGraphics struct jen::ModuleGraphics
19 20 { {
20 [[nodiscard]] Result apply_settings();
21 [[nodiscard]] Result apply_settings(const GraphicsSettings &settings);
22
21 23 void apply_camera(const Camera&, const Frustum&); void apply_camera(const Camera&, const Frustum&);
22 24 void apply_light_shadow(const Light&); void apply_light_shadow(const Light&);
23 25 void apply_lights(LightsDraw *p_lights); void apply_lights(LightsDraw *p_lights);
 
... ... struct jen::ModuleGraphics
52 54
53 55 [[nodiscard]] Result draw_frame(const jl::rarray<const Model> &models); [[nodiscard]] Result draw_frame(const jl::rarray<const Model> &models);
54 56
55 [[nodiscard]] Result update_settings_from_input();
56 57
57 58 using PF_User = void(*)(void*); using PF_User = void(*)(void*);
58 59
File include/jen/settings.h changed (mode: 100644) (index c24770b..7523f3f)
1 1 #pragma once #pragma once
2 2 #include "controls.h" #include "controls.h"
3 #include <memory>
3 #include "result.h"
4 #include "configuration.h"
4 5
5 6 namespace jen { namespace jen {
6 7 struct ApplicationSettings; struct ApplicationSettings;
7 8 struct ThreadPoolSettings; struct ThreadPoolSettings;
8 9 struct WindowSettings; struct WindowSettings;
10 #if JEN_MODULE_GRAPHICS
9 11 struct GraphicsSettings; struct GraphicsSettings;
12 #endif
13 struct Window;
10 14
11 15 namespace ModulesFlag { enum T : uint32_t { namespace ModulesFlag { enum T : uint32_t {
12 16 COMPUTE = 1, COMPUTE = 1,
 
... ... struct jen::WindowSettings {
45 49 const char *p_title_str; const char *p_title_str;
46 50 }; };
47 51
52 #if JEN_MODULE_GRAPHICS
48 53 struct jen::GraphicsSettings struct jen::GraphicsSettings
49 54 { {
50 struct DebugOverlay {
51 bool is_enabled;
52 bool is_visible;
53 Key::Board toggle_key;
54 const char *font_path;
55 };
56
57 55 enum class Shading : uint32_t { enum class Shading : uint32_t {
58 56 DEFAULT, DEFAULT,
59 57 NO_LIGHTING, NO_LIGHTING,
 
... ... struct jen::GraphicsSettings
62 60 DEBUG_CLUSTERS_NUM_LIGHTS, DEBUG_CLUSTERS_NUM_LIGHTS,
63 61 COUNT COUNT
64 62 }; };
65
66 enum class Filter : uint32_t { _1, _16, _25, _32, _64, _100, _128 };
67 struct Shadow {
68 float bias = 0.05f;
69 Filter pcss_search = Filter::_16;
70 Filter pcf = Filter::_32;
71 uint32_t extent = 512;
63 enum class Filter : uint32_t {
64 _1, _16, _25, _32, _64, _100, _128
72 65 }; };
73
74 66 enum class DrawMode : uint8_t { enum class DrawMode : uint8_t {
75 67 DEFAULT, WIREFRAME, POINTS DEFAULT, WIREFRAME, POINTS
76 68 }; };
 
... ... struct jen::GraphicsSettings
81 73 FRONT_AND_BACK = FRONT | BACK FRONT_AND_BACK = FRONT | BACK
82 74 }; };
83 75
76 [[nodiscard]] bool update_from_input(Window *p_window);
77
78 [[nodiscard]] bool operator ==(const GraphicsSettings& settings) const {
79 return memcmp(this, &settings, sizeof(*this)) == 0;
80 }
81 [[nodiscard]] bool operator !=(const GraphicsSettings& settings) const {
82 return not operator==(settings);
83 }
84
85 struct DebugOverlay {
86 bool is_enabled;
87 bool is_visible;
88 Key::Board toggle_key;
89 const char *font_path;
90 };
91 struct Shadow {
92 float bias = 0.05f;
93 Filter pcss_search = Filter::_16;
94 Filter pcf = Filter::_32;
95 uint32_t extent = 512;
96 };
97
84 98 Shading shading = Shading::DEFAULT; Shading shading = Shading::DEFAULT;
85 99 Shadow shadows; Shadow shadows;
86 100 DrawMode draw_mode; DrawMode draw_mode;
 
... ... struct jen::GraphicsSettings
92 106 bool is_debug_normals_visible; bool is_debug_normals_visible;
93 107 bool is_debug_depth_cube_visible; bool is_debug_depth_cube_visible;
94 108 DebugOverlay debug_overlay; DebugOverlay debug_overlay;
95
96 [[nodiscard]] bool operator ==(const GraphicsSettings& settings) const {
97 return memcmp(this, &settings, sizeof(*this)) == 0;
98 }
99 [[nodiscard]] bool operator !=(const GraphicsSettings& settings) const {
100 return not operator==(settings);
101 }
102 109 }; };
110 #endif
103 111
104 112 struct jen::Settings { struct jen::Settings {
105 113 constexpr void constexpr void
 
... ... struct jen::Settings {
111 119 thread_pool.queue_indices.drawFrame = 0; thread_pool.queue_indices.drawFrame = 0;
112 120
113 121 window.p_title_str = ""; window.p_title_str = "";
114
122 #if JEN_MODULE_GRAPHICS
115 123 graphics.draw_mode = GraphicsSettings::DrawMode::DEFAULT; graphics.draw_mode = GraphicsSettings::DrawMode::DEFAULT;
116 124 graphics.cull_mode = GraphicsSettings::CullMode::BACK; graphics.cull_mode = GraphicsSettings::CullMode::BACK;
117 125 graphics.shading = GraphicsSettings::Shading::DEFAULT; graphics.shading = GraphicsSettings::Shading::DEFAULT;
 
... ... struct jen::Settings {
130 138 graphics.debug_overlay.is_visible = false; graphics.debug_overlay.is_visible = false;
131 139 graphics.debug_overlay.toggle_key = Key::Board::f1; graphics.debug_overlay.toggle_key = Key::Board::f1;
132 140 graphics.debug_overlay.font_path = "fonts//IBMPlexMono.ttf"; graphics.debug_overlay.font_path = "fonts//IBMPlexMono.ttf";
141 #endif
133 142 } }
134 143 [[nodiscard]] constexpr static Settings [[nodiscard]] constexpr static Settings
135 144 get_default(const ApplicationSettings &app_settings) { get_default(const ApplicationSettings &app_settings) {
 
... ... struct jen::Settings {
141 150 ApplicationSettings application; ApplicationSettings application;
142 151 ThreadPoolSettings thread_pool; ThreadPoolSettings thread_pool;
143 152 WindowSettings window; WindowSettings window;
153 #if JEN_MODULE_GRAPHICS
144 154 GraphicsSettings graphics; GraphicsSettings graphics;
155 #endif
145 156 }; };
File include/jen/window.h changed (mode: 100644) (index 58723eb..f52cef9)
3 3 #include <math/vector.h> #include <math/vector.h>
4 4 #include <vkw/surface.h> #include <vkw/surface.h>
5 5
6 struct Window
6 namespace jen { struct Window; }
7 struct jen::Window
7 8 { {
8 9 enum class CursorMode { enum class CursorMode {
9 10 NORMAL = GLFW_CURSOR_NORMAL, NORMAL = GLFW_CURSOR_NORMAL,
File src/framework.cpp changed (mode: 100644) (index 385c744..4b5685e)
... ... void jen::Framework::destroy() {
94 94 } }
95 95 } }
96 96
97 [[nodiscard]] Window* jen::Framework::get_window() {
97 [[nodiscard]] jen::Window* jen::Framework::get_window() {
98 98 return &p_instance->window; return &p_instance->window;
99 99 } }
File src/graphics/graphics_interface.cpp changed (mode: 100644) (index f563e8e..3edca38)
... ... destroy(GpuTexture* p_gpuTexture, bool destroy_src) {
142 142 p->destroyer << p_gpuTexture; p->destroyer << p_gpuTexture;
143 143 } }
144 144
145 [[nodiscard]] Result ModuleGraphics:: apply_settings() {
146 return p->update_stages();
145 [[nodiscard]] Result ModuleGraphics::
146 apply_settings(const GraphicsSettings &settings) {
147 if (p->settings != settings) {
148 p->settings = settings;
149 return p->update_stages();
150 }
151 return VK_SUCCESS;
147 152 } }
148 153
149 154 jen::ResourceState jen::resource_state(const jen::GpuData * const p) { jen::ResourceState jen::resource_state(const jen::GpuData * const p) {
 
... ... bool call_key(Key::Board key, bool *p_pressed, const Window &input, Foo foo,
198 203 return false; return false;
199 204 } }
200 205
201 [[nodiscard]] Result ModuleGraphics::update_settings_from_input()
206 [[nodiscard]] bool GraphicsSettings::
207 update_from_input(Window *p_window)
202 208 { {
203 209 static bool is_f_pressed[Key::f12 - Key::f1 + 1]; static bool is_f_pressed[Key::f12 - Key::f1 + 1];
204 210
 
... ... bool call_key(Key::Board key, bool *p_pressed, const Window &input, Foo foo,
208 214 : Window::CursorMode::DISABLED); : Window::CursorMode::DISABLED);
209 215 }; };
210 216
211 auto p_settings = &p->settings;
212
213 auto polygon_mode = [p_settings]() {
214 auto &pm = p_settings->draw_mode;
217 auto polygon_mode = [this]() {
218 auto &pm = draw_mode;
215 219 pm = GraphicsSettings::DrawMode(int(pm) + 1); pm = GraphicsSettings::DrawMode(int(pm) + 1);
216 220 if (pm > GraphicsSettings::DrawMode::POINTS) if (pm > GraphicsSettings::DrawMode::POINTS)
217 221 pm = GraphicsSettings::DrawMode::DEFAULT; pm = GraphicsSettings::DrawMode::DEFAULT;
218 222 }; };
219 auto cull_mode = [p_settings]() {
223 auto cull_mode = [this]() {
220 224 using CM = GraphicsSettings::CullMode; using CM = GraphicsSettings::CullMode;
221 p_settings->cull_mode = p_settings->cull_mode == CM::NONE
222 ? CM::BACK : CM::NONE;
225 this->cull_mode = this->cull_mode == CM::NONE ? CM::BACK : CM::NONE;
223 226 }; };
224 auto light_mode = [p_settings]() {
227 auto light_mode = [this]() {
225 228 using Shading = jen::GraphicsSettings::Shading; using Shading = jen::GraphicsSettings::Shading;
226 auto &s = p_settings->shading;
229 auto &s = this->shading;
227 230 s = Shading(int(s) + 1); s = Shading(int(s) + 1);
228 231 if (s == Shading::COUNT) if (s == Shading::COUNT)
229 232 s = Shading::DEFAULT; s = Shading::DEFAULT;
230 233 }; };
231 auto multisampling_mode = [p_settings]() {
232 auto &m = p_settings->multisampling;
234 auto multisampling_mode = [this]() {
235 auto &m = this->multisampling;
233 236 m += m; m += m;
234 237 if (m > 8) // TODO set as hardware limits if (m > 8) // TODO set as hardware limits
235 238 m = 1; m = 1;
 
... ... bool call_key(Key::Board key, bool *p_pressed, const Window &input, Foo foo,
243 246 }; };
244 247 auto toggle = [](bool *p_d) { *p_d = not *p_d; }; auto toggle = [](bool *p_d) { *p_d = not *p_d; };
245 248
246 auto &w = p->p_instance->window;
249 auto &w = *p_window;
247 250 bool changed = false; bool changed = false;
248 call_key(p_settings->debug_overlay.toggle_key,
249 is_f_pressed, w, toggle,
250 &p_settings->debug_overlay.is_visible);
251 call_key(debug_overlay.toggle_key, is_f_pressed, w, toggle,
252 &debug_overlay.is_visible);
251 253 call_key(Key::f2, is_f_pressed, w, cursor_mode, &w); call_key(Key::f2, is_f_pressed, w, cursor_mode, &w);
252 254 changed |= call_key(Key::f3, is_f_pressed, w, toggle, changed |= call_key(Key::f3, is_f_pressed, w, toggle,
253 &p_settings->is_debug_depth_cube_visible);
255 &is_debug_depth_cube_visible);
254 256 changed |= call_key(Key::f4, is_f_pressed, w, polygon_mode); changed |= call_key(Key::f4, is_f_pressed, w, polygon_mode);
255 257 changed |= call_key(Key::f5, is_f_pressed, w, cull_mode); changed |= call_key(Key::f5, is_f_pressed, w, cull_mode);
256 258 changed |= call_key(Key::f6, is_f_pressed, w, light_mode); changed |= call_key(Key::f6, is_f_pressed, w, light_mode);
257 259 changed |= call_key(Key::f7, is_f_pressed, w, multisampling_mode); changed |= call_key(Key::f7, is_f_pressed, w, multisampling_mode);
258 260 changed |= call_key(Key::f8, is_f_pressed, w, toggle, changed |= call_key(Key::f8, is_f_pressed, w, toggle,
259 &p_settings->is_debug_normals_visible);
261 &is_debug_normals_visible);
260 262 changed |= call_key(Key::f9, is_f_pressed, w, toggle, changed |= call_key(Key::f9, is_f_pressed, w, toggle,
261 &p_settings->wait_for_monitor);
263 &wait_for_monitor);
262 264 call_key(Key::f11, is_f_pressed, w, monitor_mode, &w); call_key(Key::f11, is_f_pressed, w, monitor_mode, &w);
263 265
264 return changed ? apply_settings() : VK_SUCCESS;
266 return changed;
265 267 } }
266 268
267 269 void ModuleGraphics::Loop:: void ModuleGraphics::Loop::
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