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)
Doxygen documentation improvements 5e8201cd9a74707457ae97a10bed6681d091f10e Jackalope 2020-05-11 23:49:58
added Button state helper 15729a25a75a73f464b33e7f17d6cc7f609a3eb1 Jackalope 2020-05-11 09:05:05
bug fixes 504ff4b14e1b5a1b0cd21b10d7d867596b5b5ada Jackalope 2020-05-11 08:29:03
fixed issues with mesh lib 92c9562548dffacefaff5daadd1e39504810a633 Jackalope 2020-05-11 08:16:40
jrf update, added 2 formats to gpu_transfer b88f688303205c2e44078220f858761b84de045c Jackalope 2020-05-11 07:51:30
Doxygen documentation 34da4d6ff049e1315d58a34d8b42306dca16d89d Jackalope 2020-05-11 03:49:22
jlib update c4e0f05cd2479b8da334cd681337771dc579899d Jackalope 2020-05-09 23:32:14
math libriary update (renamed to jmath) 44798c932745bd021f5c11d018d09a055a7a1903 Jackalope 2020-05-09 19:18:59
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
Commit 5e8201cd9a74707457ae97a10bed6681d091f10e - Doxygen documentation improvements
Author: Jackalope
Author date (UTC): 2020-05-11 23:49
Committer name: Jackalope
Committer date (UTC): 2020-05-11 23:49
Parent(s): 15729a25a75a73f464b33e7f17d6cc7f609a3eb1
Signer:
Signing key:
Signing status: N
Tree: afb74a161d8b0ca6aa5b8bfb3315f4bebc9eb90d
File Lines added Lines deleted
CMakeLists.txt 1 1
include/jen/camera.h 7 7
include/jen/compute.h 28 27
include/jen/controls.h 3 3
include/jen/framework.h 4 4
include/jen/graphics.h 146 43
include/jen/light.h 5 6
include/jen/resources.h 140 49
include/jen/screen.h 9 26
include/jen/settings.h 15 15
include/jen/window.h 26 26
src/graphics/graphics.cpp 6 5
src/graphics/graphics.h 3 2
src/graphics/graphics_interface.cpp 9 14
src/graphics/resources.h 3 3
src/resource_manager/resource_manager.cpp 2 2
File CMakeLists.txt changed (mode: 100644) (index 3c11f28..64daacd)
... ... target_include_directories(ATLAS PUBLIC ${JEN_INCLUDE_DIRS})
161 161 target_include_directories(JEN PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src target_include_directories(JEN PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src
162 162 ${JEN_INCLUDE_DIRS}) ${JEN_INCLUDE_DIRS})
163 163
164 if (JEN_DOXYGEN)
164 if (JEN_DOXYGEN_HTML OR JEN_DOXYGEN_LATEX)
165 165 message(STATUS "Doxygen documentation is enabled") message(STATUS "Doxygen documentation is enabled")
166 166 find_package(Doxygen) find_package(Doxygen)
167 167 if (DOXYGEN_FOUND) if (DOXYGEN_FOUND)
File include/jen/camera.h changed (mode: 100644) (index b12e003..7b7cb55)
... ... namespace jen
13 13 /// Used for creating lookat matrix and also offsetting models position. /// Used for creating lookat matrix and also offsetting models position.
14 14 struct Camera struct Camera
15 15 { {
16 /// @brief Set axis to values that has no rotation and scaling effect
16 /// @brief Set axis to values that has no rotation and scaling effect.
17 17 [[nodiscard]] static jm::vec3<jm::v3f> default_axis() { [[nodiscard]] static jm::vec3<jm::v3f> default_axis() {
18 18 return {jm::v3f{1,0,0}, jm::v3f{0,1,0}, jm::v3f{0,0,1}}; return {jm::v3f{1,0,0}, jm::v3f{0,1,0}, jm::v3f{0,0,1}};
19 19 } }
 
... ... namespace jen
21 21 [[nodiscard]] jm::m3f axis_matrix() { [[nodiscard]] jm::m3f axis_matrix() {
22 22 return {axis.x, axis.y, axis.z}; return {axis.x, axis.y, axis.z};
23 23 } }
24 /// @brief Increase position percision by storing part of position to offset
24 /// @brief Store part of position to offset.
25 25 void stash_to_shift() { void stash_to_shift() {
26 int32_t single_value = 1 << shift_po2;
26 int32_t single_value = 1 << offset_shift;
27 27 auto multiple = jm::v3i32(position / single_value); auto multiple = jm::v3i32(position / single_value);
28 28 pos_offset += multiple; pos_offset += multiple;
29 29 position -= jm::v3f(multiple) * single_value; position -= jm::v3f(multiple) * single_value;
 
... ... namespace jen
32 32 /// Percision loss on large shift value. /// Percision loss on large shift value.
33 33 [[nodiscard]] jm::v3d world_pos() const { [[nodiscard]] jm::v3d world_pos() const {
34 34 return jm::v3d::from(position) return jm::v3d::from(position)
35 + jm::v3d::from(pos_offset) * (1 << shift_po2);
35 + jm::v3d::from(pos_offset) * (1 << offset_shift);
36 36 } }
37 37 /// C++ does not provide this by default, so ... /// C++ does not provide this by default, so ...
38 38 [[nodiscard]] bool operator == (const Camera &c) { [[nodiscard]] bool operator == (const Camera &c) {
 
... ... namespace jen
45 45 /// Position of the camera. /// Position of the camera.
46 46 /// Large values better store to pos_offset for better precision /// Large values better store to pos_offset for better precision
47 47 jm::v3f position; jm::v3f position;
48 /// Offset applied to position after scaling on power of two
48 /// Offset applied to position after shifting
49 49 jm::v3i32 pos_offset; jm::v3i32 pos_offset;
50 /// Power of 2, that is scale of offset
51 uint32_t shift_po2;
50 /// Shifting is equal to multiply on power-of-two values
51 uint32_t offset_shift;
52 52 /// x,y,z axis directions, must be normalized. /// x,y,z axis directions, must be normalized.
53 53 jm::vec3<jm::v3f> axis; jm::vec3<jm::v3f> axis;
54 54 }; };
File include/jen/compute.h changed (mode: 100644) (index 5e49ca3..8be0c41)
... ... namespace jen::compute {
217 217 } }
218 218 namespace jen namespace jen
219 219 { {
220 /// @brief Compute module interface
220 /// @brief Compute module interface.
221 221 /// ModuleCompute can only be created and destroyed by Framework. /// ModuleCompute can only be created and destroyed by Framework.
222 /// To get compute module instance use Framework.compute member field.
222 /// To get compute module instance use Framework.compute member field,
223 /// framework must be created with ModuleFlag::COMPUTE bit set.
223 224 /// ModuleCompute is used to create and destroy compute objects: /// ModuleCompute is used to create and destroy compute objects:
224 225 /// - compute::Pipeline /// - compute::Pipeline
225 226 /// - compute::BindingBuffer /// - compute::BindingBuffer
 
... ... namespace jen
228 229 /// - compute::BindingsSet /// - compute::BindingsSet
229 230 /// Compute objects can be created from multiple threads simultaneously. /// Compute objects can be created from multiple threads simultaneously.
230 231 struct ModuleCompute { struct ModuleCompute {
231 /// @brief Initialize compute::Pipeline
232 /// @brief Initialize compute::Pipeline.
232 233 /// After creation, Pipeline must be destroyed with destroy_pipeline /// After creation, Pipeline must be destroyed with destroy_pipeline
233 234 /// when is not needed anymore. /// when is not needed anymore.
234 235 /// @param bi bindings that will be bind to this pipeline, /// @param bi bindings that will be bind to this pipeline,
 
... ... namespace jen
243 244 create_pipeline(const compute::Bindings &bi, const char *p_shader_file_path, create_pipeline(const compute::Bindings &bi, const char *p_shader_file_path,
244 245 vkw::ShaderSpecialization *p_specialization, vkw::ShaderSpecialization *p_specialization,
245 246 compute::Pipeline *p_dst); compute::Pipeline *p_dst);
246 /// @brief Initialize array of compute::BindingBuffer
247 /// @brief Initialize array of compute::BindingBuffer.
247 248 /// After creation, binding buffers must be destroyed with destroy_bindings /// After creation, binding buffers must be destroyed with destroy_bindings
248 249 /// when is not needed anymore. /// when is not needed anymore.
249 250 /// @param infos information about bindings to create /// @param infos information about bindings to create
 
... ... namespace jen
255 256 [[nodiscard]] Result [[nodiscard]] Result
256 257 create_bindings(compute::BindingCreateInfos infos, create_bindings(compute::BindingCreateInfos infos,
257 258 compute::BindingBuffer *p_dst); compute::BindingBuffer *p_dst);
258 /// @brief Initialize array of compute::BindingBufferView
259 /// @brief Initialize array of compute::BindingBufferView.
259 260 /// After creation, binding buffers must be destroyed with destroy_bindings /// After creation, binding buffers must be destroyed with destroy_bindings
260 261 /// when is not needed anymore. /// when is not needed anymore.
261 262 /// @param infos information about bindings to create /// @param infos information about bindings to create
 
... ... namespace jen
270 271 [[nodiscard]] Result [[nodiscard]] Result
271 272 create_bindings(compute::BindingCreateInfos infos, VkFormat *p_formats, create_bindings(compute::BindingCreateInfos infos, VkFormat *p_formats,
272 273 compute::BindingBufferView *p_dst); compute::BindingBufferView *p_dst);
273 /// @brief Initialize array of compute::Image
274 /// @brief Initialize array of compute::Image.
274 275 /// After creation, images must be destroyed with destroy_images /// After creation, images must be destroyed with destroy_images
275 276 /// when is not needed anymore. /// when is not needed anymore.
276 277 /// @param infos information about bindings to create /// @param infos information about bindings to create
 
... ... namespace jen
281 282 /// and images are not created /// and images are not created
282 283 [[nodiscard]] Result [[nodiscard]] Result
283 284 create_images(compute::ImageCreateInfos infos, compute::Image *p_dst); create_images(compute::ImageCreateInfos infos, compute::Image *p_dst);
284 /// @brief Initialize compute::BindingsSet
285 /// @brief Initialize compute::BindingsSet.
285 286 /// After creation, binding set must be destroyed with destroy_bindingSet /// After creation, binding set must be destroyed with destroy_bindingSet
286 287 /// when is not needed anymore. /// when is not needed anymore.
287 288 /// @param pipeline specify pipeline this set to bind to /// @param pipeline specify pipeline this set to bind to
 
... ... namespace jen
295 296 create_bindingSet(const compute::Pipeline &pipeline, create_bindingSet(const compute::Pipeline &pipeline,
296 297 const compute::Bindings &bindings, const compute::Bindings &bindings,
297 298 compute::BindingsSet *p_dst); compute::BindingsSet *p_dst);
298 /// @brief Destroy binding set
299 /// @brief Destroy binding set.
299 300 /// Must be called only once for created set. /// Must be called only once for created set.
300 301 /// Set cannot be used after destroying. /// Set cannot be used after destroying.
301 302 /// @param p_set pointer to created by create_bindingSet set /// @param p_set pointer to created by create_bindingSet set
302 303 void destroy_bindingSet(compute::BindingsSet *p_set); void destroy_bindingSet(compute::BindingsSet *p_set);
303 /// @brief Destroy buffer bindings
304 /// @brief Destroy buffer bindings.
304 305 /// Must be called only once for every created binding. /// Must be called only once for every created binding.
305 306 /// Binding cannot be used after destroying. /// Binding cannot be used after destroying.
306 307 /// @param p_bs pointer to array created by create_bindings bindings /// @param p_bs pointer to array created by create_bindings bindings
307 308 /// @param count count of bindings to destroy /// @param count count of bindings to destroy
308 309 void destroy_bindings(compute::BindingBuffer *p_bs, uint32_t count = 1); void destroy_bindings(compute::BindingBuffer *p_bs, uint32_t count = 1);
309 /// @brief Destroy buffer view bindings
310 /// @brief Destroy buffer view bindings.
310 311 /// Must be called only once for every created binding. /// Must be called only once for every created binding.
311 312 /// Binding cannot be used after destroying. /// Binding cannot be used after destroying.
312 313 /// @param p_bs pointer to array created by create_bindings bindings /// @param p_bs pointer to array created by create_bindings bindings
313 314 /// @param count count of bindings to destroy /// @param count count of bindings to destroy
314 315 void destroy_bindings(compute::BindingBufferView *p_bs, uint32_t count = 1); void destroy_bindings(compute::BindingBufferView *p_bs, uint32_t count = 1);
315 /// @brief Destroy images
316 /// @brief Destroy images.
316 317 /// Must be called only once for every created image. /// Must be called only once for every created image.
317 318 /// Image cannot be used after destroying. /// Image cannot be used after destroying.
318 319 /// @param p_ims pointer to created by create_images array of images /// @param p_ims pointer to created by create_images array of images
319 320 /// @param count count of images to destroy /// @param count count of images to destroy
320 321 void destroy_images(compute::Image *p_ims, uint32_t count = 1); void destroy_images(compute::Image *p_ims, uint32_t count = 1);
321 /// @brief Destroy pipeline
322 /// @brief Destroy pipeline.
322 323 /// Must be called only once for created pipeline. /// Must be called only once for created pipeline.
323 324 /// Pipeline cannot be used after destroying. /// Pipeline cannot be used after destroying.
324 325 /// @param p_pl pointer to created by create_pipeline pipeline /// @param p_pl pointer to created by create_pipeline pipeline
 
... ... namespace jen
329 330 /// Changing leans to undefined behaviour. /// Changing leans to undefined behaviour.
330 331 Data *p; Data *p;
331 332 }; };
332 /// @brief User information for compute operation
333 /// @brief User information for compute operation.
333 334 struct ComputeInfo { struct ComputeInfo {
334 /// @brief Pointer to pipeline to use in computation.
335 /// Pointer to pipeline to use in computation.
335 336 compute::Pipeline *p_pipeline; compute::Pipeline *p_pipeline;
336 /// @brief Pointer to set to use in computation.
337 /// Pointer to set to use in computation.
337 338 /// Must be created with pipeline from *p_pipeline /// Must be created with pipeline from *p_pipeline
338 339 compute::BindingsSet *p_bindingsSet; compute::BindingsSet *p_bindingsSet;
339 /// @brief Pointer to bindings lists.
340 /// Pointer to bindings lists.
340 341 /// Must be same as passed to this pipeline and this binding set /// Must be same as passed to this pipeline and this binding set
341 342 compute::Bindings *p_bindings; compute::Bindings *p_bindings;
342 /// @brief Size of workgroups, amount of works to execute.
343 /// Size of workgroups, amount of works to execute.
343 344 jm::v3u32 group_count; jm::v3u32 group_count;
344 /// @brief Write-to buffer operations to apply before computing
345 /// Write-to buffer operations to apply before computing.
345 346 compute::BufferTransfers buffer_writes; compute::BufferTransfers buffer_writes;
346 /// @brief Read-from buffer operations to apply after computing
347 /// Read-from buffer operations to apply after computing.
347 348 compute::BufferTransfers buffer_reads; compute::BufferTransfers buffer_reads;
348 /// @brief Write-to image operations to apply before computing
349 /// Write-to image operations to apply before computing.
349 350 compute::ImagesTransfers images_writes; compute::ImagesTransfers images_writes;
350 /// @brief Read-from image operations to apply after computing
351 /// Read-from image operations to apply after computing.
351 352 compute::ImagesTransfers images_reads; compute::ImagesTransfers images_reads;
352 353 }; };
353 /// @brief Compute unit to perform compute operations
354 /// @brief Compute unit to perform compute operations.
354 355 /// While ModuleCompute is used to create compute objects, /// While ModuleCompute is used to create compute objects,
355 356 /// ComputeCmdUnit is used to run compute operations. /// ComputeCmdUnit is used to run compute operations.
356 357 /// Compute process is period between start of ComputeCmdUnit::compute and /// Compute process is period between start of ComputeCmdUnit::compute and
357 358 /// end of ComputeCmdUnit::read_result. /// end of ComputeCmdUnit::read_result.
358 359 /// User can create several ComputeCmdUnits and run them simultaneously with /// User can create several ComputeCmdUnits and run them simultaneously with
359 360 /// those restrictions: /// those restrictions:
360 /// - same buffers and images instances cannot used to simultaneous
361 /// - same buffer and image instances cannot used for simultaneous
361 362 /// compute process; /// compute process;
362 363 /// - all ComputeCmdUnit instances must be destroyed before Framework /// - all ComputeCmdUnit instances must be destroyed before Framework
363 364 /// is destroyed; /// is destroyed;
 
... ... namespace jen
367 368 /// is running; /// is running;
368 369 /// - ComputeCmdUnit must be valid (initialized and not destroyed). /// - ComputeCmdUnit must be valid (initialized and not destroyed).
369 370 struct ComputeCmdUnit { struct ComputeCmdUnit {
370 /// @brief Initialize ComputeCmdUnit
371 /// @brief Initialize ComputeCmdUnit.
371 372 /// @param mc instance of ModuleCompute /// @param mc instance of ModuleCompute
372 373 /// @return If not VK_SUCCESS than ComputeCmdUnit is not initialized /// @return If not VK_SUCCESS than ComputeCmdUnit is not initialized
373 374 [[nodiscard]] Result [[nodiscard]] Result
374 375 init(ModuleCompute mc); init(ModuleCompute mc);
375 /// @brief Destroy ComputeCmdUnit
376 /// @brief Destroy ComputeCmdUnit.
376 377 /// Destroying while running compute process is not allowed /// Destroying while running compute process is not allowed
377 378 void destroy(); void destroy();
378 /// @brief Run compute process
379 /// @brief Run compute process.
379 380 /// After this function compute process is running parallel on Device /// After this function compute process is running parallel on Device
380 381 /// Use compute_status, to get status of compute process /// Use compute_status, to get status of compute process
381 382 /// Use read_result, to wait untill process is done and get results /// Use read_result, to wait untill process is done and get results
 
... ... namespace jen
383 384 /// @return if VK_SUCCESS is not returned, compute process is not performed. /// @return if VK_SUCCESS is not returned, compute process is not performed.
384 385 [[nodiscard]] Result [[nodiscard]] Result
385 386 compute(const ComputeInfo &ci); compute(const ComputeInfo &ci);
386 /// @brief Get status of compute operation
387 /// @brief Get status of compute operation.
387 388 /// @return VK_SUCCESS - compute is done, VK_NOT_READY - compute is running, /// @return VK_SUCCESS - compute is done, VK_NOT_READY - compute is running,
388 389 /// VK_ERROR_OUT_OF_HOST_MEMORY or VK_ERROR_OUT_OF_DEVICE_MEMORY - /// VK_ERROR_OUT_OF_HOST_MEMORY or VK_ERROR_OUT_OF_DEVICE_MEMORY -
389 390 /// not enouph memory to get status, VK_ERROR_DEVICE_LOST - Vulkan /// not enouph memory to get status, VK_ERROR_DEVICE_LOST - Vulkan
File include/jen/controls.h changed (mode: 100644) (index 14e7fe5..c1cf680)
6 6
7 7 namespace Key namespace Key
8 8 { {
9 /// @brief State of button
9 /// @brief State of button.
10 10 enum State : uint8_t enum State : uint8_t
11 11 { {
12 12 OFF = GLFW_RELEASE, OFF = GLFW_RELEASE,
13 13 ON = GLFW_PRESS ON = GLFW_PRESS
14 14 }; };
15 /// @brief Keyboard key codes
15 /// @brief Keyboard key codes.
16 16 enum Board : uint16_t enum Board : uint16_t
17 17 { {
18 18 /* Printable keys */ /* Printable keys */
 
... ... namespace Key
137 137 kSUPER_R = GLFW_KEY_RIGHT_SUPER, kSUPER_R = GLFW_KEY_RIGHT_SUPER,
138 138 kMENU = GLFW_KEY_MENU, kMENU = GLFW_KEY_MENU,
139 139 }; };
140 /// @brief Mouse key codes
140 /// @brief Mouse key codes.
141 141 enum Mouse : uint8_t enum Mouse : uint8_t
142 142 { {
143 143 m1 = GLFW_MOUSE_BUTTON_1, m1 = GLFW_MOUSE_BUTTON_1,
File include/jen/framework.h changed (mode: 100644) (index 63660fa..5ebac9a)
14 14 #include "resource_manager.h" #include "resource_manager.h"
15 15 #endif #endif
16 16 #include <jlib/thread_pool.h> #include <jlib/thread_pool.h>
17 /// @brief All jen declarations is in jen namespace
17 /// @brief All jen declarations is in jen namespace.
18 18 namespace jen { namespace jen {
19 19 /// @brief There is no interface for Instance. /// @brief There is no interface for Instance.
20 20 struct Instance; struct Instance;
 
... ... namespace jen {
27 27 /// User can create any amount of Framework units and use them in parallel. /// User can create any amount of Framework units and use them in parallel.
28 28 /// User can use variable members to access modules interfaces. /// User can use variable members to access modules interfaces.
29 29 struct jen::Framework { struct jen::Framework {
30 /// @brief Initialize all components of Framework
30 /// @brief Initialize all components of Framework.
31 31 /// @param modules_mask bitmask of flags to specify which modules to load /// @param modules_mask bitmask of flags to specify which modules to load
32 32 /// @param settings valid settings for framework components /// @param settings valid settings for framework components
33 33 /// @return If false, nothing is initialized. /// @return If false, nothing is initialized.
 
... ... struct jen::Framework {
42 42 /// @return If graphics module is initialized - Window handle, else null /// @return If graphics module is initialized - Window handle, else null
43 43 [[nodiscard]] Window* [[nodiscard]] Window*
44 44 get_window(); get_window();
45 /// @brief Get pointer to physical device properties
45 /// @brief Get pointer to physical device properties.
46 46 /// @return Pointer valid until Framework is not destroyed /// @return Pointer valid until Framework is not destroyed
47 47 [[nodiscard]] const VkPhysicalDeviceProperties* [[nodiscard]] const VkPhysicalDeviceProperties*
48 48 get_device_properties(); get_device_properties();
49 /// @brief Get pointer to thread pool
49 /// @brief Get pointer to thread pool.
50 50 /// Manual destroying of this thread pool is not allowed. /// Manual destroying of this thread pool is not allowed.
51 51 /// @return Pointer valid until Framework is not destroyed /// @return Pointer valid until Framework is not destroyed
52 52 [[nodiscard]] jth::Pool* [[nodiscard]] jth::Pool*
File include/jen/graphics.h changed (mode: 100644) (index 8414877..d2f9d50)
1 /// @file graphics.h
2 /// @brief ModuleGraphics interface
1 3 #pragma once #pragma once
2 4 #include "configuration.h" #include "configuration.h"
3 5 #if not JEN_MODULE_GRAPHICS #if not JEN_MODULE_GRAPHICS
 
12 14 #include <jrf/image.h> #include <jrf/image.h>
13 15
14 16 namespace jen { namespace jen {
15 struct DebugOverlay;
16 struct GraphicsData;
17 17 struct ModuleGraphics; struct ModuleGraphics;
18 struct DrawFrameLoop;
18 19 } }
20 /// @brief 3D Graphics renderer
21 /// ModuleGraphics can only be created and destroyed by Framework.
22 /// To get compute module instance use Framework.graphics member field,
23 /// framework must be created with ModuleFlag::GRAPHICS bit set
24 /// All handles created by ModuleGraphics::create must be destroyed by calling
25 /// ModuleGraphics::destroy before Framework is destroyed.
19 26 struct jen::ModuleGraphics struct jen::ModuleGraphics
20 27 { {
21 [[nodiscard]] Result
22 apply_settings(const GraphicsSettings &settings);
23
28 /// @brief Change graphics settings.
29 /// Settings are updated anyway, but appliyng can fail,
30 /// ModuleGraphics will try to apply them again in ModuleGraphics::draw_frame.
31 /// @param settings GraphicsSettings with valid values
32 /// @return User optionally can check for VK_ERROR_OUT_OF_HOST_MEMORY or
33 /// VK_ERROR_OUT_OF_DEVICE_MEMORY to free some memory.
34 Result apply_settings(const GraphicsSettings &settings);
35 /// @brief Update camera and frustum parameters
24 36 void apply_camera(const Camera&, const Frustum&); void apply_camera(const Camera&, const Frustum&);
25 void apply_light_shadow(const Light&);
37 /// @brief Update shadow-casting light.
38 /// @param l light for shadow mapping
39 void apply_light_shadow(const Light &l);
40 /// @brief Provide pointer to lights information.
41 /// Lights data must not change simultaneously with function draw_frame
42 /// (data pointed to by array LightsDraw.lights).
43 /// When data is changed outside of draw_frame, user must set
44 /// LightsDraw.is_updated flag to true to update lights. is_updated flag is
45 /// checked in draw_frame function and will be set to false.
46 /// @param p_lights pointer to LightsDraw, must be valid pointer untill
47 /// new pointer is provided or ModuleGraphics is destroyed
26 48 void apply_lights(LightsDraw *p_lights); void apply_lights(LightsDraw *p_lights);
27
49 /// @brief Run data to GPU writing process and acquire GpuData memory handle.
50 /// User memory under WriteData.p pointer must be valid while writting process
51 /// is occuring. To check writtings process status, use is_resource_ready.
52 /// Depending on Device properties, writting process can end up after this
53 /// function return, or can require some time to wait gpu commands executions.
54 /// GpuData handle must be cleaned up by ModuleGraphics::destroy,
55 /// before destroying Framework
56 /// @param w User data to write
57 /// @param pp_dst Pointer to write GpuData handle
58 /// @param free_src If this flag set to true, WriteData.p memory will be
59 /// be deallocated in the end of writing proccess
60 /// @return If not VK_SUCCESS than nothing is done
28 61 [[nodiscard]] Result [[nodiscard]] Result
29 create(const WriteData&, GpuData **pp_dst, bool free_source);
30
62 create(const WriteData &w, GpuData **pp_dst, bool free_src);
63 /// @brief Run data to GPU writing process and write GpuData to user memory.
64 /// @param w User data to write
31 65 /// @param p_allocated externally allocated GpuData memory, /// @param p_allocated externally allocated GpuData memory,
32 /// will be deallocated after destroy(GpuData*,bool)
66 /// must have at least size of GPU_DATA_ALLOCATION_SIZE
67 /// @param free_src If this flag set to true, WriteData.p memory will be
68 /// be deallocated in the end of writing proccess
69 /// @see create(const WriteData&, GpuData**, bool)
33 70 [[nodiscard]] Result [[nodiscard]] Result
34 create(const WriteData&, GpuData *p_allocated, bool free_source);
35
71 create(const WriteData& w, GpuData *p_allocated, bool free_src);
72 /// @brief Run gpu texture creation process and acquire GpuTexture handle.
73 /// User memory under jrf::Image.p_pixels pointer must be valid while
74 /// texture creation process is occuring. To check process status,
75 /// use is_resource_ready.
76 /// Process require staging and complex image tranferring operations.
77 /// Process is running on separate thread using GPU commands execution.
78 /// GpuTexture handle must be cleaned up by ModuleGraphics::destroy,
79 /// before destroying Framework
80 /// @param texture valid jrf::Image information
81 /// @param pp_dst Pointer to write GpuTexture handle
82 /// @param free_src If this flag set to true, jrf::Image will be
83 /// be destroyed in the end of writing proccess
36 84 [[nodiscard]] Result [[nodiscard]] Result
37 create(const jrf::Image *p_texture, GpuTexture **pp_dst, bool free_src);
85 create(const jrf::Image &texture, GpuTexture **pp_dst, bool free_src);
86 /// @brief Clean memory and GpuData handle.
87 /// GpuData handle becomes invalid after cleaning
88 /// @param p Valid GpuData handle, acquired from ModuleGraphics::create
89 /// @param free_src If set to true, specified in ModuleGraphics::create
90 /// WriteData.p memory will be deallocated
91 /// (no effect if it is already deallocated after create)
92 void destroy(GpuData *p, bool free_src);
93 /// @brief Clean memory and GpuTexture handle.
94 /// GpuTexture handle becomes invalid after cleaning
95 /// @param p Valid GpuTexture handle, acquired from ModuleGraphics::create
96 /// @param free_src If set to true, specified in ModuleGraphics::create
97 /// jrf::Image will be destroyed
98 /// (no effect if it is already destroyed after create)
99 void destroy(GpuTexture *p, bool free_src);
38 100
101 /// @brief Create GlyphManager handle with font from file.
102 /// @param font_path path to font file with
103 /// supported by FreeType library format
104 /// @param pp_dst pointer to write GlyphManager handle
105 /// @return true if success, else nothing is created
39 106 [[nodiscard]] bool [[nodiscard]] bool
40 107 create(const char* font_path, GlyphManager **pp_dst); create(const char* font_path, GlyphManager **pp_dst);
41 108
42 /// @param pp_text Valid handle or nullptr.
43 /// after calling with nullptr important to fill Text.data member
44 /// Text.data can be changed at any time for changing rendering options
45 /// for next frame draw
109 /// @brief Create or update text on gpu.
110 /// After this function call this text will be drawn every frame untill
111 /// ModuleGraphics::destroy(GpuText*) is called with this GpuText handle.
112 /// @param layout text characters positioning in box
113 /// @param pixel_size Size of glyphs in pixels
114 /// @param chars UTF32 Characters
115 /// @param colors Colors of characters. If count of colors less than
116 /// characters count than colors will be repeated in cycle.
117 /// @param p_font Valid GlyphManager handle created with create func
118 /// @param pp_text Valid GpuText handle or nullptr.
119 /// If nullptr, new GpuText handle will be created.
120 /// User must fill (*pp_text)->data with correct values.
121 /// Text.data can be changed at any time to change
122 /// text options for the next frame draw
123 /// @return If not VK_SUCCESS than text is not created
46 124 [[nodiscard]] Result [[nodiscard]] Result
47 125 text_update(TextLayout layout, uint16_t pixel_size, Chars chars, text_update(TextLayout layout, uint16_t pixel_size, Chars chars,
48 126 Colors_RGBA colors, GlyphManager *p_font, GpuText **pp_text); Colors_RGBA colors, GlyphManager *p_font, GpuText **pp_text);
49
50 void destroy(GlyphManager *p_font);
127 /// @brief Stop gpu text drawing and clean GpuText handle.
128 /// After this call, GpuText handle cant be used again for text_update
129 /// @param p_text Text to clean
51 130 void destroy(GpuText *p_text); void destroy(GpuText *p_text);
52
53 void destroy(GpuTexture*, bool destroy_src_image);
54 void destroy(GpuData*, bool destroy_source);
55
56 [[nodiscard]] Result draw_frame(const jl::rarray<const Model> &models);
57
58
59 using PF_User = void(*)(void*);
60
61 struct Loop {
62 void run(ModuleGraphics mg, void *p_update_arg, PF_User pf_update);
63
64 Result result;
65 jl::time last_update_time;
66 jl::time elapsed_after_update;
67 bool pause;
68 bool is_drawn;
69 bool draw;
70 bool break_loop;
71 bool wait_events;
72 jl::rarray<const Model> models;
73 };
74
75 GraphicsData *p;
131 /// @brief Destroy GlyphManager handle and font data.
132 /// GlyphManager handle is invalid after destroying
133 /// @param p_font Valid GlyphManager handle, all GpuText handles created
134 /// with this GlyphManager handle must be destroyed before.
135 void destroy(GlyphManager *p_font);
136 /// @brief Acquire swapchain image, draw to it and preset to window surface.
137 /// @param models Constant array of models to use in rendering operation
138 /// @return If not VK_SUCCESS than frame is not presented
139 [[nodiscard]] Result
140 draw_frame(const jl::rarray<const Model> &models);
141 struct Data;
142 /// @brief Pointer to hidden data of ModuleGraphics.
143 /// Because of this pointer, ModuleGraphics can be passed by value.
144 /// Pointer value is valid untill Framework is destroyed.
145 Data *p;
146 };
147 /// @brief Routine to run produce frame drawing in infinite loop.
148 struct jen::DrawFrameLoop {
149 /// @brief Run loop.
150 /// To stop drawing loop, set break_loop frag to true.
151 /// All FrameLoop member values will be initialized before loop in this
152 /// function.
153 /// @param mg Graphics module to call draw_frame
154 /// @param p_update_arg User pointer to pass to pf_update function
155 /// @param pf_update Function pointer to user function that will be called
156 /// every frame
157 void run(ModuleGraphics mg, void *p_update_arg, void(*pf_update)(void*));
158 /// User can check reason of draw_frame failure
159 Result result;
160 /// Last time draw_frame succeeded
161 jl::time last_update_time;
162 /// Time elapsed between loop update and successfull draw_frame
163 jl::time elapsed_after_update;
164 /// If true, loop will not draw and will wait user events by using
165 /// Window.wait function.
166 /// State of this flag is also changing if Key::kPAUSE button is fired
167 bool pause;
168 /// Is draw_frame succeeded last time
169 bool is_drawn;
170 /// Set this flag to true every time when need to produce frame
171 bool draw;
172 /// If set to true, function DrawFrameLoop::run will return
173 bool break_loop;
174 /// If set to false, loop will make frames as fast as possible using
175 /// Window.poll, else it will wait user interactions in Window.wait
176 bool wait_events;
177 /// Models to put in draw_frame function
178 jl::rarray<const Model> models;
76 179 }; };
File include/jen/light.h changed (mode: 100644) (index f0813a1..3a82f55)
6 6
7 7 namespace jen namespace jen
8 8 { {
9 /// @brief Single omnidirectional light source parameters
9 /// @brief Single omnidirectional light source parameters.
10 10 struct Light { struct Light {
11 11 /// Position of the light /// Position of the light
12 12 jm::v3f pos; jm::v3f pos;
 
... ... namespace jen
37 37 using Lights = jl::rarray<const Light>; using Lights = jl::rarray<const Light>;
38 38 /// @brief List of the lights to use in frame draw. /// @brief List of the lights to use in frame draw.
39 39 struct LightsDraw { struct LightsDraw {
40 /// @brief List of lights.
41 /// Must be valid while draw_frame function is running.
40 /// List of lights. Must be valid while draw_frame function is running.
42 41 /// @see ModuleGraphics::draw_frame /// @see ModuleGraphics::draw_frame
43 42 Lights lights; Lights lights;
44 /// @brief If list of lights is changed, user must set this flag to true.
43 /// If list of lights is changed, user must set this flag to true.
45 44 bool is_updated; bool is_updated;
46 45 }; };
47 /// @brief Lights in the LightsDraw after this limit will be ignored
46 /// @brief Lights in the LightsDraw after this limit will be ignored.
48 47 constexpr static const uint32_t MAX_LIGHTS_COUNT = 512; constexpr static const uint32_t MAX_LIGHTS_COUNT = 512;
49 /// @brief Lights in single cluster after this limit will be ignored
48 /// @brief Lights in single cluster after this limit will be ignored.
50 49 constexpr static const uint32_t MAX_LIGHTS_COUNT_IN_CLUSTER = 128; constexpr static const uint32_t MAX_LIGHTS_COUNT_IN_CLUSTER = 128;
51 50 } }
File include/jen/resources.h changed (mode: 100644) (index ffa12a6..a631550)
1 /// @file resources.h
2 /// @brief Resources for graphics rendering: texts, textures, models
1 3 #pragma once #pragma once
2 4 #include <jmath/vector.h> #include <jmath/vector.h>
3 5 #include <jmath/matrix.h> #include <jmath/matrix.h>
 
5 7 #include <jlib/rarray.h> #include <jlib/rarray.h>
6 8
7 9 namespace jen { namespace jen {
8 enum class [[nodiscard]] ResourceState : uint8_t {
9 LOADING = 0b00,
10 DONE = 0b01
11 };
10 struct GpuTexture;
12 11 struct GpuData; struct GpuData;
12 struct GpuText;
13 struct GlyphManager;
14 /// @brief In case user want to allocate manually.
13 15 constexpr static const uint64_t GPU_DATA_ALLOCATION_SIZE = 88; constexpr static const uint64_t GPU_DATA_ALLOCATION_SIZE = 88;
14 struct GpuTexture;
16 /// @brief Just for fun
15 17 constexpr static const uint64_t GPU_TEXTURE_ALLOCATION_SIZE = 120; constexpr static const uint64_t GPU_TEXTURE_ALLOCATION_SIZE = 120;
16
18 /// @brief User provided data to write into resource memory.
17 19 struct WriteData { struct WriteData {
18 void *p;
19 uint64_t size;
20 void *p; ///< Pointer to data that user want to write
21 uint64_t size; ///< Size of data
20 22 }; };
21
22 ResourceState resource_state(const GpuData * const);
23 ResourceState resource_state(const GpuTexture* const);
24
23 /// @brief State of the resource creation.
24 enum class [[nodiscard]] ResourceState : uint8_t {
25 LOADING = 0b00, ///< Resource is still loading on the background
26 DONE = 0b01 ///< Resource is loaded and ready to use
27 };
28 /// @brief Get resource state of the GpuData.
29 /// @param p pointer to created by ModuleGraphics::create GpuData
30 /// @return state of the data preparing process
31 ResourceState resource_state(const GpuData * const p);
32 /// @brief Get resource state of the GpuTexture.
33 /// @param p pointer to created by ModuleGraphics::create GpuTexture
34 /// @return state of the texture preparing process
35 ResourceState resource_state(const GpuTexture* const p);
36 /// @brief Helper function to check if resource ready to use.
37 /// @param p pointer to created by ModuleGraphics::create GpuData
38 /// @return true, if resource is ready
25 39 [[nodiscard]] inline bool is_resource_ready(const GpuData*const p) { [[nodiscard]] inline bool is_resource_ready(const GpuData*const p) {
26 40 return resource_state(p) == ResourceState::DONE; return resource_state(p) == ResourceState::DONE;
27 41 } }
42 /// @brief Helper function to check if resource ready to use.
43 /// @param p pointer to created by ModuleGraphics::create GpuTexture
44 /// @return true, if resource is ready
28 45 [[nodiscard]] inline bool is_resource_ready(const GpuTexture*const p) { [[nodiscard]] inline bool is_resource_ready(const GpuTexture*const p) {
29 46 return resource_state(p) == ResourceState::DONE; return resource_state(p) == ResourceState::DONE;
30 47 } }
31 48
32
33 struct GlyphManager;
34
35 using Chars = jl::rarray<const uint32_t>;
36 using Colors_RGBA = jl::rarray<const uint32_t>;
37
38 struct TextOffsetMode {
39 enum class X : uint8_t { LEFT, CENTER, RIGHT } x;
40 enum class Y : uint8_t { TOP, CENTER, BOTTOM } y;
49 /// @brief Vertex attributes indices.
50 enum VAttr : uint8_t {
51 /// 3x32bit floating point, position
52 POSITION,
53 /// 2x32bit floating point, texture coordinate
54 TEX_COORD,
55 /// 3x32bit floating point, normal (optional if Shading is not DEFAULT)
56 NORMAL,
57 /// 32bit value, 4x8bit texture indices (for terrain pipeline)
58 TEX_IND,
59 /// 32bit value, 4x8bit texture indices weights (for terrain pipeline)
60 TEX_SCALE
41 61 }; };
42
43 enum class TextLayout : uint8_t { LEFT, CENTER, RIGHT };
44
45 struct TextPosition {
46 jm::v2f offset;
47 TextOffsetMode text_offset_mode;
48 TextOffsetMode screen_offset_mode;
49 };
50
51 struct GpuText;
52
53
54 enum VAttr : uint8_t { POSITION, TEX_COORD, NORMAL, TEX_IND, TEX_SCALE };
62 /// @brief Count of vertex attributes.
63 /// @see Vattr
55 64 constexpr static const uint8_t VATTR_TYPE_COUNT = 5; constexpr static const uint8_t VATTR_TYPE_COUNT = 5;
65 /// @brief Array of vertex attributes offsets in the memory.
56 66 using VAttrsOffsets = jl::array<uint64_t, VATTR_TYPE_COUNT>; using VAttrsOffsets = jl::array<uint64_t, VATTR_TYPE_COUNT>;
57
67 /// @brief Vertices stored on gpu.
58 68 struct VertexData { struct VertexData {
59 GpuData *p_data;
60 VAttrsOffsets offsets;
61 uint32_t count;
69 GpuData *p_data; ///< GpuData memory with vertixes
70 VAttrsOffsets offsets; ///< where to find attributes in memory
71 uint32_t count; ///< count of vertixes
62 72 }; };
63
64 enum class IndexType { U16 = 0, U32 = 1 };
65
73 /// @brief Type of index.
74 enum class IndexType {
75 U16 = 0, /// unsigned 2-byte integer
76 U32 = 1 /// unsigned 4-byte integer
77 };
78 /// @brief Indices stored on gpu.
66 79 struct IndexData { struct IndexData {
67 GpuData *p_data;
68 uint64_t offset;
69 uint32_t count;
70 IndexType type;
80 GpuData *p_data; ///< GpuData memory with indices
81 uint64_t offset; ///< where to find indices in memory
82 uint32_t count; ///< count of indices
83 IndexType type; ///< indices encoding
71 84 }; };
85 /// @brief Texture stored on gpu.
72 86 struct TextureData { struct TextureData {
73 GpuTexture *p_data;
74 uint32_t layer_index;
87 GpuTexture *p_data; ///< GpuTexture handle
88 uint32_t layer_index; ///< Array index in texture to use for model
75 89 }; };
90 /// @brief Model rotation, scaling and positioning.
76 91 struct ModelWorld { struct ModelWorld {
92 /// Model transformation matrix 4x4
93 /// Final model matrix is calculated as:
94 /// @code
95 /// matrix = transform * jm::translation(final_position);
96 /// @endcode
77 97 jm::m4f transform; jm::m4f transform;
98 /// position of the model
99 /// Final position is calculated as:
100 /// @code
101 /// auto offset = position_offset - camera.pos_offset;
102 /// for (auto &c : offset)
103 /// c <<= camera.offset_shift;
104 /// final_position = position + offset - camera.position;
105 /// @endcode
78 106 jm::v3f position; jm::v3f position;
79 jm::v3i32 position_shift;
107 /// Offset applied to position after shifting on Camera.offset_shift.
108 /// @see Camera.pos_offset
109 /// @see Camera.offset_shift
110 jm::v3i32 position_offset;
80 111 }; };
81
112 /// @brief Model data for 3D rendering.
113 /// Different models can use shared vertices, indices, textures
114 /// without restrictions. If any resource is not ready to draw, model will
115 /// be silently discarded.
82 116 struct Model { struct Model {
117 /// @brief Is model ready to draw.
118 /// This is helper function, calling it for real-time applications is
119 /// unnecessary, because unfinished models will be discarded in current
120 /// frame. But for interactive applications it can be important to
121 /// explicitly wait until all models will be ready to produce expected
122 /// drawing results.
123 /// @return false, if any of model resources is on state
124 /// ResourceState::LOADING
83 125 [[nodiscard]] bool is_ready_to_draw() const { [[nodiscard]] bool is_ready_to_draw() const {
84 126 if (not is_resource_ready(tex.p_data)) if (not is_resource_ready(tex.p_data))
85 127 return false; return false;
 
... ... namespace jen {
92 134
93 135 return true; return true;
94 136 } }
137 /// Model vertices, neccessary
95 138 VertexData ver; VertexData ver;
139 /// Indices data, optional, if ind.p_data is null then vertices will
140 /// be drawed this way: every 3 vertices is a triangle.
141 /// If indices is presented: every 3 indices pointed to vertices
142 /// making triangle.
143 /// So:
144 /// - ver.count % 3 == 0, if indices is not presented
145 /// - ind.count % 3 == 0, if indices is presented
96 146 IndexData ind; IndexData ind;
147 /// Texture to use, neccessary
97 148 TextureData tex; TextureData tex;
149 /// Model transformation info
98 150 ModelWorld world; ModelWorld world;
99 151 }; };
152
153 /// @brief constant array of UTF32 encoded characters.
154 using Chars = jl::rarray<const uint32_t>;
155 /// @brief constant array of R8G8B8A8 colors.
156 using Colors_RGBA = jl::rarray<const uint32_t>;
157 /// @brief Ancors for onscreen positioning.
158 struct TextOffsetMode {
159 /// Horizontal offset positioning
160 enum class X : uint8_t {
161 LEFT, ///< right border of the box is equal to offset value
162 CENTER, ///< center of the box is equal to offset value
163 RIGHT ///< left border of the box is equal to offset value
164 };
165 /// Vertical offset positioning
166 enum class Y : uint8_t {
167 TOP, ///< bottom border of the box is equal to offset value
168 CENTER, ///< center of the box is equal to offset value
169 BOTTOM ///< top border of the box is equal to offset value
170 };
171 X x; ///< horisontal offset mode
172 Y y; ///< vertical offset mode
173 };
174 /// @brief This option changes text characters positioning.
175 enum class TextLayout : uint8_t {
176 LEFT, ///< All lines will start from left border
177 CENTER, ///< All lines will be aligned in the center
178 RIGHT ///< All lines will be aligned to the right border
179 };
180 /// @brief User provided information about text positioning.
181 struct TextPosition {
182 /// Offset position
183 jm::v2f offset;
184 /// @brief How to place text box relative to offset.
185 TextOffsetMode text_offset_mode;
186 /// @brief How to place text box relative to screen.
187 /// In this valiable offset mode have slightly different meaning,
188 /// top-left means text is on the top-left corner of the screen and etc
189 TextOffsetMode screen_offset_mode;
190 };
100 191 } }
File include/jen/screen.h changed (mode: 100644) (index 5c3cfc8..a7bad20)
... ... namespace jen::screen {
8 8 struct Noclip; struct Noclip;
9 9 struct Static; struct Static;
10 10 } }
11 /// @brief Noclip dynamic camera with traditional mouse and WASD controls
11 /// @brief Noclip dynamic camera with traditional mouse and WASD controls.
12 12 struct jen::screen::Noclip struct jen::screen::Noclip
13 13 { {
14 /// @brief Initialize camera with default parameters
14 /// @brief Initialize camera with default parameters.
15 15 /// It is recommended to change some data after this function call, /// It is recommended to change some data after this function call,
16 16 /// Example: set camera position to {10, 50.34f, -4} /// Example: set camera position to {10, 50.34f, -4}
17 17 /// and horizontal field of view to 90 degrees: /// and horizontal field of view to 90 degrees:
 
... ... struct jen::screen::Noclip
25 25 /// @param window Used to access user input /// @param window Used to access user input
26 26 void init(const Window &window, float view_sens, float move_spd) { void init(const Window &window, float view_sens, float move_spd) {
27 27 this->cursor_pos = window.cursor; this->cursor_pos = window.cursor;
28
29 28 camera.position = {}; camera.position = {};
30 29 camera.pos_offset = {}; camera.pos_offset = {};
31 camera.shift_po2 = {};
30 camera.offset_shift = {};
32 31 camera.axis = camera.default_axis(); camera.axis = camera.default_axis();
33
34 32 frustum.set_fov_x(jm::pi<float> / 2); frustum.set_fov_x(jm::pi<float> / 2);
35 33 frustum.set_aspect(window.extent.x, window.extent.y); frustum.set_aspect(window.extent.x, window.extent.y);
36 34 frustum.zNear = 0.5; frustum.zNear = 0.5;
37 35 frustum.zFar = 32000; frustum.zFar = 32000;
38
39 36 view_sensitivity = view_sens; view_sensitivity = view_sens;
40 37 move_speed = move_spd; move_speed = move_spd;
41 38 } }
 
... ... struct jen::screen::Noclip
49 46 /// - 'x' to divide clipping plane /// - 'x' to divide clipping plane
50 47 /// - horizontal mouse movement to rotate camera left or right, /// - horizontal mouse movement to rotate camera left or right,
51 48 /// - vertical mouse movement to rotate camera top or bottom /// - vertical mouse movement to rotate camera top or bottom
52 void update(const Window &window, float elapsed_secs)
53 {
49 void update(const Window &window, float elapsed_secs) {
54 50 if (window.is_on(Key::R)) { if (window.is_on(Key::R)) {
55 51 camera.axis = camera.default_axis(); camera.axis = camera.default_axis();
56 52 } }
57
58 53 auto get_sign = [](bool pos, bool neg) { auto get_sign = [](bool pos, bool neg) {
59 54 return pos - neg; return pos - neg;
60 55 }; };
61
62 56 int sign = get_sign(window.is_on(Key::E), window.is_on(Key::Q)); int sign = get_sign(window.is_on(Key::E), window.is_on(Key::Q));
63 57 if (sign != 0) { if (sign != 0) {
64 58 camera.axis.y = jm::rotation(camera.axis.z, elapsed_secs * 200 * camera.axis.y = jm::rotation(camera.axis.z, elapsed_secs * 200 *
 
... ... struct jen::screen::Noclip
69 63 sign = get_sign(window.is_on(Key::W), window.is_on(Key::S)); sign = get_sign(window.is_on(Key::W), window.is_on(Key::S));
70 64 if (sign != 0) if (sign != 0)
71 65 camera.position += camera.axis.z * sign * elapsed_secs * move_speed; camera.position += camera.axis.z * sign * elapsed_secs * move_speed;
72
73 66 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));
74 67 if (sign != 0) if (sign != 0)
75 68 camera.position -= camera.axis.x * elapsed_secs * move_speed * sign; camera.position -= camera.axis.x * elapsed_secs * move_speed * sign;
76
77 69 if (window.is_on(Key::kEQUAL)) if (window.is_on(Key::kEQUAL))
78 70 move_speed *= 1 + (3.5f * elapsed_secs); move_speed *= 1 + (3.5f * elapsed_secs);
79 71 if (window.is_on(Key::kMINUS)) if (window.is_on(Key::kMINUS))
80 72 move_speed /= 1 + (3.5f * elapsed_secs); move_speed /= 1 + (3.5f * elapsed_secs);
81
82
83
84 73 if (window.is_on(Key::Z)) { if (window.is_on(Key::Z)) {
85 74 frustum.zNear *= 1 + (1.4f * elapsed_secs); frustum.zNear *= 1 + (1.4f * elapsed_secs);
86 75 frustum.zFar *= 1 + (1.4f * elapsed_secs); frustum.zFar *= 1 + (1.4f * elapsed_secs);
 
... ... struct jen::screen::Noclip
90 79 frustum.zFar /= 1 + (1.4f * elapsed_secs); frustum.zFar /= 1 + (1.4f * elapsed_secs);
91 80 } }
92 81 frustum.set_aspect(window.extent.x, window.extent.y); frustum.set_aspect(window.extent.x, window.extent.y);
93
94 if (window.cursor != cursor_pos)
95 {
82 if (window.cursor != cursor_pos) {
96 83 auto cursor_diff = jm::v2f::from(window.cursor - cursor_pos); auto cursor_diff = jm::v2f::from(window.cursor - cursor_pos);
97 84 cursor_diff *= view_sensitivity; cursor_diff *= view_sensitivity;
98
99 85 camera.axis.z = jm::rotation(camera.axis.y, cursor_diff.x) camera.axis.z = jm::rotation(camera.axis.y, cursor_diff.x)
100 86 * camera.axis.z; * camera.axis.z;
101 87 camera.axis.x = jm::cross(camera.axis.y, camera.axis.z).normalized(); camera.axis.x = jm::cross(camera.axis.y, camera.axis.z).normalized();
 
... ... struct jen::screen::Noclip
106 92
107 93 cursor_pos = window.cursor; cursor_pos = window.cursor;
108 94 } }
109
110 95 camera.stash_to_shift(); camera.stash_to_shift();
111 96 } }
112 97 /// Last known cursor position /// Last known cursor position
 
... ... struct jen::screen::Noclip
120 105 /// @see Frustum /// @see Frustum
121 106 Frustum frustum; Frustum frustum;
122 107 }; };
123 /// @brief Static camera
108 /// @brief Static camera.
124 109 struct jen::screen::Static struct jen::screen::Static
125 110 { {
126 /// @brief Initialize camera with default parameters
111 /// @brief Initialize camera with default parameters.
127 112 /// It is recommended to tweak frustum options after this function call, /// It is recommended to tweak frustum options after this function call,
128 113 /// Example: set vertical field of view to 75 degrees /// Example: set vertical field of view to 75 degrees
129 114 /// and clipping planes to [0.5;200]: /// and clipping planes to [0.5;200]:
 
... ... struct jen::screen::Static
138 123 /// @param up vector of head orientation /// @param up vector of head orientation
139 124 /// @param window Used for aspect calculation /// @param window Used for aspect calculation
140 125 void void
141 init(const Window &window, jm::v3f pos, jm::v3f look_direction, jm::v3f up)
142 {
126 init(const Window &window, jm::v3f pos, jm::v3f look_direction, jm::v3f up) {
143 127 camera.position = pos; camera.position = pos;
144 128 camera.pos_offset = {}; camera.pos_offset = {};
145 camera.shift_po2 = {};
129 camera.offset_shift = {};
146 130 camera.axis.z = look_direction.normalized(); camera.axis.z = look_direction.normalized();
147 131 camera.axis.y = up.normalized(); camera.axis.y = up.normalized();
148 132 camera.axis.x = jm::cross(camera.axis.y, camera.axis.z); camera.axis.x = jm::cross(camera.axis.y, camera.axis.z);
149
150 133 frustum.set_fov_x(jm::pi<float> / 2); frustum.set_fov_x(jm::pi<float> / 2);
151 134 frustum.set_aspect(window.extent.x, window.extent.y); frustum.set_aspect(window.extent.x, window.extent.y);
152 135 frustum.zNear = 0.5; frustum.zNear = 0.5;
File include/jen/settings.h changed (mode: 100644) (index ac79870..97c37cd)
... ... namespace jen {
14 14 struct GraphicsSettings; struct GraphicsSettings;
15 15 #endif #endif
16 16 struct Window; struct Window;
17 /// @brief Flags of modules
17 /// @brief Flags of modules.
18 18 namespace ModulesFlag { enum : uint32_t { namespace ModulesFlag { enum : uint32_t {
19 19 COMPUTE = 1, COMPUTE = 1,
20 20 GRAPHICS = 2, GRAPHICS = 2,
21 21 RESOURCE_MANAGER = 4 RESOURCE_MANAGER = 4
22 22 }; } }; }
23 /// @brief bitmask of ModulesFlag::T
23 /// @brief bitmask of ModulesFlag::T.
24 24 using ModulesMask = uint32_t; using ModulesMask = uint32_t;
25 /// @brief Store major, minor and patch version numbers
25 /// @brief Store major, minor and patch version numbers.
26 26 struct Version { struct Version {
27 27 uint16_t major; ///< major version uint16_t major; ///< major version
28 28 uint16_t minor; ///< minor version uint16_t minor; ///< minor version
 
... ... namespace jen {
30 30 }; };
31 31 struct Settings; struct Settings;
32 32 } }
33 /// @brief User application information
33 /// @brief User application information.
34 34 struct jen::ApplicationSettings { struct jen::ApplicationSettings {
35 35 /// @brief nullptr or pointer to application name. /// @brief nullptr or pointer to application name.
36 36 const char *p_name_str; const char *p_name_str;
 
... ... struct jen::ApplicationSettings {
39 39 }; };
40 40 /// @brief Settings for thread pool. /// @brief Settings for thread pool.
41 41 struct jen::ThreadPoolSettings { struct jen::ThreadPoolSettings {
42 /// @brief Queue indices to use in some framework modules
42 /// @brief Queue indices to use in some framework modules.
43 43 struct Indices { struct Indices {
44 44 /// Index to use for ModuleGraphics::draw_frame. /// Index to use for ModuleGraphics::draw_frame.
45 45 /// Must be less than ThreadPoolSettings.queues_count /// Must be less than ThreadPoolSettings.queues_count
 
... ... struct jen::WindowSettings {
65 65 }; };
66 66
67 67 #if JEN_MODULE_GRAPHICS #if JEN_MODULE_GRAPHICS
68 /// @brief Settings for ModuleGraphics
68 /// @brief Settings for ModuleGraphics.
69 69 /// Can be changed in runtime by using ModuleGraphics::apply_settings /// Can be changed in runtime by using ModuleGraphics::apply_settings
70 70 struct jen::GraphicsSettings struct jen::GraphicsSettings
71 71 { {
72 /// @brief Shading options for general 3D pipeline
72 /// @brief Shading options for general 3D pipeline.
73 73 enum class Shading : uint32_t { enum class Shading : uint32_t {
74 74 /// Default shading with clustered forward rendering and shadow mapping /// Default shading with clustered forward rendering and shadow mapping
75 75 DEFAULT, DEFAULT,
 
... ... struct jen::GraphicsSettings
89 89 enum class Filter : uint32_t { enum class Filter : uint32_t {
90 90 _1, _16, _25, _32, _64, _100, _128 _1, _16, _25, _32, _64, _100, _128
91 91 }; };
92 /// @brief Rasterization modes
92 /// @brief Rasterization modes.
93 93 enum class DrawMode : uint8_t { enum class DrawMode : uint8_t {
94 94 DEFAULT, /// Default rasterization mode, fill triangles DEFAULT, /// Default rasterization mode, fill triangles
95 95 WIREFRAME, /// Draw lines only WIREFRAME, /// Draw lines only
96 96 POINTS /// Draw only fragments in vertex positions POINTS /// Draw only fragments in vertex positions
97 97 }; };
98 /// @brief Face culling mode
98 /// @brief Face culling mode.
99 99 enum class CullMode : uint8_t { enum class CullMode : uint8_t {
100 100 NONE, /// Nothing to discard NONE, /// Nothing to discard
101 101 FRONT = 1, /// Discard front faces FRONT = 1, /// Discard front faces
102 102 BACK = 2, /// Discard back faces BACK = 2, /// Discard back faces
103 103 FRONT_AND_BACK = FRONT | BACK /// Discard all faces FRONT_AND_BACK = FRONT | BACK /// Discard all faces
104 104 }; };
105 /// @brief Update settubgs from keyboard input
105 /// @brief Update settubgs from keyboard input.
106 106 /// Function must be called every frame to be usefull /// Function must be called every frame to be usefull
107 107 /// - F2 to toggle window cursor mode /// - F2 to toggle window cursor mode
108 108 /// - F3 to toggle is_debug_depth_cube_visible /// - F3 to toggle is_debug_depth_cube_visible
 
... ... struct jen::GraphicsSettings
144 144 debug_overlay.toggle_key = Key::Board::f1; debug_overlay.toggle_key = Key::Board::f1;
145 145 debug_overlay.font_path = "fonts//IBMPlexMono.ttf"; debug_overlay.font_path = "fonts//IBMPlexMono.ttf";
146 146 } }
147 /// @brief Get default settings
147 /// @brief Get default settings.
148 148 /// @see GraphicsSettings::set_default /// @see GraphicsSettings::set_default
149 149 [[nodiscard]] constexpr static GraphicsSettings [[nodiscard]] constexpr static GraphicsSettings
150 150 get_default() { get_default() {
 
... ... struct jen::GraphicsSettings
152 152 s.set_default(); s.set_default();
153 153 return s; return s;
154 154 } }
155 /// @brief Settings for shadow mapping
155 /// @brief Settings for shadow mapping.
156 156 struct Shadow { struct Shadow {
157 157 /// bias value /// bias value
158 158 float bias; float bias;
 
... ... struct jen::GraphicsSettings
164 164 /// There is 2D-cube texture, so 6 layers: extent*extent*6. /// There is 2D-cube texture, so 6 layers: extent*extent*6.
165 165 uint32_t extent; uint32_t extent;
166 166 }; };
167 /// @brief Options for DebugOverlay (display some information on screen)
167 /// @brief Options for DebugOverlay (display some information on screen).
168 168 struct DebugOverlay { struct DebugOverlay {
169 169 /// If not enabled, it is impossible to enable later /// If not enabled, it is impossible to enable later
170 170 bool is_enabled; bool is_enabled;
 
... ... struct jen::GraphicsSettings
204 204 DebugOverlay debug_overlay; DebugOverlay debug_overlay;
205 205 }; };
206 206 #endif #endif
207 /// @brief All settings for framework components
207 /// @brief All settings for framework components.
208 208 struct jen::Settings { struct jen::Settings {
209 209 /// @brief Initialize by default values. /// @brief Initialize by default values.
210 210 /// @param app_settings application settings (there is no defaults for this) /// @param app_settings application settings (there is no defaults for this)
 
... ... struct jen::Settings {
223 223 graphics.set_default(); graphics.set_default();
224 224 #endif #endif
225 225 } }
226 /// @brief Get default settings
226 /// @brief Get default settings.
227 227 /// @see Settings::set_default /// @see Settings::set_default
228 228 [[nodiscard]] constexpr static Settings [[nodiscard]] constexpr static Settings
229 229 get_default(const ApplicationSettings &app_settings) { get_default(const ApplicationSettings &app_settings) {
File include/jen/window.h changed (mode: 100644) (index 7f61b6e..b41cf6d)
5 5 #include <jmath/vector.h> #include <jmath/vector.h>
6 6
7 7 namespace jen { struct Window; struct Button; } namespace jen { struct Window; struct Button; }
8 /// @brief Configurable Window based on GLFWwindow
8 /// @brief Configurable Window based on GLFWwindow.
9 9 /// Window can only be created and destroyed by Instance, but can be hidden by /// Window can only be created and destroyed by Instance, but can be hidden by
10 10 /// user. User is allowed to call any function, but only read data members. /// user. User is allowed to call any function, but only read data members.
11 11 /// @see Framework::get_window To get pointer to window instance /// @see Framework::get_window To get pointer to window instance
12 12 struct jen::Window struct jen::Window
13 13 { {
14 /// @brief Window cursor mode
14 /// @brief Window cursor mode.
15 15 /// @see Window::set_cursor_mode /// @see Window::set_cursor_mode
16 16 enum class CursorMode { enum class CursorMode {
17 17 NORMAL = GLFW_CURSOR_NORMAL, NORMAL = GLFW_CURSOR_NORMAL,
18 18 HIDDEN = GLFW_CURSOR_HIDDEN, HIDDEN = GLFW_CURSOR_HIDDEN,
19 19 DISABLED = GLFW_CURSOR_DISABLED DISABLED = GLFW_CURSOR_DISABLED
20 20 }; };
21 /// @brief Cursor is just 2D position vector
21 /// @brief Cursor is just 2D position vector.
22 22 using Cursor = jm::v2d; using Cursor = jm::v2d;
23 /// @brief Extent is 2D size vector
23 /// @brief Extent is 2D size vector.
24 24 using Extent = jm::vec2<int>; using Extent = jm::vec2<int>;
25 /// @brief "I DON'T CARE SIZE"
25 /// @brief "I DON'T CARE SIZE".
26 26 constexpr static const Extent ExtentAny = { GLFW_DONT_CARE, GLFW_DONT_CARE }; constexpr static const Extent ExtentAny = { GLFW_DONT_CARE, GLFW_DONT_CARE };
27 /// @brief Set Window visible or invisible
27 /// @brief Set Window visible or invisible.
28 28 void set_visibility(bool is_visible) { void set_visibility(bool is_visible) {
29 29 this->is_visible = is_visible; this->is_visible = is_visible;
30 30 if (is_visible) if (is_visible)
 
... ... struct jen::Window
32 32 else else
33 33 glfwHideWindow(p_window); glfwHideWindow(p_window);
34 34 } }
35 /// @brief Set minimum and maximum allowed window size
35 /// @brief Set minimum and maximum allowed window size.
36 36 void set_extent_limits(Extent min = ExtentAny, Extent max = ExtentAny) const { void set_extent_limits(Extent min = ExtentAny, Extent max = ExtentAny) const {
37 37 glfwSetWindowSizeLimits(p_window, min.x, min.y, max.x, max.y); glfwSetWindowSizeLimits(p_window, min.x, min.y, max.x, max.y);
38 38 } }
39 /// @brief Get state of keyboard button
39 /// @brief Get state of keyboard button.
40 40 [[nodiscard]] Key::State state(Key::Board key) const { [[nodiscard]] Key::State state(Key::Board key) const {
41 41 return Key::State(glfwGetKey(p_window, key)); return Key::State(glfwGetKey(p_window, key));
42 42 } }
43 /// @brief Get state of mouse button
43 /// @brief Get state of mouse button.
44 44 [[nodiscard]] Key::State state(Key::Mouse key) const { [[nodiscard]] Key::State state(Key::Mouse key) const {
45 45 return Key::State(glfwGetMouseButton(p_window, key)); return Key::State(glfwGetMouseButton(p_window, key));
46 46 } }
47 /// @brief Is keyboard button pressed
47 /// @brief Is keyboard button pressed.
48 48 [[nodiscard]] bool is_on(Key::Board key) const { [[nodiscard]] bool is_on(Key::Board key) const {
49 49 return state(key) == Key::State::ON; return state(key) == Key::State::ON;
50 50 } }
51 /// @brief Is mouse button pressed
51 /// @brief Is mouse button pressed.
52 52 [[nodiscard]] bool is_on(Key::Mouse key) const { [[nodiscard]] bool is_on(Key::Mouse key) const {
53 53 return state(key) == Key::State::ON; return state(key) == Key::State::ON;
54 54 } }
55 /// @brief Is keyboard button released
55 /// @brief Is keyboard button released.
56 56 [[nodiscard]] bool is_off(Key::Board key) const { [[nodiscard]] bool is_off(Key::Board key) const {
57 57 return state(key) == Key::State::OFF; return state(key) == Key::State::OFF;
58 58 } }
59 /// @brief Is mouse button released
59 /// @brief Is mouse button released.
60 60 [[nodiscard]] bool is_off(Key::Mouse key) const { [[nodiscard]] bool is_off(Key::Mouse key) const {
61 61 return state(key) == Key::State::OFF; return state(key) == Key::State::OFF;
62 62 } }
63 /// @brief Update user input and window state
63 /// @brief Update user input and window state.
64 64 /// Recommended for realtime application /// Recommended for realtime application
65 65 /// @see glfwPollEvents /// @see glfwPollEvents
66 66 static void poll() { static void poll() {
67 67 glfwPollEvents(); glfwPollEvents();
68 68 } }
69 /// @brief Wait untill user input or window state will be changed
69 /// @brief Wait untill user input or window state will be changed.
70 70 /// Same as glfwPollEvents, but it will wait untill something to update. /// Same as glfwPollEvents, but it will wait untill something to update.
71 71 /// Recommended for interactive window usage /// Recommended for interactive window usage
72 72 /// @see glfwWaitEvents /// @see glfwWaitEvents
73 73 static void wait() { static void wait() {
74 74 glfwWaitEvents(); glfwWaitEvents();
75 75 } }
76 /// @brief Check if user want to close the window
76 /// @brief Check if user want to close the window.
77 77 /// @see glfwWindowShouldClose /// @see glfwWindowShouldClose
78 78 [[nodiscard]] bool is_window_close_fired() const { [[nodiscard]] bool is_window_close_fired() const {
79 79 return glfwWindowShouldClose(p_window) == GLFW_TRUE; return glfwWindowShouldClose(p_window) == GLFW_TRUE;
80 80 } }
81 /// @brief Use monitor directly without window manager
81 /// @brief Use monitor directly without window manager.
82 82 void set_fullscreen() { void set_fullscreen() {
83 83 if (not is_fullscreen) { if (not is_fullscreen) {
84 84 old_window_data.extent = extent; old_window_data.extent = extent;
 
... ... struct jen::Window
90 90 is_fullscreen = true; is_fullscreen = true;
91 91 } }
92 92 } }
93 /// @brief Use window manager instead of fullscreen
93 /// @brief Use window manager instead of fullscreen.
94 94 void set_windowed() { void set_windowed() {
95 95 if (is_fullscreen) { if (is_fullscreen) {
96 96 glfwSetWindowMonitor(p_window, nullptr, old_window_data.position.x, glfwSetWindowMonitor(p_window, nullptr, old_window_data.position.x,
 
... ... struct jen::Window
100 100 is_fullscreen = false; is_fullscreen = false;
101 101 } }
102 102 } }
103 /// @brief Set fullscreen mode from windowed or windowed from fullscreen
103 /// @brief Set fullscreen mode from windowed or windowed from fullscreen.
104 104 void toggle_fullscreen() { void toggle_fullscreen() {
105 105 if (is_fullscreen) if (is_fullscreen)
106 106 set_windowed(); set_windowed();
107 107 else else
108 108 set_fullscreen(); set_fullscreen();
109 109 } }
110 /// @brief Get monitor refresh rate
110 /// @brief Get monitor refresh rate.
111 111 /// @see glfwGetVideoMode /// @see glfwGetVideoMode
112 112 [[nodiscard]] int refresh_rate() { [[nodiscard]] int refresh_rate() {
113 113 auto monitor = glfwGetPrimaryMonitor(); auto monitor = glfwGetPrimaryMonitor();
 
... ... struct jen::Window
120 120 void window_close_fire() { void window_close_fire() {
121 121 glfwSetWindowShouldClose(p_window, GLFW_TRUE); glfwSetWindowShouldClose(p_window, GLFW_TRUE);
122 122 } }
123 /// @brief Set cursor to hidden or disabled or normal mode
123 /// @brief Set cursor to hidden or disabled or normal mode.
124 124 /// @see glfwSetInputMode /// @see glfwSetInputMode
125 125 void set_cursor_mode(CursorMode mode) { void set_cursor_mode(CursorMode mode) {
126 126 glfwSetInputMode(p_window, GLFW_CURSOR, int(mode)); glfwSetInputMode(p_window, GLFW_CURSOR, int(mode));
127 127 } }
128 /// @brief Get current cursor mode
128 /// @brief Get current cursor mode.
129 129 [[nodiscard]] CursorMode get_cursor_mode() const { [[nodiscard]] CursorMode get_cursor_mode() const {
130 130 return CursorMode(glfwGetInputMode(p_window, GLFW_CURSOR)); return CursorMode(glfwGetInputMode(p_window, GLFW_CURSOR));
131 131 } }
132 /// @brief Window data type will be converted to GLFWwindow* silently
132 /// @brief Window data type will be converted to GLFWwindow* silently.
133 133 operator GLFWwindow* () { return p_window; } operator GLFWwindow* () { return p_window; }
134 134 /// @brief This data is used to restore window position and size /// @brief This data is used to restore window position and size
135 135 /// as before fullscreen. /// as before fullscreen.
 
... ... struct jen::Window
166 166 /// User cursor position /// User cursor position
167 167 Cursor cursor; Cursor cursor;
168 168 }; };
169 /// @brief Button state helper
169 /// @brief Button state helper.
170 170 struct jen::Button { struct jen::Button {
171 /// @brief Function to get user input without repeating
171 /// @brief Function to get user input without repeating.
172 172 /// @param key key code to check state on /// @param key key code to check state on
173 173 /// @param w window handle to get input from /// @param w window handle to get input from
174 174 /// @return true if button is pressed if and only if it was not pressed /// @return true if button is pressed if and only if it was not pressed
 
... ... struct jen::Button {
182 182 } }
183 183 return false; return false;
184 184 } }
185 Key::State state; /// Last known state of key
185 Key::State state; ///< Last known state of key
186 186 }; };
File src/graphics/graphics.cpp changed (mode: 100644) (index c262565..f1fae91)
4 4
5 5 using namespace jen; using namespace jen;
6 6 using namespace jen::vk; using namespace jen::vk;
7 using GraphicsData = ModuleGraphics::Data;
7 8
8 9 void cmd_transfer_clusters(GraphicsData *p_g, vkw::CmdBuffer cmd) { void cmd_transfer_clusters(GraphicsData *p_g, vkw::CmdBuffer cmd) {
9 10 auto &cb = p_g->stages.clusters_buffer; auto &cb = p_g->stages.clusters_buffer;
 
... ... void cmd_primary_shadow_map_models(GraphicsData *p_g, vkw::CmdBuffer cmd)
159 160
160 161 ModelWorld shader_data = model.world; { ModelWorld shader_data = model.world; {
161 162 shader_data.position -= draw_data.shadow_light.pos; shader_data.position -= draw_data.shadow_light.pos;
162 for (auto &c : shader_data.position_shift)
163 c <<= draw_data.camera.shift_po2;
164 shader_data.position += shader_data.position_shift;
163 for (auto &c : shader_data.position_offset)
164 c <<= draw_data.camera.offset_shift;
165 shader_data.position += shader_data.position_offset;
165 166 shader_data.transform *= jm::translation(shader_data.position); shader_data.transform *= jm::translation(shader_data.position);
166 167 } }
167 168 cmd.cmd_set_pushs(stage_sho.layout, stages::Offscreen::PUSH_VERT_RANGE, cmd.cmd_set_pushs(stage_sho.layout, stages::Offscreen::PUSH_VERT_RANGE,
 
... ... REPEAT_MODELS:
208 209
209 210 ModelWorld shader_data = model.world; { ModelWorld shader_data = model.world; {
210 211 shader_data.position -= draw_data.camera.position; shader_data.position -= draw_data.camera.position;
211 auto shift = shader_data.position_shift - draw_data.camera.pos_offset;
212 auto shift = shader_data.position_offset - draw_data.camera.pos_offset;
212 213 for (auto &c : shift) for (auto &c : shift)
213 c <<= draw_data.camera.shift_po2;
214 c <<= draw_data.camera.offset_shift;
214 215 shader_data.position += shift; shader_data.position += shift;
215 216 shader_data.transform *= jm::translation(shader_data.position); shader_data.transform *= jm::translation(shader_data.position);
216 217 } }
File src/graphics/graphics.h changed (mode: 100644) (index 7a8776e..5a272a8)
5 5 #include <jlib/time.h> #include <jlib/time.h>
6 6 #include <jen/graphics.h> #include <jen/graphics.h>
7 7
8 struct jen::GraphicsData {
9
8 namespace jen { struct DebugOverlay; }
9 struct jen::ModuleGraphics::Data
10 {
10 11 [[nodiscard]] Result [[nodiscard]] Result
11 12 init(Instance*, Device*, const GraphicsSettings&); init(Instance*, Device*, const GraphicsSettings&);
12 13
File src/graphics/graphics_interface.cpp changed (mode: 100644) (index a51d41b..517cce9)
5 5 using namespace jen; using namespace jen;
6 6 using namespace jen::vk; using namespace jen::vk;
7 7
8 [[nodiscard]] Result GraphicsData::
8 [[nodiscard]] Result ModuleGraphics::Data::
9 9 init(Instance *p_inst, Device *p_dev, const GraphicsSettings &setts) init(Instance *p_inst, Device *p_dev, const GraphicsSettings &setts)
10 10 { {
11 11 p_instance = p_inst; p_instance = p_inst;
 
... ... EXIT:
76 76 return res; return res;
77 77 } }
78 78
79 void GraphicsData::destroy(int code)
79 void ModuleGraphics::Data::
80 destroy(int code)
80 81 { {
81 82 (void)p_device->device.wait_idle(); (void)p_device->device.wait_idle();
82 83
 
... ... void ModuleGraphics::destroy(GpuData *p_data, bool destroy_source) {
123 124 } }
124 125
125 126 [[nodiscard]] Result ModuleGraphics:: [[nodiscard]] Result ModuleGraphics::
126 create(const jrf::Image *p_t, GpuTexture **pp_dst, bool free_source){
127 create(const jrf::Image &im, GpuTexture **pp_dst, bool free_source){
127 128 if (not jl::allocate(pp_dst)) if (not jl::allocate(pp_dst))
128 129 return VK_ERROR_OUT_OF_HOST_MEMORY; return VK_ERROR_OUT_OF_HOST_MEMORY;
129 (*pp_dst)->init(p_t, free_source);
130 (*pp_dst)->init(im, free_source);
130 131 auto r = p->gpu_transfer.submit(GpuTransfer::Priority::LOW, auto r = p->gpu_transfer.submit(GpuTransfer::Priority::LOW,
131 132 *pp_dst, p->stages.textureSampler); *pp_dst, p->stages.textureSampler);
132 133 if (r != VK_SUCCESS) if (r != VK_SUCCESS)
 
... ... update_from_input(Window *p_window)
266 267 return graphics_changed; return graphics_changed;
267 268 } }
268 269
269 void ModuleGraphics::Loop::
270 run(ModuleGraphics mg, void *p_update_arg, PF_User pf_update)
270 void DrawFrameLoop::
271 run(ModuleGraphics mg, void *p_update_arg, void(*pf_update)(void*))
271 272 { {
272 273 result = VK_SUCCESS; result = VK_SUCCESS;
273 274 pause = false; pause = false;
 
... ... run(ModuleGraphics mg, void *p_update_arg, PF_User pf_update)
279 280 last_update_time = jl::time::current(); last_update_time = jl::time::current();
280 281 elapsed_after_update = {}; elapsed_after_update = {};
281 282
282 bool pause_hold = false;
283 Button pause_button = {};
283 284
284 285 auto &window = mg.p->p_instance->window; auto &window = mg.p->p_instance->window;
285 286 window.set_visibility(true); window.set_visibility(true);
286 287
287 288 while (not window.is_window_close_fired()) while (not window.is_window_close_fired())
288 289 { {
289 if (pause_hold)
290 if (not window.is_on(Key::kPAUSE) and not window.is_on(Key::P))
291 pause_hold = false;
292 if (pause_hold == false
293 and (window.is_on(Key::kPAUSE) or window.is_on(Key::P))) {
290 if (pause_button.is_fired(Key::kPAUSE, window))
294 291 pause = not pause; pause = not pause;
295 pause_hold = true;
296 }
297 292
298 293 if (wait_events) if (wait_events)
299 294 mg.p->p_instance->window.wait(); mg.p->p_instance->window.wait();
File src/graphics/resources.h changed (mode: 100644) (index cbbea01..c8bd2f0)
... ... struct jen::GpuData {
21 21 static_assert(jen::GPU_DATA_ALLOCATION_SIZE == sizeof(jen::GpuData)); static_assert(jen::GPU_DATA_ALLOCATION_SIZE == sizeof(jen::GpuData));
22 22
23 23 struct jen::GpuTexture { struct jen::GpuTexture {
24 void init(const jrf::Image *p_src, bool destroy_source) {
24 void init(const jrf::Image &src, bool destroy_source) {
25 25 state = ResourceState::LOADING; state = ResourceState::LOADING;
26 26 is_source_destroy_allowed = destroy_source; is_source_destroy_allowed = destroy_source;
27 source = *p_src;
28 mip_levels = mip_level(p_src->extent.width, p_src->extent.height);
27 source = src;
28 mip_levels = mip_level(src.extent.width, src.extent.height);
29 29 } }
30 30 void destroy_source_if_allowed() { void destroy_source_if_allowed() {
31 31 if (is_source_destroy_allowed) { if (is_source_destroy_allowed) {
File src/resource_manager/resource_manager.cpp changed (mode: 100644) (index 7c5c6cc..c7cc81e)
... ... create_render(jen::ModuleGraphics mg, jrf::Indices *p_jrf, jen::IndexData *p)
167 167 create_render(jen::ModuleGraphics mg, jrf::Image *p_jrf, jen::TextureData *p) create_render(jen::ModuleGraphics mg, jrf::Image *p_jrf, jen::TextureData *p)
168 168 { {
169 169 p->layer_index = 0; p->layer_index = 0;
170 auto res = mg.create(p_jrf, &p->p_data, true);
170 auto res = mg.create(*p_jrf, &p->p_data, true);
171 171 if (res == VK_SUCCESS) if (res == VK_SUCCESS)
172 172 *p_jrf = {}; *p_jrf = {};
173 173 return res; return res;
 
... ... create_scene(const jl::string_ro &path, uint32_t shift_scale, SceneData *p_dst)
625 625 "checking memcpy"); "checking memcpy");
626 626
627 627 for (unsigned int c = 0; c < 3; ++c) for (unsigned int c = 0; c < 3; ++c)
628 ed.world.position_shift[c]
628 ed.world.position_offset[c]
629 629 = (e.options.shift[c] + scene.options.shift[c]) << scale_diff; = (e.options.shift[c] + scene.options.shift[c]) << scale_diff;
630 630 } }
631 631
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