abstruct custom shader
This commit is contained in:
parent
a6f4b253ae
commit
51e7730fdb
1 changed files with 109 additions and 97 deletions
206
main.cpp
206
main.cpp
|
|
@ -53,6 +53,107 @@ const std::vector<Vertex> vertices = {
|
|||
|
||||
const std::vector<uint16_t > indices = { 0, 1, 2, 2, 3, 0 };
|
||||
|
||||
struct CustomShader {
|
||||
|
||||
void create(VkDevice device) {
|
||||
std::vector<char> vertShaderByteCode = readFile("bin/vert.spv");
|
||||
mVertexModule = createShaderModule(device, vertShaderByteCode);
|
||||
|
||||
std::vector<char> fragShaderByteCode = readFile("bin/frag.spv");
|
||||
mFragmentModule = createShaderModule(device, fragShaderByteCode);
|
||||
|
||||
VkPipelineShaderStageCreateInfo vertShaderStageCreateInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
||||
.stage = VK_SHADER_STAGE_VERTEX_BIT,
|
||||
.module = mVertexModule,
|
||||
.pName = "main",
|
||||
};
|
||||
|
||||
VkPipelineShaderStageCreateInfo fragShaderStageCreateInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
||||
.stage = VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
.module = mFragmentModule,
|
||||
.pName = "main",
|
||||
};
|
||||
|
||||
mStageCreateInfos = {
|
||||
vertShaderStageCreateInfo,
|
||||
fragShaderStageCreateInfo
|
||||
};
|
||||
}
|
||||
|
||||
void destroy(VkDevice device) const {
|
||||
vkDestroyShaderModule(device, mVertexModule, nullptr);
|
||||
vkDestroyShaderModule(device, mFragmentModule, nullptr);
|
||||
}
|
||||
|
||||
static std::vector<char> readFile(const std::string &fileName) {
|
||||
std::ifstream file(fileName, std::ios::ate | std::ios::binary);
|
||||
|
||||
if (!file.is_open()) {
|
||||
throw std::runtime_error("cannot open file");
|
||||
}
|
||||
|
||||
size_t fileSize = (size_t) file.tellg();
|
||||
std::vector<char> buffer(fileSize);
|
||||
|
||||
file.seekg(0);
|
||||
file.read(buffer.data(), (std::streamsize) fileSize);
|
||||
|
||||
file.close();
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static VkShaderModule createShaderModule(VkDevice device, const std::vector<char> &bytecode) {
|
||||
VkShaderModuleCreateInfo createInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
|
||||
.codeSize = (uint32_t) bytecode.size(),
|
||||
.pCode = (uint32_t *) bytecode.data(),
|
||||
};
|
||||
|
||||
VkShaderModule shaderModule;
|
||||
|
||||
if (vkCreateShaderModule(device, &createInfo, nullptr, &shaderModule) != VK_SUCCESS) {
|
||||
throw std::runtime_error("cannot create shader module");
|
||||
}
|
||||
|
||||
return shaderModule;
|
||||
}
|
||||
|
||||
public:
|
||||
struct UniformBuffer {
|
||||
glm::mat4 transforms {};
|
||||
glm::vec4 origin {};
|
||||
} mVertexUBO;
|
||||
|
||||
VkVertexInputBindingDescription mVertexInputDescription {
|
||||
.binding = 0,
|
||||
.stride = sizeof(Vertex),
|
||||
.inputRate = VK_VERTEX_INPUT_RATE_VERTEX,
|
||||
};
|
||||
|
||||
std::vector<VkVertexInputAttributeDescription> mVertexAttributes = {
|
||||
{
|
||||
.location = 0,
|
||||
.binding = 0,
|
||||
.format = VK_FORMAT_R32G32_SFLOAT,
|
||||
.offset = offsetof(Vertex, pos),
|
||||
},
|
||||
{
|
||||
.location = 1,
|
||||
.binding = 0,
|
||||
.format = VK_FORMAT_R32G32B32_SFLOAT,
|
||||
.offset = offsetof(Vertex, color),
|
||||
},
|
||||
};
|
||||
|
||||
std::vector<VkPipelineShaderStageCreateInfo> mStageCreateInfos;
|
||||
|
||||
VkShaderModule mVertexModule = VK_NULL_HANDLE;
|
||||
VkShaderModule mFragmentModule = VK_NULL_HANDLE;
|
||||
};
|
||||
|
||||
class Application {
|
||||
public:
|
||||
void run() {
|
||||
|
|
@ -99,6 +200,8 @@ private:
|
|||
createSwapChain(width, height);
|
||||
createSwapChainImageViews();
|
||||
|
||||
mShader.create(mDevice);
|
||||
|
||||
createRenderPass();
|
||||
createGraphicsPipeline();
|
||||
|
||||
|
|
@ -521,30 +624,6 @@ private:
|
|||
}
|
||||
|
||||
void createGraphicsPipeline() {
|
||||
std::vector<char> vertShaderByteCode = readFile("bin/vert.spv");
|
||||
mShaderModuleVert = createShaderModule(vertShaderByteCode);
|
||||
|
||||
VkPipelineShaderStageCreateInfo vertShaderStageCreateInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
||||
.stage = VK_SHADER_STAGE_VERTEX_BIT,
|
||||
.module = mShaderModuleVert,
|
||||
.pName = "main",
|
||||
};
|
||||
|
||||
std::vector<char> fragShaderByteCode = readFile("bin/frag.spv");
|
||||
mShaderModuleFrag = createShaderModule(fragShaderByteCode);
|
||||
|
||||
VkPipelineShaderStageCreateInfo fragShaderStageCreateInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
||||
.stage = VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
.module = mShaderModuleFrag,
|
||||
.pName = "main",
|
||||
};
|
||||
|
||||
VkPipelineShaderStageCreateInfo shaderStageCreateInfos[] = {
|
||||
vertShaderStageCreateInfo,
|
||||
fragShaderStageCreateInfo
|
||||
};
|
||||
|
||||
std::vector<VkDynamicState> dynamicStates = {
|
||||
VK_DYNAMIC_STATE_VIEWPORT,
|
||||
|
|
@ -557,15 +636,12 @@ private:
|
|||
.pDynamicStates = dynamicStates.data(),
|
||||
};
|
||||
|
||||
auto attributes = getShaderAttributesDescriptors();
|
||||
auto vertexInput = getShaderVertexInputDescription();
|
||||
|
||||
VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
|
||||
.vertexBindingDescriptionCount = 1,
|
||||
.pVertexBindingDescriptions = &vertexInput,
|
||||
.vertexAttributeDescriptionCount = (uint32_t) attributes.size(),
|
||||
.pVertexAttributeDescriptions = attributes.data(),
|
||||
.pVertexBindingDescriptions = &mShader.mVertexInputDescription,
|
||||
.vertexAttributeDescriptionCount = (uint32_t) mShader.mVertexAttributes.size(),
|
||||
.pVertexAttributeDescriptions = mShader.mVertexAttributes.data(),
|
||||
};
|
||||
|
||||
VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateCreateInfo{
|
||||
|
|
@ -643,7 +719,7 @@ private:
|
|||
VkGraphicsPipelineCreateInfo graphicsPipelineCreateInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
|
||||
.stageCount = 2,
|
||||
.pStages = shaderStageCreateInfos,
|
||||
.pStages = mShader.mStageCreateInfos.data(),
|
||||
.pVertexInputState = &vertexInputStateCreateInfo,
|
||||
.pInputAssemblyState = &inputAssemblyStateCreateInfo,
|
||||
.pViewportState = &viewportState,
|
||||
|
|
@ -710,46 +786,11 @@ private:
|
|||
}
|
||||
|
||||
void destroyGraphicsPipeline() {
|
||||
vkDestroyShaderModule(mDevice, mShaderModuleVert, nullptr);
|
||||
vkDestroyShaderModule(mDevice, mShaderModuleFrag, nullptr);
|
||||
mShader.destroy(mDevice);
|
||||
vkDestroyPipelineLayout(mDevice, mGraphicsPipelineLayout, nullptr);
|
||||
vkDestroyPipeline(mDevice, mGraphicsPipeline, nullptr);
|
||||
}
|
||||
|
||||
VkShaderModule createShaderModule(const std::vector<char> &bytecode) {
|
||||
VkShaderModuleCreateInfo createInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
|
||||
.codeSize = (uint32_t) bytecode.size(),
|
||||
.pCode = (uint32_t *) bytecode.data(),
|
||||
};
|
||||
|
||||
VkShaderModule shaderModule;
|
||||
|
||||
if (vkCreateShaderModule(mDevice, &createInfo, nullptr, &shaderModule) != VK_SUCCESS) {
|
||||
throw std::runtime_error("cannot create shader module");
|
||||
}
|
||||
|
||||
return shaderModule;
|
||||
}
|
||||
|
||||
static std::vector<char> readFile(const std::string &fileName) {
|
||||
std::ifstream file(fileName, std::ios::ate | std::ios::binary);
|
||||
|
||||
if (!file.is_open()) {
|
||||
throw std::runtime_error("cannot open file");
|
||||
}
|
||||
|
||||
size_t fileSize = (size_t) file.tellg();
|
||||
std::vector<char> buffer(fileSize);
|
||||
|
||||
file.seekg(0);
|
||||
file.read(buffer.data(), (std::streamsize) fileSize);
|
||||
|
||||
file.close();
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void createCommandPool() {
|
||||
VkCommandPoolCreateInfo createInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
|
||||
|
|
@ -1044,34 +1085,6 @@ private:
|
|||
*/
|
||||
}
|
||||
|
||||
static VkVertexInputBindingDescription getShaderVertexInputDescription() {
|
||||
return {
|
||||
.binding = 0,
|
||||
.stride = sizeof(Vertex),
|
||||
.inputRate = VK_VERTEX_INPUT_RATE_VERTEX,
|
||||
};
|
||||
}
|
||||
|
||||
static std::vector<VkVertexInputAttributeDescription> getShaderAttributesDescriptors() {
|
||||
std::vector<VkVertexInputAttributeDescription> out(2);
|
||||
|
||||
out[0] = {
|
||||
.location = 0,
|
||||
.binding = 0,
|
||||
.format = VK_FORMAT_R32G32_SFLOAT,
|
||||
.offset = offsetof(Vertex, pos),
|
||||
};
|
||||
|
||||
out[1] = {
|
||||
.location = 1,
|
||||
.binding = 0,
|
||||
.format = VK_FORMAT_R32G32B32_SFLOAT,
|
||||
.offset = offsetof(Vertex, color),
|
||||
};
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
void destroySynchronizationObjects() {
|
||||
vkDestroySemaphore(mDevice, mSemaphoreImageAcquired, nullptr);
|
||||
vkDestroySemaphore(mDevice, mSemaphoreFramebufferDrawn, nullptr);
|
||||
|
|
@ -1127,9 +1140,8 @@ private:
|
|||
std::vector<VkImageView> mSwapChainImageViews;
|
||||
std::vector<VkFramebuffer> mSwapChainFrameBuffers;
|
||||
|
||||
CustomShader mShader;
|
||||
VkPipeline mGraphicsPipeline = VK_NULL_HANDLE;
|
||||
VkShaderModule mShaderModuleVert = VK_NULL_HANDLE;
|
||||
VkShaderModule mShaderModuleFrag = VK_NULL_HANDLE;
|
||||
VkRenderPass mGraphicsRenderPass = VK_NULL_HANDLE;
|
||||
VkPipelineLayout mGraphicsPipelineLayout{}; // no uniforms used in the shader
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue