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/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/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_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(); |