add new render opengl

This commit is contained in:
ouczbs 2024-07-05 22:18:08 +08:00
parent b05c6dd27c
commit 50f7188503
22 changed files with 214 additions and 127 deletions

View File

@ -8,3 +8,4 @@ local utils = {
"spirv-cross-glsl","spirv-cross-cpp", "spirv-cross-core", "spirv-cross-reflect","spirv-cross-util"
}
add_requires("vulkansdk",{configs = {utils = utils}})
add_requires("opengl", "opencl-headers")

View File

@ -12,7 +12,7 @@ namespace engineapi {
const char* name = "zengine";
SystemList.push_back(new FileManager());
SystemList.push_back(new ResourceManager());
SystemList.push_back(RenderAPI::MakeInstance());
SystemList.push_back(RenderAPI::API(GraphicsAPI::OpenGL));
SystemList.push_back(Window::MakeInstance(3, 640, 720, name));
SystemList.push_back(new SceneManager());
}

View File

@ -0,0 +1,4 @@
#include "backend.h"
namespace openglapi {
}

View File

@ -0,0 +1,4 @@
#pragma once
namespace openglapi {
}

View File

@ -0,0 +1,15 @@
#include "opengl_glsl_loader.h"
#include "asset/file_handle.h"
using namespace engineapi;
namespace openglapi {
void OpenGLGlslLoader::Init()
{
ResourceManager::GetSingleton().RegisterLoader<OpenGLGlslLoader>(".frag");
ResourceManager::GetSingleton().RegisterLoader<OpenGLGlslLoader>(".vert");
}
ResourceBundle OpenGLGlslLoader::LoadFile(PackagePath path, const MetaBundle& meta)
{
return {};
}
}

View File

@ -0,0 +1,13 @@
#pragma once
#include "render/asset/shader.h"
#include "asset/resource_manager.h"
namespace openglapi {
using engineapi::table;
class OpenGLGlslLoader : public engineapi::IFileLoader
{
inline static table<engineapi::Guid, void*> ShaderTable;
public:
static void Init();
engineapi::ResourceBundle LoadFile(engineapi::PackagePath handle, const engineapi::MetaBundle& meta) override;
};
}

View File

@ -0,0 +1,33 @@
#include "openglapi.h"
#include "loader/opengl_glsl_loader.h"
namespace openglapi {
void RenderOpenGLApi::SwitchContext()
{
}
void RenderOpenGLApi::Init()
{
OpenGLGlslLoader::Init();
}
void RenderOpenGLApi::InitRenderPass()
{
}
void RenderOpenGLApi::SetViewPort(uint32_t width, uint32_t height, uint32_t xOffset, uint32_t yOffset)
{
}
void RenderOpenGLApi::BeginFrame()
{
}
void RenderOpenGLApi::EndFrame()
{
}
void RenderOpenGLApi::SetStaticMesh(Mesh& mesh)
{
}
void RenderOpenGLApi::DrawStaticMesh(Mesh& mesh)
{
}
void RenderOpenGLApi::LoadShader(Shader& shader)
{
}
}

View File

@ -0,0 +1,30 @@
#pragma once
#include "render/renderapi.h"
#include "asset/render/asset_struct.h"
#include "gl/GL.h"
namespace openglapi {
using engineapi::RenderContext;
using engineapi::Mesh;
using engineapi::Shader;
class RenderOpenGLApi : public engineapi::RenderAPI {
RenderContext context;
public:
RenderContext* GetContext() override {
return &context;
};
public:
void SwitchContext()override;
public:
void Init() override;
void InitRenderPass()override;
public:
void SetViewPort(uint32_t width, uint32_t height, uint32_t xOffset = 0, uint32_t yOffset = 0)override;
void BeginFrame()override;
void EndFrame()override;
void SetStaticMesh(Mesh& mesh)override;
void DrawStaticMesh(Mesh& mesh)override;
void LoadShader(Shader& shader)override;
};
}

View File

@ -0,0 +1,7 @@
#include "window.h"
namespace openglapi {
OpenGLWindow::OpenGLWindow(int frames, uint32_t width, uint32_t height, const char* title)
:engineapi::Window(width, height, title)
{
}
}

View File

