Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • 119-graphicspipeline-refactoring
  • 129-projekte-und-assets-auslagern
  • 132-denoising-module
  • 143-ar-vr-support-via-openxr
  • 43-multi-threading
  • 91-compute-first-network
  • 95-arm64-raspberry-pi-4-support
  • develop
  • master
  • optimizations
  • 0.1.0
  • 0.2.0
12 results

Target

Select target project
  • vulkan2021/vkcv-framework
1 result
Select Git revision
  • 119-graphicspipeline-refactoring
  • 129-projekte-und-assets-auslagern
  • 132-denoising-module
  • 143-ar-vr-support-via-openxr
  • 43-multi-threading
  • 91-compute-first-network
  • 95-arm64-raspberry-pi-4-support
  • develop
  • master
  • optimizations
  • 0.1.0
  • 0.2.0
12 results
Show changes
Commits on Source (124)
Showing
with 1082 additions and 574 deletions
...@@ -23,7 +23,7 @@ build_ubuntu_gcc: ...@@ -23,7 +23,7 @@ build_ubuntu_gcc:
- mkdir debug - mkdir debug
- cd debug - cd debug
- cmake -DCMAKE_BUILD_TYPE=Debug .. - cmake -DCMAKE_BUILD_TYPE=Debug ..
- cmake --build . - cmake --build . -j 4
artifacts: artifacts:
name: "Documentation - $CI_PIPELINE_ID" name: "Documentation - $CI_PIPELINE_ID"
paths: paths:
...@@ -49,7 +49,7 @@ build_win10_msvc: ...@@ -49,7 +49,7 @@ build_win10_msvc:
- mkdir debug - mkdir debug
- cd debug - cd debug
- cmake -DCMAKE_BUILD_TYPE=Debug .. - cmake -DCMAKE_BUILD_TYPE=Debug ..
- cmake --build . - cmake --build . -j 4
build_win10_mingw: build_win10_mingw:
only: only:
...@@ -66,7 +66,7 @@ build_win10_mingw: ...@@ -66,7 +66,7 @@ build_win10_mingw:
- mkdir debug - mkdir debug
- cd debug - cd debug
- cmake --no-warn-unused-cli -DCMAKE_EXPORT_COMPILE_COMMANDS:BOOL=TRUE -DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_C_COMPILER:FILEPATH=C:\msys64\mingw64\bin\x86_64-w64-mingw32-gcc.exe -DCMAKE_CXX_COMPILER:FILEPATH=C:\msys64\mingw64\bin\x86_64-w64-mingw32-g++.exe .. -G "Unix Makefiles" - cmake --no-warn-unused-cli -DCMAKE_EXPORT_COMPILE_COMMANDS:BOOL=TRUE -DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_C_COMPILER:FILEPATH=C:\msys64\mingw64\bin\x86_64-w64-mingw32-gcc.exe -DCMAKE_CXX_COMPILER:FILEPATH=C:\msys64\mingw64\bin\x86_64-w64-mingw32-g++.exe .. -G "Unix Makefiles"
- cmake --build . -j 8 - cmake --build . -j 4
build_mac_clang: build_mac_clang:
only: only:
...@@ -85,7 +85,7 @@ build_mac_clang: ...@@ -85,7 +85,7 @@ build_mac_clang:
- export LDFLAGS="-L/usr/local/opt/llvm/lib" - export LDFLAGS="-L/usr/local/opt/llvm/lib"
- export CPPFLAGS="-I/usr/local/opt/llvm/include" - export CPPFLAGS="-I/usr/local/opt/llvm/include"
- cmake -DCMAKE_C_COMPILER="/usr/local/opt/llvm/bin/clang" -DCMAKE_CXX_COMPILER="/usr/local/opt/llvm/bin/clang++" -DCMAKE_BUILD_TYPE=Debug .. - cmake -DCMAKE_C_COMPILER="/usr/local/opt/llvm/bin/clang" -DCMAKE_CXX_COMPILER="/usr/local/opt/llvm/bin/clang++" -DCMAKE_BUILD_TYPE=Debug ..
- cmake --build . - cmake --build . -j 4
deploy_doc_develop: deploy_doc_develop:
only: only:
......
...@@ -22,9 +22,6 @@ ...@@ -22,9 +22,6 @@
[submodule "modules/gui/lib/imgui"] [submodule "modules/gui/lib/imgui"]
path = modules/gui/lib/imgui path = modules/gui/lib/imgui
url = https://github.com/ocornut/imgui.git url = https://github.com/ocornut/imgui.git
[submodule "lib/VulkanMemoryAllocator"]
path = lib/VulkanMemoryAllocator
url = https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git
[submodule "lib/VulkanMemoryAllocator-Hpp"] [submodule "lib/VulkanMemoryAllocator-Hpp"]
path = lib/VulkanMemoryAllocator-Hpp path = lib/VulkanMemoryAllocator-Hpp
url = https://github.com/malte-v/VulkanMemoryAllocator-Hpp.git url = https://github.com/malte-v/VulkanMemoryAllocator-Hpp.git
......
...@@ -76,8 +76,8 @@ namespace vkcv { ...@@ -76,8 +76,8 @@ namespace vkcv {
{} {}
[[nodiscard]] [[nodiscard]]
static Buffer<T> create(BufferManager* manager, BufferType type, size_t count, BufferMemoryType memoryType) { static Buffer<T> create(BufferManager* manager, BufferType type, size_t count, BufferMemoryType memoryType, bool supportIndirect) {
return Buffer<T>(manager, manager->createBuffer(type, count * sizeof(T), memoryType), type, count, memoryType); return Buffer<T>(manager, manager->createBuffer(type, count * sizeof(T), memoryType, supportIndirect), type, count, memoryType);
} }
}; };
......
...@@ -70,7 +70,7 @@ namespace vkcv ...@@ -70,7 +70,7 @@ namespace vkcv
* @param memoryType Type of buffers memory * @param memoryType Type of buffers memory
* @return New buffer handle * @return New buffer handle
*/ */
BufferHandle createBuffer(BufferType type, size_t size, BufferMemoryType memoryType); BufferHandle createBuffer(BufferType type, size_t size, BufferMemoryType memoryType, bool supportIndirect);
/** /**
* Returns the Vulkan buffer handle of a buffer * Returns the Vulkan buffer handle of a buffer
......
...@@ -185,8 +185,8 @@ namespace vkcv ...@@ -185,8 +185,8 @@ namespace vkcv
* return Buffer-Object * return Buffer-Object
*/ */
template<typename T> template<typename T>
Buffer<T> createBuffer(vkcv::BufferType type, size_t count, BufferMemoryType memoryType = BufferMemoryType::DEVICE_LOCAL) { Buffer<T> createBuffer(vkcv::BufferType type, size_t count, BufferMemoryType memoryType = BufferMemoryType::DEVICE_LOCAL, bool supportIndirect = false) {
return Buffer<T>::create(m_BufferManager.get(), type, count, memoryType); return Buffer<T>::create(m_BufferManager.get(), type, count, memoryType, supportIndirect);
} }
/** /**
...@@ -271,6 +271,14 @@ namespace vkcv ...@@ -271,6 +271,14 @@ namespace vkcv
const std::vector<DescriptorSetUsage> &descriptorSetUsages, const std::vector<DescriptorSetUsage> &descriptorSetUsages,
const PushConstants& pushConstants); const PushConstants& pushConstants);
void recordComputeIndirectDispatchToCmdStream(
const CommandStreamHandle cmdStream,
const PipelineHandle computePipeline,
const vkcv::BufferHandle buffer,
const size_t bufferArgOffset,
const std::vector<DescriptorSetUsage>& descriptorSetUsages,
const PushConstants& pushConstants);
/** /**
* @brief end recording and present image * @brief end recording and present image
*/ */
......
...@@ -29,8 +29,19 @@ namespace vkcv { ...@@ -29,8 +29,19 @@ namespace vkcv {
}; };
struct Mesh { struct Mesh {
inline Mesh(std::vector<VertexBufferBinding> vertexBufferBindings, vk::Buffer indexBuffer, size_t indexCount, IndexBitCount indexBitCount = IndexBitCount::Bit16) noexcept
: vertexBufferBindings(vertexBufferBindings), indexBuffer(indexBuffer), indexCount(indexCount), indexBitCount(indexBitCount){} inline Mesh(){}
inline Mesh(
std::vector<VertexBufferBinding> vertexBufferBindings,
vk::Buffer indexBuffer,
size_t indexCount,
IndexBitCount indexBitCount = IndexBitCount::Bit16) noexcept
:
vertexBufferBindings(vertexBufferBindings),
indexBuffer(indexBuffer),
indexCount(indexCount),
indexBitCount(indexBitCount) {}
std::vector<VertexBufferBinding> vertexBufferBindings; std::vector<VertexBufferBinding> vertexBufferBindings;
vk::Buffer indexBuffer; vk::Buffer indexBuffer;
......
...@@ -53,9 +53,10 @@ namespace vkcv { ...@@ -53,9 +53,10 @@ namespace vkcv {
VKCV_DEBUG_MESSAGE_LEN, \ VKCV_DEBUG_MESSAGE_LEN, \
__VA_ARGS__ \ __VA_ARGS__ \
); \ ); \
auto output = getLogOutput(level); \
if (level != vkcv::LogLevel::RAW_INFO) { \ if (level != vkcv::LogLevel::RAW_INFO) { \
fprintf( \ fprintf( \
getLogOutput(level), \ output, \
"[%s]: %s [%s, line %d: %s]\n", \ "[%s]: %s [%s, line %d: %s]\n", \
vkcv::getLogName(level), \ vkcv::getLogName(level), \
output_message, \ output_message, \
...@@ -65,12 +66,13 @@ namespace vkcv { ...@@ -65,12 +66,13 @@ namespace vkcv {
); \ ); \
} else { \ } else { \
fprintf( \ fprintf( \
getLogOutput(level), \ output, \
"[%s]: %s\n", \ "[%s]: %s\n", \
vkcv::getLogName(level), \ vkcv::getLogName(level), \
output_message \ output_message \
); \ ); \
} \ } \
fflush(output); \
} }
#else #else
......
...@@ -31,10 +31,10 @@ include(config/FX_GLTF.cmake) ...@@ -31,10 +31,10 @@ include(config/FX_GLTF.cmake)
include(config/STB.cmake) include(config/STB.cmake)
# link the required libraries to the module # link the required libraries to the module
target_link_libraries(vkcv_asset_loader ${vkcv_asset_loader_libraries} vkcv) target_link_libraries(vkcv_asset_loader ${vkcv_asset_loader_libraries} vkcv ${vkcv_libraries})
# including headers of dependencies and the VkCV framework # including headers of dependencies and the VkCV framework
target_include_directories(vkcv_asset_loader SYSTEM BEFORE PRIVATE ${vkcv_asset_loader_includes}) target_include_directories(vkcv_asset_loader SYSTEM BEFORE PRIVATE ${vkcv_asset_loader_includes} ${vkcv_includes})
# add the own include directory for public headers # add the own include directory for public headers
target_include_directories(vkcv_asset_loader BEFORE PUBLIC ${vkcv_asset_loader_include}) target_include_directories(vkcv_asset_loader BEFORE PUBLIC ${vkcv_asset_loader_include})
......
...@@ -11,17 +11,7 @@ ...@@ -11,17 +11,7 @@
#include <cstdint> #include <cstdint>
#include <filesystem> #include <filesystem>
/** These macros define limits of the following structs. Implementations can /* LOADING MESHES
* test against these limits when performing sanity checks. The main constraint
* expressed is that of the data type: Material indices are identified by a
* uint8_t in the VertexGroup struct, so there can't be more than UINT8_MAX
* materials in the mesh. Should these limits be too narrow, the data type has
* to be changed, but the current ones should be generous enough for most use
* cases. */
#define MAX_MATERIALS_PER_MESH UINT8_MAX
#define MAX_VERTICES_PER_VERTEX_GROUP UINT32_MAX
/** LOADING MESHES
* The description of meshes is a hierarchy of structures with the Mesh at the * The description of meshes is a hierarchy of structures with the Mesh at the
* top. * top.
* *
...@@ -46,53 +36,89 @@ ...@@ -46,53 +36,89 @@
namespace vkcv::asset { namespace vkcv::asset {
/** This enum matches modes in fx-gltf, the library returns a standard mode /**
* (TRIANGLES) if no mode is given in the file. */ * These return codes are limited to the asset loader module. If unified return
* codes are defined for the vkcv framework, these will be used instead.
*/
#define ASSET_ERROR 0
#define ASSET_SUCCESS 1
/**
* This enum matches modes in fx-gltf, the library returns a standard mode
* (TRIANGLES) if no mode is given in the file.
*/
enum class PrimitiveMode : uint8_t { enum class PrimitiveMode : uint8_t {
POINTS=0, LINES, LINELOOP, LINESTRIP, TRIANGLES, TRIANGLESTRIP, POINTS = 0,
TRIANGLEFAN LINES = 1,
LINELOOP = 2,
LINESTRIP = 3,
TRIANGLES = 4,
TRIANGLESTRIP = 5,
TRIANGLEFAN = 6
}; };
/** The indices in the index buffer can be of different bit width. */ /**
enum class IndexType : uint8_t { UNDEFINED=0, UINT8=1, UINT16=2, UINT32=3 }; * The indices in the index buffer can be of different bit width.
*/
typedef struct { enum class IndexType : uint8_t {
// TODO define struct for samplers (low priority) UNDEFINED=0,
// NOTE: glTF defines samplers based on OpenGL, which can not be UINT8=1,
// directly translated to Vulkan. Specifically, OpenGL (and glTF) UINT16=2,
// define a different set of Min/Mag-filters than Vulkan. UINT32=3
} Sampler; };
/** struct for defining the loaded texture */
typedef struct {
int sampler; // index into the sampler array of the Scene
uint8_t channels; // number of channels
uint16_t w, h; // width and height of the texture
std::vector<uint8_t> data; // binary data of the decoded texture
} Texture;
/** The asset loader module only supports the PBR-MetallicRoughness model for /**
* materials.*/ * This struct defines a sampler for a texture object. All values here can
typedef struct { * directly be passed to VkSamplerCreateInfo.
uint16_t textureMask; // bit mask with active texture targets * NOTE that glTF defines samplers based on OpenGL, which can not be directly
// Indices into the Array.textures array * translated to Vulkan. The vkcv::asset::Sampler struct defined here adheres
int baseColor, metalRough, normal, occlusion, emissive; * to the Vulkan spec, having alerady translated the flags from glTF to Vulkan.
// Scaling factors for each texture target * Since glTF does not specify border sampling for more than two dimensions,
struct { float r, g, b, a; } baseColorFactor; * the addressModeW is hardcoded to a default: VK_SAMPLER_ADDRESS_MODE_REPEAT.
float metallicFactor, roughnessFactor; */
float normalScale; struct Sampler {
float occlusionStrength; int minFilter, magFilter;
struct { float r, g, b; } emissiveFactor; int mipmapMode;
} Material; float minLOD, maxLOD;
int addressModeU, addressModeV, addressModeW;
};
/** Flags for the bit-mask in the Material struct. To check if a material has a /**
* This struct describes a (partially) loaded texture.
* The data member is not populated after calling probeScene() but only when
* calling loadMesh(), loadScene() or loadTexture(). Note that textures are
* currently always loaded with 4 channels as RGBA, even if the image has just
* RGB or is grayscale. In the case where the glTF-file does not provide a URI
* but references a buffer view for the raw data, the path member will be empty
* even though the rest is initialized properly.
* NOTE: Loading textures without URI is untested.
*/
struct Texture {
std::filesystem::path path; // URI to the encoded texture data
int sampler; // index into the sampler array of the Scene
union { int width; int w; };
union { int height; int h; };
int channels;
std::vector<uint8_t> data; // binary data of the decoded texture
};
/**
* Flags for the bit-mask in the Material struct. To check if a material has a
* certain texture target, you can use the hasTexture() function below, passing * certain texture target, you can use the hasTexture() function below, passing
* the material struct and the enum. */ * the material struct and the enum.
*/
enum class PBRTextureTarget { enum class PBRTextureTarget {
baseColor=1, metalRough=2, normal=4, occlusion=8, emissive=16 baseColor=1,
metalRough=2,
normal=4,
occlusion=8,
emissive=16
}; };
/** This macro translates the index of an enum in the defined order to an /**
* This macro translates the index of an enum in the defined order to an
* integer with a single bit set in the corresponding place. It is used for * integer with a single bit set in the corresponding place. It is used for
* working with the bitmask of texture targets ("textureMask") in the Material * working with the bitmask of texture targets ("textureMask") in the Material
* struct: * struct:
...@@ -103,100 +129,196 @@ enum class PBRTextureTarget { ...@@ -103,100 +129,196 @@ enum class PBRTextureTarget {
* contact with bit-level operations. */ * contact with bit-level operations. */
#define bitflag(ENUM) (0x1u << ((unsigned)(ENUM))) #define bitflag(ENUM) (0x1u << ((unsigned)(ENUM)))
/** To signal that a certain texture target is active in a Material struct, its /**
* bit is set in the textureMask. You can use this function to check that: * The asset loader module only supports the PBR-MetallicRoughness model for
* Material mat = ...; * materials.
* if (materialHasTexture(&mat, baseColor)) {...} */ */
bool materialHasTexture(const Material *const m, const PBRTextureTarget t); struct Material {
uint16_t textureMask; // bit mask with active texture targets
// Indices into the Scene.textures vector
int baseColor, metalRough, normal, occlusion, emissive;
// Scaling factors for each texture target
struct { float r, g, b, a; } baseColorFactor;
float metallicFactor, roughnessFactor;
float normalScale;
float occlusionStrength;
struct { float r, g, b; } emissiveFactor;
/**
* To signal that a certain texture target is active in this Material
* struct, its bit is set in the textureMask. You can use this function
* to check that:
* if (myMaterial.hasTexture(baseColor)) {...}
*
* @param t The target to query for
* @return Boolean to signal whether the texture target is active in
* the material.
*/
bool hasTexture(PBRTextureTarget target) const;
};
/** With these enums, 0 is reserved to signal uninitialized or invalid data. */ /* With these enums, 0 is reserved to signal uninitialized or invalid data. */
enum class PrimitiveType : uint32_t { enum class PrimitiveType : uint32_t {
UNDEFINED = 0, UNDEFINED = 0,
POSITION = 1, POSITION = 1,
NORMAL = 2, NORMAL = 2,
TEXCOORD_0 = 3, TEXCOORD_0 = 3,
TEXCOORD_1 = 4, TEXCOORD_1 = 4,
TANGENT = 5 TANGENT = 5,
COLOR_0 = 6,
COLOR_1 = 7,
JOINTS_0 = 8,
WEIGHTS_0 = 9
}; };
/** These integer values are used the same way in OpenGL, Vulkan and glTF. This /**
* These integer values are used the same way in OpenGL, Vulkan and glTF. This
* enum is not needed for translation, it's only for the programmers * enum is not needed for translation, it's only for the programmers
* convenience (easier to read in if/switch statements etc). While this enum * convenience (easier to read in if/switch statements etc). While this enum
* exists in (almost) the same definition in the fx-gltf library, we want to * exists in (almost) the same definition in the fx-gltf library, we want to
* avoid exposing that dependency, thus it is re-defined here. */ * avoid exposing that dependency, thus it is re-defined here.
*/
enum class ComponentType : uint16_t { enum class ComponentType : uint16_t {
NONE = 0, INT8 = 5120, UINT8 = 5121, INT16 = 5122, UINT16 = 5123, NONE = 0,
UINT32 = 5125, FLOAT32 = 5126 INT8 = 5120,
UINT8 = 5121,
INT16 = 5122,
UINT16 = 5123,
UINT32 = 5125,
FLOAT32 = 5126
}; };
/** This struct describes one vertex attribute of a vertex buffer. */ /**
typedef struct { * This struct describes one vertex attribute of a vertex buffer.
*/
struct VertexAttribute {
PrimitiveType type; // POSITION, NORMAL, ... PrimitiveType type; // POSITION, NORMAL, ...
uint32_t offset; // offset in bytes uint32_t offset; // offset in bytes
uint32_t length; // length of ... in bytes uint32_t length; // length of ... in bytes
uint32_t stride; // stride in bytes uint32_t stride; // stride in bytes
ComponentType componentType; // eg. 5126 for float
uint8_t componentCount; // eg. 3 for vec3 ComponentType componentType; // eg. 5126 for float
} VertexAttribute; uint8_t componentCount; // eg. 3 for vec3
};
/** This struct represents one (possibly the only) part of a mesh. There is /**
* This struct represents one (possibly the only) part of a mesh. There is
* always one vertexBuffer and zero or one indexBuffer (indexed rendering is * always one vertexBuffer and zero or one indexBuffer (indexed rendering is
* common but not always used). If there is no index buffer, this is indicated * common but not always used). If there is no index buffer, this is indicated
* by indexBuffer.data being empty. Each vertex buffer can have one or more * by indexBuffer.data being empty. Each vertex buffer can have one or more
* vertex attributes. */ * vertex attributes.
typedef struct { */
struct VertexGroup {
enum PrimitiveMode mode; // draw as points, lines or triangle? enum PrimitiveMode mode; // draw as points, lines or triangle?
size_t numIndices, numVertices; size_t numIndices;
size_t numVertices;
struct { struct {
enum IndexType type; // data type of the indices enum IndexType type; // data type of the indices
std::vector<uint8_t> data; // binary data of the index buffer std::vector<uint8_t> data; // binary data of the index buffer
} indexBuffer; } indexBuffer;
struct { struct {
std::vector<uint8_t> data; // binary data of the vertex buffer std::vector<uint8_t> data; // binary data of the vertex buffer
std::vector<VertexAttribute> attributes; // description of one std::vector<VertexAttribute> attributes; // description of one
} vertexBuffer; } vertexBuffer;
struct { float x, y, z; } min; // bounding box lower left struct { float x, y, z; } min; // bounding box lower left
struct { float x, y, z; } max; // bounding box upper right struct { float x, y, z; } max; // bounding box upper right
int materialIndex; // index to one of the materials int materialIndex; // index to one of the materials
} VertexGroup; };
/** This struct represents a single mesh as it was loaded from a glTF file. It /**
* This struct represents a single mesh as it was loaded from a glTF file. It
* consists of at least one VertexGroup, which then references other resources * consists of at least one VertexGroup, which then references other resources
* such as Materials. */ * such as Materials.
typedef struct { */
struct Mesh {
std::string name; std::string name;
std::array<float, 16> modelMatrix; std::array<float, 16> modelMatrix;
std::vector<int> vertexGroups; std::vector<int> vertexGroups;
} Mesh; };
/** The scene struct is simply a collection of objects in the scene as well as /**
* The scene struct is simply a collection of objects in the scene as well as
* the resources used by those objects. * the resources used by those objects.
* For now the only type of object are the meshes and they are represented in a * Note that parent-child relations are not yet possible.
* flat array. */
* Note that parent-child relations are not yet possible. */ struct Scene {
typedef struct {
std::vector<Mesh> meshes; std::vector<Mesh> meshes;
std::vector<VertexGroup> vertexGroups; std::vector<VertexGroup> vertexGroups;
std::vector<Material> materials; std::vector<Material> materials;
std::vector<Texture> textures; std::vector<Texture> textures;
std::vector<Sampler> samplers; std::vector<Sampler> samplers;
} Scene; std::vector<std::string> uris;
};
/** /**
* Load every mesh from the glTF file, as well as materials and textures. * Parse the given glTF file and create a shallow description of the content.
* Only the meta-data of the objects in the scene is loaded, not the binary
* content. The rationale is to provide a means of probing the content of a
* glTF file without the costly process of loading and decoding large amounts
* of data. The returned Scene struct can be used to search for specific meshes
* in the scene, that can then be loaded on their own using the loadMesh()
* function. Note that the Scene struct received as output argument will be
* overwritten by this function.
* After this function completes, the returned Scene struct is completely
* initialized and all information is final, except for the missing binary
* data. This means that indices to vectors will remain valid even when the
* shallow scene struct is filled with data by loadMesh().
* Note that for URIs only (local) filesystem paths are supported, no
* URLs using network protocols etc.
* *
* @param path must be the path to a glTF or glb file. * @param path must be the path to a glTF- or glb-file.
* @param scene is a reference to a Scene struct that will be filled with the
* meta-data of all objects described in the glTF file.
* @return ASSET_ERROR on failure, otherwise ASSET_SUCCESS
*/
int probeScene(const std::filesystem::path &path, Scene &scene);
/**
* This function loads a single mesh from the given file and adds it to the
* given scene. The scene must already be initialized (via probeScene()).
* The mesh_index refers to the Scenes meshes array and identifies the mesh to
* load. To find the mesh you want, iterate over the probed scene and check the
* meshes details (eg. name).
* Besides the mesh, this function will also add any associated data to the
* Scene struct such as Materials and Textures required by the Mesh.
*
* @param path must be the path to a glTF- or glb-file.
* @param scene is the scene struct to which the results will be written.
* @return ASSET_ERROR on failure, otherwise ASSET_SUCCESS
*/
int loadMesh(Scene &scene, int mesh_index);
/**
* Load every mesh from the glTF file, as well as materials, textures and other
* associated objects.
*
* @param path must be the path to a glTF- or glb-file.
* @param scene is a reference to a Scene struct that will be filled with the * @param scene is a reference to a Scene struct that will be filled with the
* content of the glTF file being loaded. * content of the glTF file being loaded.
* */ * @return ASSET_ERROR on failure, otherwise ASSET_SUCCESS
int loadScene(const std::string &path, Scene &scene); */
int loadScene(const std::filesystem::path &path, Scene &scene);
struct TextureData {
int width; /**
int height; * Simply loads a single image at the given path and returns a Texture
int componentCount; * struct describing it. This is for special use cases only (eg.
std::vector<char*> data; * loading a font atlas) and not meant to be used for regular assets.
}; * The sampler is set to -1, signalling that this Texture was loaded
TextureData loadTexture(const std::filesystem::path& path); * outside the context of a glTF-file.
* If there was an error loading or decoding the image, the returned struct
* will be cleared to all 0 with path and data being empty; make sure to always
* check that !data.empty() before using the struct.
*
* @param path must be the path to an image file.
* @return Texture struct describing the loaded image.
*/
Texture loadTexture(const std::filesystem::path& path);
} } // end namespace vkcv::asset
...@@ -29,42 +29,6 @@ namespace vkcv::camera { ...@@ -29,42 +29,6 @@ namespace vkcv::camera {
float m_fov_min; float m_fov_min;
float m_fov_max; float m_fov_max;
/**
* @brief Indicates forward movement of the camera depending on the performed @p action.
* @param[in] action The performed action.
*/
void moveForward(int action);
/**
* @brief Indicates backward movement of the camera depending on the performed @p action.
* @param[in] action The performed action.
*/
void moveBackward(int action);
/**
* @brief Indicates left movement of the camera depending on the performed @p action.
* @param[in] action The performed action.
*/
void moveLeft(int action);
/**
* @brief Indicates right movement of the camera depending on the performed @p action.
* @param[in] action The performed action.
*/
void moveRight(int action);
/**
* @brief Indicates upward movement of the camera depending on the performed @p action.
* @param[in] action The performed action.
*/
void moveUpward(int action);
/**
* @brief Indicates downward movement of the camera depending on the performed @p action.
* @param[in] action The performed action.
*/
void moveDownward(int action);
public: public:
/** /**
......
...@@ -52,8 +52,8 @@ namespace vkcv::camera { ...@@ -52,8 +52,8 @@ namespace vkcv::camera {
} }
void CameraManager::mouseMoveCallback(double x, double y){ void CameraManager::mouseMoveCallback(double x, double y){
auto xoffset = static_cast<float>(x - m_lastX); auto xoffset = static_cast<float>(x - m_lastX) / m_window.getWidth();
auto yoffset = static_cast<float>(y - m_lastY); auto yoffset = static_cast<float>(y - m_lastY) / m_window.getHeight();
m_lastX = x; m_lastX = x;
m_lastY = y; m_lastY = y;
getActiveController().mouseMoveCallback(xoffset, yoffset, getActiveCamera()); getActiveController().mouseMoveCallback(xoffset, yoffset, getActiveCamera());
......
...@@ -50,11 +50,11 @@ namespace vkcv::camera { ...@@ -50,11 +50,11 @@ namespace vkcv::camera {
} }
// handle yaw rotation // handle yaw rotation
float yaw = camera.getYaw() + static_cast<float>(xOffset) * m_cameraSpeed; float yaw = camera.getYaw() + static_cast<float>(xOffset) * 90.0f * m_cameraSpeed;
camera.setYaw(yaw); camera.setYaw(yaw);
// handle pitch rotation // handle pitch rotation
float pitch = camera.getPitch() - static_cast<float>(yOffset) * m_cameraSpeed; float pitch = camera.getPitch() - static_cast<float>(yOffset) * 90.0f * m_cameraSpeed;
pitch = glm::clamp(pitch, -89.0f, 89.0f); pitch = glm::clamp(pitch, -89.0f, 89.0f);
camera.setPitch(pitch); camera.setPitch(pitch);
} }
...@@ -82,22 +82,22 @@ namespace vkcv::camera { ...@@ -82,22 +82,22 @@ namespace vkcv::camera {
void PilotCameraController::keyCallback(int key, int scancode, int action, int mods, Camera &camera) { void PilotCameraController::keyCallback(int key, int scancode, int action, int mods, Camera &camera) {
switch (key) { switch (key) {
case GLFW_KEY_W: case GLFW_KEY_W:
moveForward(action); m_forward = static_cast<bool>(action);
break; break;
case GLFW_KEY_S: case GLFW_KEY_S:
moveBackward(action); m_backward = static_cast<bool>(action);
break; break;
case GLFW_KEY_A: case GLFW_KEY_A:
moveLeft(action); m_left = static_cast<bool>(action);
break; break;
case GLFW_KEY_D: case GLFW_KEY_D:
moveRight(action); m_right = static_cast<bool>(action);
break; break;
case GLFW_KEY_E: case GLFW_KEY_E:
moveUpward(action); m_upward = static_cast<bool>(action);
break; break;
case GLFW_KEY_Q: case GLFW_KEY_Q:
moveDownward(action); m_downward = static_cast<bool>(action);
break; break;
default: default:
break; break;
...@@ -109,31 +109,25 @@ namespace vkcv::camera { ...@@ -109,31 +109,25 @@ namespace vkcv::camera {
} }
void PilotCameraController::mouseMoveCallback(double xoffset, double yoffset, Camera &camera) { void PilotCameraController::mouseMoveCallback(double xoffset, double yoffset, Camera &camera) {
if(!m_rotationActive){ xoffset *= static_cast<float>(m_rotationActive);
return; yoffset *= static_cast<float>(m_rotationActive);
}
float sensitivity = 0.05f;
xoffset *= sensitivity;
yoffset *= sensitivity;
panView(xoffset , yoffset, camera); panView(xoffset , yoffset, camera);
} }
void PilotCameraController::mouseButtonCallback(int button, int action, int mods, Camera &camera) { void PilotCameraController::mouseButtonCallback(int button, int action, int mods, Camera &camera) {
if(button == GLFW_MOUSE_BUTTON_2 && m_rotationActive == false && action == GLFW_PRESS){ if (button == GLFW_MOUSE_BUTTON_2) {
m_rotationActive = true; if (m_rotationActive != (action == GLFW_PRESS)) {
} m_rotationActive = (action == GLFW_PRESS);
else if(button == GLFW_MOUSE_BUTTON_2 && m_rotationActive == true && action == GLFW_RELEASE){ }
m_rotationActive = false; }
}
} }
void PilotCameraController::gamepadCallback(int gamepadIndex, Camera &camera, double frametime) { void PilotCameraController::gamepadCallback(int gamepadIndex, Camera &camera, double frametime) {
GLFWgamepadstate gamepadState; GLFWgamepadstate gamepadState;
glfwGetGamepadState(gamepadIndex, &gamepadState); glfwGetGamepadState(gamepadIndex, &gamepadState);
float sensitivity = 100.0f; float sensitivity = 1.0f;
double threshold = 0.1; double threshold = 0.1;
// handle rotations // handle rotations
...@@ -162,29 +156,4 @@ namespace vkcv::camera { ...@@ -162,29 +156,4 @@ namespace vkcv::camera {
* -copysign(1.0, stickLeftX); * -copysign(1.0, stickLeftX);
} }
void PilotCameraController::moveForward(int action){
m_forward = static_cast<bool>(action);
}
void PilotCameraController::moveBackward(int action){
m_backward = static_cast<bool>(action);
}
void PilotCameraController::moveLeft(int action){
m_left = static_cast<bool>(action);
}
void PilotCameraController::moveRight(int action){
m_right = static_cast<bool>(action);
}
void PilotCameraController::moveUpward(int action){
m_upward = static_cast<bool>(action);
}
void PilotCameraController::moveDownward(int action){
m_downward = static_cast<bool>(action);
}
} }
\ No newline at end of file
...@@ -23,10 +23,10 @@ namespace vkcv::camera { ...@@ -23,10 +23,10 @@ namespace vkcv::camera {
} }
// handle yaw rotation // handle yaw rotation
m_yaw = m_yaw + static_cast<float>(xOffset) * m_cameraSpeed; m_yaw = m_yaw + static_cast<float>(xOffset) * 90.0f * m_cameraSpeed;
// handle pitch rotation // handle pitch rotation
m_pitch = m_pitch + static_cast<float>(yOffset) * m_cameraSpeed; m_pitch = m_pitch + static_cast<float>(yOffset) * 90.0f * m_cameraSpeed;
} }
void TrackballCameraController::updateRadius(double offset, Camera &camera) { void TrackballCameraController::updateRadius(double offset, Camera &camera) {
...@@ -67,15 +67,10 @@ namespace vkcv::camera { ...@@ -67,15 +67,10 @@ namespace vkcv::camera {
} }
void TrackballCameraController::mouseMoveCallback(double xoffset, double yoffset, Camera &camera) { void TrackballCameraController::mouseMoveCallback(double xoffset, double yoffset, Camera &camera) {
if(!m_rotationActive){ xoffset *= static_cast<float>(m_rotationActive);
return; yoffset *= static_cast<float>(m_rotationActive);
}
float sensitivity = 0.025f;
xoffset *= sensitivity;
yoffset *= sensitivity;
panView(xoffset , yoffset, camera); panView(xoffset, yoffset, camera);
} }
void TrackballCameraController::mouseButtonCallback(int button, int action, int mods, Camera &camera) { void TrackballCameraController::mouseButtonCallback(int button, int action, int mods, Camera &camera) {
...@@ -91,7 +86,7 @@ namespace vkcv::camera { ...@@ -91,7 +86,7 @@ namespace vkcv::camera {
GLFWgamepadstate gamepadState; GLFWgamepadstate gamepadState;
glfwGetGamepadState(gamepadIndex, &gamepadState); glfwGetGamepadState(gamepadIndex, &gamepadState);
float sensitivity = 100.0f; float sensitivity = 1.0f;
double threshold = 0.1; double threshold = 0.1;
// handle rotations // handle rotations
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
#include "vkcv/shader/GLSLCompiler.hpp" #include "vkcv/shader/GLSLCompiler.hpp"
#include <fstream> #include <fstream>
#include <strstream> #include <sstream>
#include <glslang/SPIRV/GlslangToSpv.h> #include <glslang/SPIRV/GlslangToSpv.h>
#include <glslang/StandAlone/DirStackFileIncluder.h> #include <glslang/StandAlone/DirStackFileIncluder.h>
...@@ -219,12 +219,10 @@ namespace vkcv::shader { ...@@ -219,12 +219,10 @@ namespace vkcv::shader {
std::string source (shaderSource); std::string source (shaderSource);
if (!m_defines.empty()) { if (!m_defines.empty()) {
std::strstream defines; std::ostringstream defines;
for (const auto& define : m_defines) { for (const auto& define : m_defines) {
defines << "#define " << define.first << " " << define.second << std::endl; defines << "#define " << define.first << " " << define.second << std::endl;
} }
defines << '\0';
size_t pos = source.find("#version") + 8; size_t pos = source.find("#version") + 8;
if (pos >= source.length()) { if (pos >= source.length()) {
...@@ -236,8 +234,10 @@ namespace vkcv::shader { ...@@ -236,8 +234,10 @@ namespace vkcv::shader {
pos = epos; pos = epos;
} }
const auto defines_str = defines.str();
pos = source.find('\n', pos) + 1; pos = source.find('\n', pos) + 1;
source = source.insert(pos, defines.str()); source = source.insert(pos, defines_str);
} }
const char *shaderStrings [1]; const char *shaderStrings [1];
......
...@@ -6,3 +6,4 @@ add_subdirectory(first_scene) ...@@ -6,3 +6,4 @@ add_subdirectory(first_scene)
add_subdirectory(particle_simulation) add_subdirectory(particle_simulation)
add_subdirectory(voxelization) add_subdirectory(voxelization)
add_subdirectory(mesh_shader) add_subdirectory(mesh_shader)
add_subdirectory(indirect_dispatch)
...@@ -166,7 +166,6 @@ int main(int argc, const char** argv) { ...@@ -166,7 +166,6 @@ int main(int argc, const char** argv) {
vkcv::camera::CameraManager cameraManager(window); vkcv::camera::CameraManager cameraManager(window);
uint32_t camIndex0 = cameraManager.addCamera(vkcv::camera::ControllerType::PILOT); uint32_t camIndex0 = cameraManager.addCamera(vkcv::camera::ControllerType::PILOT);
uint32_t camIndex1 = cameraManager.addCamera(vkcv::camera::ControllerType::TRACKBALL);
cameraManager.getCamera(camIndex0).setPosition(glm::vec3(0, 0, -3)); cameraManager.getCamera(camIndex0).setPosition(glm::vec3(0, 0, -3));
......
...@@ -26,8 +26,6 @@ int main(int argc, const char** argv) { ...@@ -26,8 +26,6 @@ int main(int argc, const char** argv) {
{ "VK_KHR_swapchain" } { "VK_KHR_swapchain" }
); );
const auto& context = core.getContext();
auto triangleIndexBuffer = core.createBuffer<uint16_t>(vkcv::BufferType::INDEX, 3, vkcv::BufferMemoryType::DEVICE_LOCAL); auto triangleIndexBuffer = core.createBuffer<uint16_t>(vkcv::BufferType::INDEX, 3, vkcv::BufferMemoryType::DEVICE_LOCAL);
uint16_t indices[3] = { 0, 1, 2 }; uint16_t indices[3] = { 0, 1, 2 };
triangleIndexBuffer.fill(&indices[0], sizeof(indices)); triangleIndexBuffer.fill(&indices[0], sizeof(indices));
......
indirect_dispatch
cmake_minimum_required(VERSION 3.16)
project(indirect_dispatch)
# setting c++ standard for the project
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# this should fix the execution path to load local files from the project
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
# adding source files to the project
add_executable(indirect_dispatch src/main.cpp)
target_sources(indirect_dispatch PRIVATE
src/App.hpp
src/App.cpp
src/AppConfig.hpp
src/MotionBlurConfig.hpp
src/AppSetup.hpp
src/AppSetup.cpp
src/MotionBlur.hpp
src/MotionBlur.cpp
src/MotionBlurSetup.hpp
src/MotionBlurSetup.cpp)
# this should fix the execution path to load local files from the project (for MSVC)
if(MSVC)
set_target_properties(indirect_dispatch PROPERTIES RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
set_target_properties(indirect_dispatch PROPERTIES RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
# in addition to setting the output directory, the working directory has to be set
# by default visual studio sets the working directory to the build directory, when using the debugger
set_target_properties(indirect_dispatch PROPERTIES VS_DEBUGGER_WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
endif()
# including headers of dependencies and the VkCV framework
target_include_directories(indirect_dispatch SYSTEM BEFORE PRIVATE ${vkcv_include} ${vkcv_includes} ${vkcv_testing_include} ${vkcv_camera_include} ${vkcv_shader_compiler_include} ${vkcv_gui_include})
# linking with libraries from all dependencies and the VkCV framework
target_link_libraries(indirect_dispatch vkcv ${vkcv_libraries} vkcv_asset_loader ${vkcv_asset_loader_libraries} vkcv_testing vkcv_camera vkcv_shader_compiler vkcv_gui)
\ No newline at end of file