187 lines
4.3 KiB
C++
187 lines
4.3 KiB
C++
/*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "Base/ICloseable.hpp"
|
|
#include "Base/Utils.hpp"
|
|
#include "VertexInputDescription.hpp"
|
|
#include <string>
|
|
#include <stdexcept>
|
|
|
|
namespace openVulkanoCpp::Scene
|
|
{
|
|
enum class CullMode : uint32_t
|
|
{
|
|
NONE = 0,
|
|
FRONT,
|
|
BACK,
|
|
FRONT_AND_BACK
|
|
};
|
|
|
|
enum class Topology : uint32_t
|
|
{
|
|
POINT_LIST = 0,
|
|
LINE_LIST,
|
|
LINE_STRIPE,
|
|
TRIANGLE_LIST,
|
|
TRIANGLE_STRIP,
|
|
TRIANGLE_FAN,
|
|
LINE_LIST_WITH_ADJACENCY,
|
|
LINE_STRIP_WITH_ADJACENCY,
|
|
TRIANGLE_LIST_WITH_ADJACENCY,
|
|
TRIANGLE_STRIP_WITH_ADJACENCY,
|
|
PATCH_LIST
|
|
};
|
|
|
|
class ShaderProgramType
|
|
{
|
|
static constexpr std::string_view FILE_EXTENSIONS_OPENGL[] = {
|
|
".vert", ".tesc", ".tese", ".geom", ".frag", ".comp", ".mesh", ".task",
|
|
".rgen", ".rahit", ".rchit", ".rmiss", ".rint", ".rcall", ".glsl"
|
|
};
|
|
|
|
public:
|
|
enum Type : uint32_t {
|
|
VERTEX = 1,
|
|
TESSELLATION_CONTROL = 2,
|
|
TESSELLATION_EVALUATION = 4,
|
|
GEOMETRY = 8,
|
|
FRAGMENT = 16,
|
|
COMPUTE = 32,
|
|
|
|
// Mesh shader
|
|
MESH_TASK = 0x40,
|
|
MESH_MESH = 0x80,
|
|
|
|
// Raytracing
|
|
RAY_GEN = 0x100,
|
|
RAY_ANY_HIT = 0x200,
|
|
RAY_CLOSEST_HIT = 0x400,
|
|
RAY_MISS = 0x800,
|
|
RAY_INTERSECTION = 0x1000,
|
|
RAY_CALLABLE = 0x2000,
|
|
|
|
ALL_GRAPHICS = 0x0000001F
|
|
};
|
|
|
|
ShaderProgramType(Type type) : m_type(type) {}
|
|
|
|
[[nodiscard]] constexpr std::string_view GetExtensionOpenGL() const
|
|
{
|
|
return FILE_EXTENSIONS_OPENGL[GetId()];
|
|
}
|
|
|
|
[[nodiscard]] constexpr uint32_t GetId() const
|
|
{
|
|
if (m_type == ALL_GRAPHICS) return 14;
|
|
return Utils::Log2OfPow2(static_cast<uint32_t>(m_type));
|
|
}
|
|
|
|
[[nodiscard]] bool operator ==(Type rhs) const
|
|
{
|
|
return m_type == rhs;
|
|
}
|
|
|
|
[[nodiscard]] bool operator !=(Type rhs) const
|
|
{
|
|
return m_type != rhs;
|
|
}
|
|
|
|
[[nodiscard]] operator uint32_t() const
|
|
{
|
|
return m_type;
|
|
}
|
|
|
|
private:
|
|
Type m_type;
|
|
};
|
|
|
|
struct ShaderProgram
|
|
{
|
|
ShaderProgramType type;
|
|
std::string name;
|
|
|
|
ShaderProgram(ShaderProgramType type, const std::string& name) : type(type), name(name) {}
|
|
|
|
ShaderProgram(const ShaderProgram& program) : type(program.type), name(program.name) {}
|
|
|
|
ShaderProgram(ShaderProgram&& program) : type(program.type), name(std::move(program.name)) {}
|
|
|
|
[[nodiscard]] std::string GetShaderNameOpenGL() const
|
|
{
|
|
std::string oglName;
|
|
std::string_view ext = type.GetExtensionOpenGL();
|
|
oglName.reserve(name.size() + ext.size());
|
|
return oglName.append(name).append(ext);
|
|
}
|
|
|
|
[[nodiscard]] std::string GetShaderNameVulkan() const
|
|
{
|
|
return GetShaderNameOpenGL() + ".spv";
|
|
}
|
|
};
|
|
|
|
struct Shader final : public virtual ICloseable
|
|
{
|
|
std::vector<ShaderProgram> shaderPrograms{};
|
|
std::vector<VertexInputDescription> vertexInputDescriptions{};
|
|
Topology topology = Topology::TRIANGLE_LIST;
|
|
CullMode cullMode = CullMode::BACK;
|
|
ICloseable* renderShader = nullptr;
|
|
|
|
Shader() = default;
|
|
~Shader() override { if (renderShader) Shader::Close(); }
|
|
|
|
Shader& AddShaderProgram(const ShaderProgram& shaderProgram)
|
|
{
|
|
if (renderShader) throw std::runtime_error("Shader already initialized!");
|
|
shaderPrograms.push_back(shaderProgram);
|
|
return *this;
|
|
}
|
|
|
|
Shader& AddShaderProgram(ShaderProgram&& shaderProgram)
|
|
{
|
|
if (renderShader) throw std::runtime_error("Shader already initialized!");
|
|
shaderPrograms.push_back(std::move(shaderProgram));
|
|
return *this;
|
|
}
|
|
|
|
template<typename ...ARGS>
|
|
Shader& AddShaderProgram(ARGS&&... args)
|
|
{
|
|
if (renderShader) throw std::runtime_error("Shader already initialized!");
|
|
shaderPrograms.emplace_back(std::forward<ARGS>(args)...);
|
|
return *this;
|
|
}
|
|
|
|
Shader& AddVertexInputDescription(const VertexInputDescription& inputDescription, int bindingId = -1)
|
|
{
|
|
if (renderShader) throw std::runtime_error("Shader already initialized!");
|
|
if (bindingId < 0) bindingId = vertexInputDescriptions.size();
|
|
if (bindingId > vertexInputDescriptions.size())
|
|
{
|
|
vertexInputDescriptions.emplace_back(0, 0);
|
|
}
|
|
if (bindingId == vertexInputDescriptions.size())
|
|
{
|
|
vertexInputDescriptions.emplace_back(bindingId, inputDescription);
|
|
}
|
|
else
|
|
{
|
|
vertexInputDescriptions[bindingId] = inputDescription;
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
void Close() override
|
|
{
|
|
renderShader->Close();
|
|
renderShader = nullptr;
|
|
}
|
|
};
|
|
}
|