@ -0,0 +1,8 @@
#pragma once
#include "render/window.h"
namespace openglapi {
class OpenGLWindow : public engineapi::Window {
public:
OpenGLWindow(int frames, uint32_t width, uint32_t height, const char* title);
};
}

View File

@ -4,6 +4,9 @@
#ifdef VULKAN_API
#include "vulkanapi/vulkanapi.h"
#endif // VULKAN_API
#ifdef OPENGL_API
#include "openglapi/openglapi.h"
#endif // OPENGL_API
namespace engineapi {
RenderAPI::RenderAPI()
{
@ -34,7 +37,22 @@ namespace engineapi {
RenderAPI* RenderAPI::MakeInstance()
{
#ifdef VULKAN_API
return new vulkanapi::RenderVulkanAPI();
if(api == GraphicsAPI::Vulkan)
return new vulkanapi::RenderVulkanAPI();
#endif
#ifdef OPENGL_API
if (api == GraphicsAPI::OpenGL)
return new openglapi::RenderOpenGLApi();
#endif
return nullptr;
}
RenderAPI* RenderAPI::API(GraphicsAPI _api)
{
if (ms_Singleton) {
delete ms_Singleton;
ms_Singleton = nullptr;
}
api = _api;
return MakeInstance();
}
}

View File

@ -40,5 +40,11 @@ namespace engineapi
public:
static RenderAPI* MakeInstance();
static GraphicsAPI API() {
return api;
}
static RenderAPI* API(GraphicsAPI _api);
private:
inline static GraphicsAPI api = GraphicsAPI::Vulkan;
};
}

View File

@ -0,0 +1,21 @@
#include "glsl_to_spirv.h"
#include <shaderc/shaderc.hpp>
namespace engineapi
{
optional<vector<uint32_t>> GlslToSpirv::spirv(const string& glsl, shaderc_shader_kind kind, string_view code_id)
{
optional<vector<uint32_t>> spirv_out;
{
shaderc::Compiler compiler;
shaderc::CompileOptions options;
options.SetOptimizationLevel(shaderc_optimization_level_performance);
options.SetTargetEnvironment(shaderc_target_env::shaderc_target_env_vulkan, shaderc_env_version_vulkan_1_3);
auto result = compiler.CompileGlslToSpv(glsl, kind, code_id.data(), options);
if (result.GetCompilationStatus() != shaderc_compilation_status::shaderc_compilation_status_success)
return spirv_out;
spirv_out = vector<uint32_t>{ result.cbegin(),result.cend() };
}
return spirv_out;
}
}

View File

@ -0,0 +1,17 @@
#pragma once
#include <optional>
#include <string_view>
#include <vector>
#include <shaderc/shaderc.h>
namespace engineapi
{
using std::string_view;
using std::string;
using std::vector;
using std::optional;
class GlslToSpirv
{
public:
static optional<vector<uint32_t>> spirv(const string& glsl, shaderc_shader_kind kind, string_view code_id = "unknown_shader");
};
}

View File

@ -1,14 +1,25 @@
#include "window.h"
#include "renderapi.h"
#ifdef VULKAN_API
#include "vulkanapi/window.h"
#endif // VULKAN_API
#ifdef OPENGL_API
#include "openglapi/window.h"
#endif // OPENGL_API
namespace engineapi {
Window::WindowClass Window::WindowClass::wndClass;
Window* Window::MakeInstance(int frames, uint32_t width, uint32_t height, const char* title)
{
GraphicsAPI api = RenderAPI::API();
#ifdef VULKAN_API
if(api == GraphicsAPI::Vulkan)
return new vulkanapi::VulkanWindow(frames, width, height, title);
#endif
#ifdef OPENGL_API
if (api == GraphicsAPI::OpenGL)
return new openglapi::OpenGLWindow(frames, width, height, title);
#endif
return nullptr;
}
Window::WindowClass::WindowClass() noexcept
:

View File

@ -1,13 +1,28 @@
#include "vulkan_glsl_loader.h"
#include "vulkanapi/tool/glsl_to_spirv.h"
#include "vulkanapi/vulkanapi.h"
#include "asset/file_manager.h"
#include "render/tool/glsl_to_spirv.h"
#include "render/asset/vertex.h"
#include "vkmeta_vertex_gen.inl"
#include <spirv_cross/spirv_reflect.hpp>
#include "asset/file_handle.h"
#include "meta/hash.h"
#include <vulkan/vulkan.hpp>
using namespace engineapi;
namespace vulkanapi {
using std::string_view;
using meta::string_hash;
shaderc_shader_kind ConvertStageSC(vk::ShaderStageFlagBits stage)
{
static hash_table< vk::ShaderStageFlagBits, shaderc_shader_kind> conv
{
{ vk::ShaderStageFlagBits::eVertex ,shaderc_shader_kind::shaderc_vertex_shader },
{ vk::ShaderStageFlagBits::eFragment ,shaderc_shader_kind::shaderc_fragment_shader },
{ vk::ShaderStageFlagBits::eGeometry ,shaderc_shader_kind::shaderc_geometry_shader },
{ vk::ShaderStageFlagBits::eTessellationControl ,shaderc_shader_kind::shaderc_tess_control_shader },
{ vk::ShaderStageFlagBits::eTessellationEvaluation,shaderc_shader_kind::shaderc_tess_evaluation_shader },
};
auto itr = conv.find(stage);
return itr->second;
}
vk::ShaderStageFlagBits GetShaderType(string_view ext)
{
switch (string_hash(ext))
@ -30,17 +45,6 @@ namespace vulkanapi {
ResourceManager::GetSingleton().RegisterLoader<VulkanGlslLoader>(".frag");
ResourceManager::GetSingleton().RegisterLoader<VulkanGlslLoader>(".vert");
}
void VulkanGlslLoader::LoadShaderInfo(const engineapi::Guid& guid, const std::vector<uint32_t>& spirv)
{
spirv_cross::Compiler compiler(spirv);
auto resources = compiler.get_shader_resources();
for (auto& ub : resources.uniform_buffers)
{
auto type = compiler.get_type(ub.type_id);
auto binding = compiler.get_decoration(ub.id, spv::Decoration::DecorationBinding);
auto set = compiler.get_decoration(ub.id, spv::Decoration::DecorationDescriptorSet);
}
}
ResourceBundle VulkanGlslLoader::LoadFile(PackagePath path, const MetaBundle& meta)
{
auto m = meta.FetchMeta<ShaderProgram>();
@ -55,15 +59,15 @@ namespace vulkanapi {
std::vector<unsigned int> spirv(data.size() / 4);
std::memcpy(spirv.data(), data.data(), data.size());
program->Load(spirv);
LoadShaderInfo(program->GetGuid(), spirv);
//LoadShaderInfo(program->GetGuid(), spirv);
}
else {
string glsl = handle.ReadAll<string>();
auto shader_enum = GetShaderType(path.GetExtension());
auto spirv = GlslToSpirv::spirv(glsl, shader_enum, path.GetFileName());
auto spirv = GlslToSpirv::spirv(glsl, ConvertStageSC(shader_enum), path.GetFileName());
if (spirv) {
program->Load(*spirv);
LoadShaderInfo(program->GetGuid(), *spirv);
//LoadShaderInfo(program->GetGuid(), *spirv);
}
}
return program;

View File

@ -17,7 +17,6 @@ namespace vulkanapi {
inline static table<engineapi::Guid, void*> ShaderTable;
public:
static void Init();
static void LoadShaderInfo(const engineapi::Guid& guid, const std::vector<unsigned int>& spirv);
engineapi::ResourceBundle LoadFile(engineapi::PackagePath handle, const engineapi::MetaBundle& meta) override;
};
}

View File

@ -1,40 +0,0 @@
#include "glsl_to_spirv.h"
#include "zstd/table.h"
#include "meta/hash.h"
#include "yaml/yaml.h"
#include <shaderc/shaderc.hpp>
#include <vector>
namespace vulkanapi
{
using std::vector;
using zstd::hash_table;
shaderc_shader_kind ConvertStageSC(vk::ShaderStageFlagBits stage)
{
static hash_table< vk::ShaderStageFlagBits, shaderc_shader_kind> conv
{
{ vk::ShaderStageFlagBits::eVertex ,shaderc_shader_kind::shaderc_vertex_shader },
{ vk::ShaderStageFlagBits::eFragment ,shaderc_shader_kind::shaderc_fragment_shader },
{ vk::ShaderStageFlagBits::eGeometry ,shaderc_shader_kind::shaderc_geometry_shader },
{ vk::ShaderStageFlagBits::eTessellationControl ,shaderc_shader_kind::shaderc_tess_control_shader },
{ vk::ShaderStageFlagBits::eTessellationEvaluation,shaderc_shader_kind::shaderc_tess_evaluation_shader },
};
auto itr = conv.find(stage);
return itr->second;
}
std::optional<std::vector<uint32_t>> GlslToSpirv::spirv(const string& glsl, vk::ShaderStageFlagBits v_stage, string_view code_id)
{
std::optional<std::vector<uint32_t>> spirv_out;
{
shaderc::Compiler compiler;
shaderc::CompileOptions options;
options.SetOptimizationLevel(shaderc_optimization_level_performance);
options.SetTargetEnvironment(shaderc_target_env::shaderc_target_env_vulkan, shaderc_env_version_vulkan_1_3);
auto result = compiler.CompileGlslToSpv(glsl, ConvertStageSC(v_stage), code_id.data(), options);
if (result.GetCompilationStatus() != shaderc_compilation_status::shaderc_compilation_status_success)
return spirv_out;
spirv_out = vector<uint32_t>{ result.cbegin(),result.cend() };
}
return spirv_out;
}
}

View File

@ -1,15 +0,0 @@
#pragma once
#include "vulkan/vulkan.hpp"
#include <glslang/public/ShaderLang.h>
#include <optional>
#include <string_view>
namespace vulkanapi
{
using std::string_view;
using std::string;
class GlslToSpirv
{
public:
static std::optional<std::vector<uint32_t>> spirv(const string& glsl, vk::ShaderStageFlagBits v_stage, string_view code_id = "unknown_shader");
};
}

View File

@ -1,33 +0,0 @@
#include "spirv_compiler.h"
namespace vulkanapi {
void SPIRVCompiler::CompileAllShader(string path)
{
for (const auto& entry : std::filesystem::directory_iterator(path))
{
string extension = entry.path().filename().extension().string();
if (extension == ".vert")
GenerateSPIRVVertFile(entry.path().string());
else if (extension == ".frag")
GenerateSPIRVFragFile(entry.path());
else if (extension == "")
CompileAllShader(entry.path().string());
}
}
void SPIRVCompiler::GenerateSPIRVFragFile(const filesystem::path& path)
{
string filePath = path.string();
string outputFinalPath = path.parent_path().string() + "\\" + path.stem().string() + ".spv";
//glslc simple.vert -o simple.vert.spv
//glslc simple.frag -o simple.frag.spv
//glslc -fshader-stage=vertex simple.vs.glsl -o simple.vert.spv
//glslc -fshader-stage=fragment simple.ps.glsl -o simple.frag.spv
string command = "glslc ";
std::system(command.c_str());
}
void SPIRVCompiler::GenerateSPIRVVertFile(const filesystem::path& path)
{
}
}

View File

@ -1,16 +0,0 @@
#pragma once
#include "../vulkan.h"
#include <filesystem>
namespace filesystem = std::filesystem;
namespace vulkanapi {
class Device;
class Queue;
class SPIRVCompiler {
public:
static void CompileAllShader(string path);
private:
static void GenerateSPIRVFragFile(const filesystem::path& path);
static void GenerateSPIRVVertFile(const filesystem::path& path);
};
}

View File

@ -12,8 +12,8 @@ target("zengine")
"src/engine/asset/res/*.h"}
})
add_deps("zlog","zlib")
add_defines("VULKAN_API")
add_packages("vulkansdk","tinyobjloader","assimp","nlohmann_json")
add_defines("VULKAN_API", "OPENGL_API")
add_packages("vulkansdk","tinyobjloader","assimp","nlohmann_json","opencl", "opencl-headers")
add_includedirs("src/engine")
add_includedirs("src/3rdparty/volk", "src/3rdparty/vulkan-memory-allocator", "src/3rdparty/template")
add_syslinks("user32", "Ole32")