Skip to content
Snippets Groups Projects
Commit 44638d6c authored by Simeon Hermann's avatar Simeon Hermann
Browse files

[#10] created ShaderProgram class, basic shaders and glslc-compile.bat

parent 6fed231d
Branches
Tags
4 merge requests!12Resolve "Swapchain Class",!7Resolve "Shader Program Class",!5Resolve "Pipeline State Object",!4Resolve "Renderpass Class"
This commit is part of merge request !5. Comments created here will be created in the context of that merge request.
...@@ -6,4 +6,6 @@ set(vkcv_sources ...@@ -6,4 +6,6 @@ set(vkcv_sources
${vkcv_source}/vkcv/Window.cpp ${vkcv_source}/vkcv/Window.cpp
${vkcv_source}/vkcv/CoreManager.hpp ${vkcv_source}/vkcv/CoreManager.hpp
${vkcv_source}/vkcv/CoreManager.cpp ${vkcv_source}/vkcv/CoreManager.cpp
${vkcv_source}/vkcv/ShaderProgram.hpp
${vkcv_source}/vkcv/ShaderProgram.cpp
) )
...@@ -32,6 +32,10 @@ int main(int argc, const char** argv) { ...@@ -32,6 +32,10 @@ int main(int argc, const char** argv) {
default: std::cout << "Unknown GPU vendor?! Either you're on an exotic system or your driver is broken..." << std::endl; default: std::cout << "Unknown GPU vendor?! Either you're on an exotic system or your driver is broken..." << std::endl;
} }
vkcv::ShaderProgram shaderProgram = vkcv::ShaderProgram::create(context);
shaderProgram.addShader(VK_SHADER_STAGE_VERTEX_BIT, "../../../../../shaders/vert.spv");
shaderProgram.addShader(VK_SHADER_STAGE_FRAGMENT_BIT, "../../../../../shaders/frag.spv");
while (window.isWindowOpen()) { while (window.isWindowOpen()) {
window.pollEvents(); window.pollEvents();
} }
......
C:\VulkanSDK\1.2.170.0\Bin32\glslc.exe shader.vert -o vert.spv
C:\VulkanSDK\1.2.170.0\Bin32\glslc.exe shader.frag -o frag.spv
pause
\ No newline at end of file
File added
#version 450
#extension GL_ARB_separate_shader_objects : enable
layout(location = 0) in vec3 fragColor;
layout(location = 0) out vec4 outColor;
void main() {
outColor = vec4(fragColor, 1.0);
}
\ No newline at end of file
#version 450
#extension GL_ARB_separate_shader_objects : enable
layout(location = 0) in vec2 inPosition;
layout(location = 1) in vec3 inColor;
layout(location = 0) out vec3 fragColor;
void main() {
gl_Position = vec4(inPosition, 0.0, 1.0);
fragColor = inColor;
}
\ No newline at end of file
File added
/**
* @authors Simeon Hermann
* @file src/vkcv/ShaderProgram.cpp
* @brief ShaderProgram class to handle and prepare the shader stages for a graphics pipeline
*/
#include "ShaderProgram.hpp"
#include <fstream>
#include <iostream>
std::vector<const char*> validationLayers = {
"VK_LAYER_KHRONOS_validation"
};
namespace vkcv {
ShaderProgram::ShaderProgram(vkcv::Context& context)
: m_context(context)
{}
std::vector<char> ShaderProgram::readFile(const std::string& filepath) {
std::ifstream file(filepath, std::ios::ate | std::ios::binary);
if (!file.is_open()) {
throw std::runtime_error("The file could not be opened.");
}
size_t fileSize = (size_t)file.tellg();
std::vector<char> buffer(fileSize);
file.seekg(0);
file.read(buffer.data(), fileSize);
return buffer;
}
VkShaderModule ShaderProgram::createShaderModule(const std::vector<char>& shaderCode) {
VkShaderModuleCreateInfo createInfo{};
createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
createInfo.codeSize = shaderCode.size();
createInfo.pCode = reinterpret_cast<const uint32_t*>(shaderCode.data());
VkShaderModule shaderModule;
if (vkCreateShaderModule(m_context.getDevice(), &createInfo, nullptr, &shaderModule) != VK_SUCCESS) {
throw std::runtime_error("Failed to create shader module!");
}
return shaderModule;
}
VkPipelineShaderStageCreateInfo ShaderProgram::createShaderStage(VkShaderModule& shaderModule, VkShaderStageFlagBits shaderStage) {
VkPipelineShaderStageCreateInfo shaderStageInfo{};
shaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
shaderStageInfo.stage = shaderStage;
shaderStageInfo.module = shaderModule;
shaderStageInfo.pName = "main";
return shaderStageInfo;
}
ShaderProgram::~ShaderProgram() {
}
ShaderProgram ShaderProgram::create(vkcv::Context& context) {
return ShaderProgram(context);
}
void ShaderProgram::addShader(VkShaderStageFlagBits shaderStage, const std::string& filepath) {
if (containsShaderStage(shaderStage)) {
throw std::runtime_error("Shader program already contains this particular shader stage.");
}
else {
auto shaderCode = readFile(filepath);
VkShaderModule shaderModule = createShaderModule(shaderCode);
VkPipelineShaderStageCreateInfo shaderInfo = createShaderStage(shaderModule, shaderStage);
m_shaderStagesList.push_back(shaderInfo);
vkDestroyShaderModule(m_context.getDevice(), shaderModule, nullptr);
}
}
bool ShaderProgram::containsShaderStage(VkShaderStageFlagBits shaderStage) {
for (int i = 0; i < m_shaderStagesList.size(); i++) {
if (m_shaderStagesList[i].stage == shaderStage) {
return true;
}
}
return false;
}
bool ShaderProgram::deleteShaderStage(VkShaderStageFlagBits shaderStage) {
for (int i = 0; i < m_shaderStagesList.size() - 1; i++) {
if (m_shaderStagesList[i].stage == shaderStage) {
m_shaderStagesList.erase(m_shaderStagesList.begin() + i);
return true;
}
}
return false;
}
std::vector<VkPipelineShaderStageCreateInfo> ShaderProgram::getShaderStages() {
return m_shaderStagesList;
}
int ShaderProgram::getShaderStagesCount() {
return m_shaderStagesList.size();
}
}
#pragma once
/**
* @authors Simeon Hermann
* @file src/vkcv/ShaderProgram.hpp
* @brief ShaderProgram class to handle and prepare the shader stages for a graphics pipeline
*/
#define GLFW_INCLUDE_VULKAN
#include <vector>
#include <map>
#include <vulkan/vulkan.hpp>
#include "Context.hpp"
namespace vkcv {
class ShaderProgram final {
private:
vkcv::Context& m_context;
std::vector<VkPipelineShaderStageCreateInfo> m_shaderStagesList;
/**
* Constructor of ShaderProgram requires a context for the logical device.
* @param context of the app
*/
ShaderProgram(vkcv::Context& context);
/**
* Reads the file of a given shader code.
* Only used within the class.
* @param[in] relative path to the shader code
* @return vector of chars as a buffer for the code
*/
std::vector<char> readFile(const std::string& filepath);
/**
* Creates a shader module that encapsulates the read shader code.
* Only used within the class.
* Shader modules are destroyed after respective shader stages are created.
* @param[in] a vector of chars as a buffer for the code
* @return shader module
*/
VkShaderModule createShaderModule(const std::vector<char>& shaderCode);
/**
* Creates a shader stage (info struct) for the to be added shader.
* Only used within the class.
* @param[in] Shader module that encapsulates the shader code
* @param[in] flag that signals the respective shaderStage
* @return pipeline shader stage info struct
*/
VkPipelineShaderStageCreateInfo createShaderStage(VkShaderModule& shaderModule, VkShaderStageFlagBits shaderStage);
public:
/**
* destructor of ShaderProgram, does nothing so far
*/
~ShaderProgram();
/**
* Creates a shader program.
* So far it only calls the constructor.
* @param[in] context of the app
*/
static ShaderProgram create(vkcv::Context& context);
/**
* Adds a shader into the shader program.
* The shader is only added if the shader program does not contain the particular shader stage already.
* Contains: (1) reading of the code, (2) creation of a shader module, (3) creation of a shader stage, (4) adding to the shader stage list, (5) destroying of the shader module
* @param[in] flag that signals the respective shaderStage (e.g. VK_SHADER_STAGE_VERTEX_BIT)
* @param[in] relative path to the shader code (e.g. "../../../../../shaders/vert.spv")
*/
void addShader(VkShaderStageFlagBits shaderStage, const std::string& filepath);
/**
* Tests if the shader program contains a certain shader stage.
* @param[in] flag that signals the respective shader stage (e.g. VK_SHADER_STAGE_VERTEX_BIT)
* @return boolean that is true if the shader program contains the shader stage
*/
bool containsShaderStage(VkShaderStageFlagBits shaderStage);
/**
* Deletes the given shader stage in the shader program.
* @param[in] flag that signals the respective shader stage (e.g. VK_SHADER_STAGE_VERTEX_BIT)
* @return boolean that is false if the shader stage was not found in the shader program
*/
bool deleteShaderStage(VkShaderStageFlagBits shaderStage);
/**
* Returns a list with all the shader stages in the shader program.
* Needed for the transfer to the pipeline.
* @return vector list with all shader stage info structs
*/
std::vector<VkPipelineShaderStageCreateInfo> getShaderStages();
/**
* Returns the number of shader stages in the shader program.
* Needed for the transfer to the pipeline.
* @return integer with the number of stages
*/
int getShaderStagesCount();
};
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment