forked from pupbrained/vulkan-test
better handling of models, textures and shaders
This commit is contained in:
parent
4a4939e65b
commit
edbcf2406b
14
meson.build
14
meson.build
|
@ -31,13 +31,25 @@ deps = [
|
||||||
dependency('vulkan', include_type: 'system'),
|
dependency('vulkan', include_type: 'system'),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
glslang_dep = cpp.find_library('glslang', required: false)
|
||||||
|
|
||||||
|
if not glslang_dep.found()
|
||||||
|
glslang_dep = dependency('glslang', required: true, include_type: 'system')
|
||||||
|
endif
|
||||||
|
|
||||||
|
spirv_dep = cpp.find_library('SPIRV', required: false)
|
||||||
|
|
||||||
|
if not spirv_dep.found()
|
||||||
|
spirv_dep = dependency('SPIRV', required: true, include_type: 'system')
|
||||||
|
endif
|
||||||
|
|
||||||
imgui_dep = dependency('imgui', required: false, include_type: 'system')
|
imgui_dep = dependency('imgui', required: false, include_type: 'system')
|
||||||
|
|
||||||
if not imgui_dep.found()
|
if not imgui_dep.found()
|
||||||
imgui_dep = cpp.find_library('imgui', required: true)
|
imgui_dep = cpp.find_library('imgui', required: true)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
deps += imgui_dep
|
deps += [glslang_dep, spirv_dep, imgui_dep]
|
||||||
|
|
||||||
executable(
|
executable(
|
||||||
'graphics-test',
|
'graphics-test',
|
||||||
|
|
BIN
shaders/frag.spv
BIN
shaders/frag.spv
Binary file not shown.
|
@ -1,12 +0,0 @@
|
||||||
#version 450
|
|
||||||
|
|
||||||
layout(binding = 1) uniform sampler2D texSampler;
|
|
||||||
|
|
||||||
layout(location = 0) in vec3 fragColor;
|
|
||||||
layout(location = 1) in vec2 fragTexCoord;
|
|
||||||
|
|
||||||
layout(location = 0) out vec4 outColor;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
outColor = texture(texSampler, fragTexCoord);
|
|
||||||
}
|
|
|
@ -1,20 +0,0 @@
|
||||||
#version 450
|
|
||||||
|
|
||||||
layout(binding = 0) uniform UniformBufferObject {
|
|
||||||
mat4 model;
|
|
||||||
mat4 view;
|
|
||||||
mat4 proj;
|
|
||||||
} ubo;
|
|
||||||
|
|
||||||
layout(location = 0) in vec3 inPosition;
|
|
||||||
layout(location = 1) in vec3 inColor;
|
|
||||||
layout(location = 2) in vec2 inTexCoord;
|
|
||||||
|
|
||||||
layout(location = 0) out vec3 fragColor;
|
|
||||||
layout(location = 1) out vec2 fragTexCoord;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
gl_Position = ubo.proj * ubo.view * ubo.model * vec4(inPosition, 1.0);
|
|
||||||
fragColor = inColor;
|
|
||||||
fragTexCoord = inTexCoord;
|
|
||||||
}
|
|
|
@ -1,7 +0,0 @@
|
||||||
#!/usr/bin/env sh
|
|
||||||
|
|
||||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
||||||
cd "$SCRIPT_DIR" || exit
|
|
||||||
|
|
||||||
glslc -c ./shader.vert -o ./vert.spv
|
|
||||||
glslc -c ./shader.frag -o ./frag.spv
|
|
BIN
shaders/vert.spv
BIN
shaders/vert.spv
Binary file not shown.
41
src/main.cpp
41
src/main.cpp
|
@ -22,6 +22,7 @@
|
||||||
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE
|
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE
|
||||||
|
|
||||||
// Include custom utility headers
|
// Include custom utility headers
|
||||||
|
#include "util/shader.h" // Shader compilation utilities
|
||||||
#include "util/types.h" // Custom type definitions
|
#include "util/types.h" // Custom type definitions
|
||||||
#include "util/unique_image.h" // Custom image handling utilities
|
#include "util/unique_image.h" // Custom image handling utilities
|
||||||
#include "util/vertex.h" // Custom vertex structure definition
|
#include "util/vertex.h" // Custom vertex structure definition
|
||||||
|
@ -39,14 +40,6 @@ VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE
|
||||||
constexpr i32 WIDTH = 800;
|
constexpr i32 WIDTH = 800;
|
||||||
constexpr i32 HEIGHT = 600;
|
constexpr i32 HEIGHT = 600;
|
||||||
|
|
||||||
// File paths for 3D model and texture
|
|
||||||
constexpr const char* MODEL_PATH = "models/viking_room.obj";
|
|
||||||
constexpr const char* TEXTURE_PATH = "textures/viking_room.png";
|
|
||||||
|
|
||||||
// File paths for shader programs
|
|
||||||
constexpr const char* FRAGMENT_SHADER_PATH = "shaders/frag.spv";
|
|
||||||
constexpr const char* VERTEX_SHADER_PATH = "shaders/vert.spv";
|
|
||||||
|
|
||||||
// Maximum number of frames that can be processed concurrently
|
// Maximum number of frames that can be processed concurrently
|
||||||
constexpr i32 MAX_FRAMES_IN_FLIGHT = 2;
|
constexpr i32 MAX_FRAMES_IN_FLIGHT = 2;
|
||||||
|
|
||||||
|
@ -73,10 +66,12 @@ class VulkanApp {
|
||||||
* It also cleans up resources when the application is closed.
|
* It also cleans up resources when the application is closed.
|
||||||
*/
|
*/
|
||||||
fn run() -> void {
|
fn run() -> void {
|
||||||
|
InitGlslang();
|
||||||
initWindow(); // Initialize the application window
|
initWindow(); // Initialize the application window
|
||||||
initVulkan(); // Initialize Vulkan
|
initVulkan(); // Initialize Vulkan
|
||||||
mainLoop(); // Enter the main rendering loop
|
mainLoop(); // Enter the main rendering loop
|
||||||
|
|
||||||
|
CleanupGlslang();
|
||||||
cleanupSwapChain(); // Clean up swap chain resources
|
cleanupSwapChain(); // Clean up swap chain resources
|
||||||
|
|
||||||
for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++)
|
for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++)
|
||||||
|
@ -472,7 +467,7 @@ class VulkanApp {
|
||||||
|
|
||||||
// Application metadata
|
// Application metadata
|
||||||
vk::ApplicationInfo appInfo {
|
vk::ApplicationInfo appInfo {
|
||||||
.pApplicationName = "Hello Triangle",
|
.pApplicationName = "Vulkan App",
|
||||||
.applicationVersion = 1,
|
.applicationVersion = 1,
|
||||||
.pEngineName = "No Engine",
|
.pEngineName = "No Engine",
|
||||||
.engineVersion = 1,
|
.engineVersion = 1,
|
||||||
|
@ -848,8 +843,8 @@ class VulkanApp {
|
||||||
* states.
|
* states.
|
||||||
*/
|
*/
|
||||||
fn createGraphicsPipeline() -> void {
|
fn createGraphicsPipeline() -> void {
|
||||||
std::vector<char> vertShaderCode = readFile(VERTEX_SHADER_PATH);
|
std::vector<u32> vertShaderCode = CompileShader(vertShaderSrc, EShLangVertex);
|
||||||
std::vector<char> fragShaderCode = readFile(FRAGMENT_SHADER_PATH);
|
std::vector<u32> fragShaderCode = CompileShader(fragShaderSrc, EShLangFragment);
|
||||||
|
|
||||||
vk::UniqueShaderModule vertShaderModule = createShaderModule(vertShaderCode);
|
vk::UniqueShaderModule vertShaderModule = createShaderModule(vertShaderCode);
|
||||||
vk::UniqueShaderModule fragShaderModule = createShaderModule(fragShaderCode);
|
vk::UniqueShaderModule fragShaderModule = createShaderModule(fragShaderCode);
|
||||||
|
@ -1105,7 +1100,7 @@ class VulkanApp {
|
||||||
* @param format The format to check.
|
* @param format The format to check.
|
||||||
* @return True if the format has a stencil component, false otherwise.
|
* @return True if the format has a stencil component, false otherwise.
|
||||||
*/
|
*/
|
||||||
static fn hasStencilComponent(vk::Format format) {
|
static fn hasStencilComponent(const vk::Format& format) {
|
||||||
return format == vk::Format::eD32SfloatS8Uint || format == vk::Format::eD24UnormS8Uint;
|
return format == vk::Format::eD32SfloatS8Uint || format == vk::Format::eD24UnormS8Uint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1117,7 +1112,8 @@ class VulkanApp {
|
||||||
* buffer to the texture image. It also generates mipmaps for the texture.
|
* buffer to the texture image. It also generates mipmaps for the texture.
|
||||||
*/
|
*/
|
||||||
fn createTextureImage() -> void {
|
fn createTextureImage() -> void {
|
||||||
stb::UniqueImage image(TEXTURE_PATH);
|
std::filesystem::path texturePath = std::filesystem::current_path() / "textures" / "viking_room.png";
|
||||||
|
stb::UniqueImage image(texturePath);
|
||||||
|
|
||||||
u8* pixels = image.getData();
|
u8* pixels = image.getData();
|
||||||
i32 texWidth = image.getWidth(), texHeight = image.getHeight();
|
i32 texWidth = image.getWidth(), texHeight = image.getHeight();
|
||||||
|
@ -1176,8 +1172,13 @@ class VulkanApp {
|
||||||
* This function generates mipmaps for the given texture image by repeatedly scaling down
|
* This function generates mipmaps for the given texture image by repeatedly scaling down
|
||||||
* the image by half until reaching the smallest mip level.
|
* the image by half until reaching the smallest mip level.
|
||||||
*/
|
*/
|
||||||
fn generateMipmaps(vk::Image image, vk::Format imageFormat, i32 texWidth, i32 texHeight, u32 mipLevels)
|
fn generateMipmaps(
|
||||||
-> void {
|
const vk::Image& image,
|
||||||
|
const vk::Format& imageFormat,
|
||||||
|
const i32& texWidth,
|
||||||
|
const i32& texHeight,
|
||||||
|
const u32& mipLevels
|
||||||
|
) -> void {
|
||||||
vk::FormatProperties formatProperties = mPhysicalDevice.getFormatProperties(imageFormat);
|
vk::FormatProperties formatProperties = mPhysicalDevice.getFormatProperties(imageFormat);
|
||||||
|
|
||||||
if (!(formatProperties.optimalTilingFeatures & vk::FormatFeatureFlagBits::eSampledImageFilterLinear))
|
if (!(formatProperties.optimalTilingFeatures & vk::FormatFeatureFlagBits::eSampledImageFilterLinear))
|
||||||
|
@ -1527,7 +1528,9 @@ class VulkanApp {
|
||||||
std::vector<tinyobj::material_t> materials;
|
std::vector<tinyobj::material_t> materials;
|
||||||
std::string warn, err;
|
std::string warn, err;
|
||||||
|
|
||||||
if (!tinyobj::LoadObj(&attrib, &shapes, &materials, &warn, &err, MODEL_PATH))
|
std::filesystem::path modelPath = std::filesystem::current_path() / "models" / "viking_room.obj";
|
||||||
|
|
||||||
|
if (!tinyobj::LoadObj(&attrib, &shapes, &materials, &warn, &err, modelPath.string().c_str()))
|
||||||
throw std::runtime_error(warn + err);
|
throw std::runtime_error(warn + err);
|
||||||
|
|
||||||
std::unordered_map<Vertex, u32> uniqueVertices {};
|
std::unordered_map<Vertex, u32> uniqueVertices {};
|
||||||
|
@ -2183,10 +2186,10 @@ class VulkanApp {
|
||||||
*
|
*
|
||||||
* This function takes compiled shader code and creates a Vulkan shader module from it.
|
* This function takes compiled shader code and creates a Vulkan shader module from it.
|
||||||
*/
|
*/
|
||||||
fn createShaderModule(const std::vector<char>& code) -> vk::UniqueShaderModule {
|
fn createShaderModule(const std::vector<u32>& code) -> vk::UniqueShaderModule {
|
||||||
vk::ShaderModuleCreateInfo createInfo {
|
vk::ShaderModuleCreateInfo createInfo {
|
||||||
.codeSize = code.size(),
|
.codeSize = code.size() * sizeof(u32),
|
||||||
.pCode = std::bit_cast<const u32*>(code.data()),
|
.pCode = code.data(),
|
||||||
};
|
};
|
||||||
|
|
||||||
return mDevice->createShaderModuleUnique(createInfo);
|
return mDevice->createShaderModuleUnique(createInfo);
|
||||||
|
|
196
src/util/shader.h
Normal file
196
src/util/shader.h
Normal file
|
@ -0,0 +1,196 @@
|
||||||
|
#include <glslang/Public/ShaderLang.h>
|
||||||
|
#include <glslang/SPIRV/GlslangToSpv.h>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
|
const TBuiltInResource DefaultTBuiltInResource = {
|
||||||
|
.maxLights = 32,
|
||||||
|
.maxClipPlanes = 6,
|
||||||
|
.maxTextureUnits = 32,
|
||||||
|
.maxTextureCoords = 32,
|
||||||
|
.maxVertexAttribs = 64,
|
||||||
|
.maxVertexUniformComponents = 4096,
|
||||||
|
.maxVaryingFloats = 64,
|
||||||
|
.maxVertexTextureImageUnits = 32,
|
||||||
|
.maxCombinedTextureImageUnits = 80,
|
||||||
|
.maxTextureImageUnits = 32,
|
||||||
|
.maxFragmentUniformComponents = 4096,
|
||||||
|
.maxDrawBuffers = 32,
|
||||||
|
.maxVertexUniformVectors = 128,
|
||||||
|
.maxVaryingVectors = 8,
|
||||||
|
.maxFragmentUniformVectors = 16,
|
||||||
|
.maxVertexOutputVectors = 16,
|
||||||
|
.maxFragmentInputVectors = 15,
|
||||||
|
.minProgramTexelOffset = -8,
|
||||||
|
.maxProgramTexelOffset = 7,
|
||||||
|
.maxClipDistances = 8,
|
||||||
|
.maxComputeWorkGroupCountX = 65535,
|
||||||
|
.maxComputeWorkGroupCountY = 65535,
|
||||||
|
.maxComputeWorkGroupCountZ = 65535,
|
||||||
|
.maxComputeWorkGroupSizeX = 1024,
|
||||||
|
.maxComputeWorkGroupSizeY = 1024,
|
||||||
|
.maxComputeWorkGroupSizeZ = 64,
|
||||||
|
.maxComputeUniformComponents = 1024,
|
||||||
|
.maxComputeTextureImageUnits = 16,
|
||||||
|
.maxComputeImageUniforms = 8,
|
||||||
|
.maxComputeAtomicCounters = 8,
|
||||||
|
.maxComputeAtomicCounterBuffers = 1,
|
||||||
|
.maxVaryingComponents = 60,
|
||||||
|
.maxVertexOutputComponents = 64,
|
||||||
|
.maxGeometryInputComponents = 64,
|
||||||
|
.maxGeometryOutputComponents = 128,
|
||||||
|
.maxFragmentInputComponents = 128,
|
||||||
|
.maxImageUnits = 8,
|
||||||
|
.maxCombinedImageUnitsAndFragmentOutputs = 8,
|
||||||
|
.maxCombinedShaderOutputResources = 8,
|
||||||
|
.maxImageSamples = 0,
|
||||||
|
.maxVertexImageUniforms = 0,
|
||||||
|
.maxTessControlImageUniforms = 0,
|
||||||
|
.maxTessEvaluationImageUniforms = 0,
|
||||||
|
.maxGeometryImageUniforms = 0,
|
||||||
|
.maxFragmentImageUniforms = 8,
|
||||||
|
.maxCombinedImageUniforms = 8,
|
||||||
|
.maxGeometryTextureImageUnits = 16,
|
||||||
|
.maxGeometryOutputVertices = 256,
|
||||||
|
.maxGeometryTotalOutputComponents = 1024,
|
||||||
|
.maxGeometryUniformComponents = 1024,
|
||||||
|
.maxGeometryVaryingComponents = 64,
|
||||||
|
.maxTessControlInputComponents = 128,
|
||||||
|
.maxTessControlOutputComponents = 128,
|
||||||
|
.maxTessControlTextureImageUnits = 16,
|
||||||
|
.maxTessControlUniformComponents = 1024,
|
||||||
|
.maxTessControlTotalOutputComponents = 4096,
|
||||||
|
.maxTessEvaluationInputComponents = 128,
|
||||||
|
.maxTessEvaluationOutputComponents = 128,
|
||||||
|
.maxTessEvaluationTextureImageUnits = 16,
|
||||||
|
.maxTessEvaluationUniformComponents = 1024,
|
||||||
|
.maxTessPatchComponents = 120,
|
||||||
|
.maxPatchVertices = 32,
|
||||||
|
.maxTessGenLevel = 64,
|
||||||
|
.maxViewports = 16,
|
||||||
|
.maxVertexAtomicCounters = 0,
|
||||||
|
.maxTessControlAtomicCounters = 0,
|
||||||
|
.maxTessEvaluationAtomicCounters = 0,
|
||||||
|
.maxGeometryAtomicCounters = 0,
|
||||||
|
.maxFragmentAtomicCounters = 8,
|
||||||
|
.maxCombinedAtomicCounters = 8,
|
||||||
|
.maxAtomicCounterBindings = 1,
|
||||||
|
.maxVertexAtomicCounterBuffers = 0,
|
||||||
|
.maxTessControlAtomicCounterBuffers = 0,
|
||||||
|
.maxTessEvaluationAtomicCounterBuffers = 0,
|
||||||
|
.maxGeometryAtomicCounterBuffers = 0,
|
||||||
|
.maxFragmentAtomicCounterBuffers = 1,
|
||||||
|
.maxCombinedAtomicCounterBuffers = 1,
|
||||||
|
.maxAtomicCounterBufferSize = 16384,
|
||||||
|
.maxTransformFeedbackBuffers = 4,
|
||||||
|
.maxTransformFeedbackInterleavedComponents = 64,
|
||||||
|
.maxCullDistances = 8,
|
||||||
|
.maxCombinedClipAndCullDistances = 8,
|
||||||
|
.maxSamples = 4,
|
||||||
|
.maxMeshOutputVerticesNV = 256,
|
||||||
|
.maxMeshOutputPrimitivesNV = 512,
|
||||||
|
.maxMeshWorkGroupSizeX_NV = 32,
|
||||||
|
.maxMeshWorkGroupSizeY_NV = 1,
|
||||||
|
.maxMeshWorkGroupSizeZ_NV = 1,
|
||||||
|
.maxTaskWorkGroupSizeX_NV = 32,
|
||||||
|
.maxTaskWorkGroupSizeY_NV = 1,
|
||||||
|
.maxTaskWorkGroupSizeZ_NV = 1,
|
||||||
|
.maxMeshViewCountNV = 4,
|
||||||
|
.maxMeshOutputVerticesEXT = 256,
|
||||||
|
.maxMeshOutputPrimitivesEXT = 512,
|
||||||
|
.maxMeshWorkGroupSizeX_EXT = 32,
|
||||||
|
.maxMeshWorkGroupSizeY_EXT = 1,
|
||||||
|
.maxMeshWorkGroupSizeZ_EXT = 1,
|
||||||
|
.maxTaskWorkGroupSizeX_EXT = 32,
|
||||||
|
.maxTaskWorkGroupSizeY_EXT = 1,
|
||||||
|
.maxTaskWorkGroupSizeZ_EXT = 1,
|
||||||
|
.maxMeshViewCountEXT = 4,
|
||||||
|
.maxDualSourceDrawBuffersEXT = 1,
|
||||||
|
.limits = {
|
||||||
|
.nonInductiveForLoops = true,
|
||||||
|
.whileLoops = true,
|
||||||
|
.doWhileLoops = true,
|
||||||
|
.generalUniformIndexing = true,
|
||||||
|
.generalAttributeMatrixVectorIndexing = true,
|
||||||
|
.generalVaryingIndexing = true,
|
||||||
|
.generalSamplerIndexing = true,
|
||||||
|
.generalVariableIndexing = true,
|
||||||
|
.generalConstantMatrixVectorIndexing = true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr const char* vertShaderSrc = R"glsl(
|
||||||
|
#version 450
|
||||||
|
|
||||||
|
layout(binding = 0) uniform UniformBufferObject {
|
||||||
|
mat4 model;
|
||||||
|
mat4 view;
|
||||||
|
mat4 proj;
|
||||||
|
} ubo;
|
||||||
|
|
||||||
|
layout(location = 0) in vec3 inPosition;
|
||||||
|
layout(location = 1) in vec3 inColor;
|
||||||
|
layout(location = 2) in vec2 inTexCoord;
|
||||||
|
|
||||||
|
layout(location = 0) out vec3 fragColor;
|
||||||
|
layout(location = 1) out vec2 fragTexCoord;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
gl_Position = ubo.proj * ubo.view * ubo.model * vec4(inPosition, 1.0);
|
||||||
|
fragColor = inColor;
|
||||||
|
fragTexCoord = inTexCoord;
|
||||||
|
}
|
||||||
|
)glsl";
|
||||||
|
|
||||||
|
constexpr const char* fragShaderSrc = R"glsl(
|
||||||
|
#version 450
|
||||||
|
|
||||||
|
layout(binding = 1) uniform sampler2D texSampler;
|
||||||
|
|
||||||
|
layout(location = 0) in vec3 fragColor;
|
||||||
|
layout(location = 1) in vec2 fragTexCoord;
|
||||||
|
|
||||||
|
layout(location = 0) out vec4 outColor;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
outColor = texture(texSampler, fragTexCoord);
|
||||||
|
}
|
||||||
|
)glsl";
|
||||||
|
|
||||||
|
inline void InitGlslang() { glslang::InitializeProcess(); }
|
||||||
|
|
||||||
|
inline void CleanupGlslang() { glslang::FinalizeProcess(); }
|
||||||
|
|
||||||
|
inline fn CompileShader(const char* source, EShLanguage shaderType) -> std::vector<uint32_t> {
|
||||||
|
glslang::TShader shader(shaderType);
|
||||||
|
shader.setStrings(&source, 1);
|
||||||
|
|
||||||
|
// Set shader environment details (language version, profile)
|
||||||
|
shader.setEnvInput(glslang::EShSourceGlsl, shaderType, glslang::EShClientVulkan, 450);
|
||||||
|
shader.setEnvClient(glslang::EShClientVulkan, glslang::EShTargetVulkan_1_2);
|
||||||
|
shader.setEnvTarget(glslang::EShTargetSpv, glslang::EShTargetSpv_1_3);
|
||||||
|
|
||||||
|
// Parse GLSL to AST (abstract syntax tree)
|
||||||
|
if (!shader.parse(&DefaultTBuiltInResource, 450, false, EShMsgDefault)) {
|
||||||
|
std::cerr << "GLSL parsing failed: " << shader.getInfoLog() << std::endl;
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a program to hold the compiled shader
|
||||||
|
glslang::TProgram program;
|
||||||
|
program.addShader(&shader);
|
||||||
|
|
||||||
|
// Link the program
|
||||||
|
if (!program.link(EShMsgDefault)) {
|
||||||
|
std::cerr << "Linking failed: " << program.getInfoLog() << std::endl;
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert AST to SPIR-V
|
||||||
|
std::vector<uint32_t> spirv;
|
||||||
|
glslang::SpvOptions spvOptions;
|
||||||
|
glslang::GlslangToSpv(*program.getIntermediate(shaderType), spirv, &spvOptions);
|
||||||
|
|
||||||
|
return spirv;
|
||||||
|
}
|
|
@ -1,3 +1,5 @@
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
#define STB_IMAGE_IMPLEMENTATION
|
#define STB_IMAGE_IMPLEMENTATION
|
||||||
#include <stb_image.h>
|
#include <stb_image.h>
|
||||||
|
|
||||||
|
@ -7,7 +9,7 @@ namespace stb {
|
||||||
class UniqueImage {
|
class UniqueImage {
|
||||||
public:
|
public:
|
||||||
// Constructor
|
// Constructor
|
||||||
UniqueImage(const char* filename) { load(filename); }
|
UniqueImage(const std::filesystem::path& path) { load(path.string().c_str()); }
|
||||||
|
|
||||||
// Deleted copy constructor and assignment operator
|
// Deleted copy constructor and assignment operator
|
||||||
UniqueImage(const UniqueImage&) = delete;
|
UniqueImage(const UniqueImage&) = delete;
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 75 KiB |
Loading…
Reference in a new issue