添加鼠标点击实体事件,添加spirv着色器系统
This commit is contained in:
6
.gitmodules
vendored
6
.gitmodules
vendored
@ -17,3 +17,9 @@
|
||||
[submodule "Hazel/vendor/ImGuizmo"]
|
||||
path = Hazel/vendor/ImGuizmo
|
||||
url = https://github.com/CedricGuillemet/ImGuizmo.git
|
||||
[submodule "Hazel/vendor/shaderc"]
|
||||
path = Hazel/vendor/shaderc
|
||||
url = https://github.com/google/shaderc.git
|
||||
[submodule "Hazel/vendor/SPIRV-Cross"]
|
||||
path = Hazel/vendor/SPIRV-Cross
|
||||
url = https://github.com/KhronosGroup/SPIRV-Cross.git
|
||||
|
||||
@ -6,6 +6,8 @@ add_subdirectory(vendor/spdlog)
|
||||
add_subdirectory(vendor/GLAD)
|
||||
add_subdirectory(vendor/glm)
|
||||
add_subdirectory(vendor/yaml-cpp)
|
||||
add_subdirectory(vendor/shaderc)
|
||||
add_subdirectory(vendor/SPIRV-Cross)
|
||||
|
||||
file(GLOB_RECURSE SOURCES "src/**.cpp")
|
||||
|
||||
@ -59,7 +61,9 @@ target_link_libraries(${PROJECT_NAME} PUBLIC
|
||||
opengl32
|
||||
glm::glm
|
||||
yaml-cpp::yaml-cpp
|
||||
|
||||
shaderc
|
||||
spirv-cross-cpp
|
||||
spirv-cross-core
|
||||
)
|
||||
# target_compile_definitions(${PROJECT_NAME} PRIVATE HZ_BUILD_DLL IMGUI_API=__declspec\(dllexport\) STB_IMAGE_IMPLEMENTATION)# 编译DLL时定义
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE STB_IMAGE_IMPLEMENTATION)
|
||||
|
||||
5
Hazel/src/Hazel/Core/Timer.cpp
Normal file
5
Hazel/src/Hazel/Core/Timer.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
//
|
||||
// Created by sfd on 25-6-8.
|
||||
//
|
||||
|
||||
#include "Timer.h"
|
||||
42
Hazel/src/Hazel/Core/Timer.h
Normal file
42
Hazel/src/Hazel/Core/Timer.h
Normal file
@ -0,0 +1,42 @@
|
||||
//
|
||||
// Created by sfd on 25-6-8.
|
||||
//
|
||||
|
||||
#ifndef TIMER_H
|
||||
#define TIMER_H
|
||||
|
||||
#include <chrono>
|
||||
#include "Core.h"
|
||||
|
||||
namespace Hazel
|
||||
{
|
||||
class HAZEL_API Timer
|
||||
{
|
||||
public:
|
||||
Timer()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
m_Start = std::chrono::high_resolution_clock::now();
|
||||
}
|
||||
|
||||
float Elapsed()
|
||||
{
|
||||
return std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::now() - m_Start).count() * 0.001f * 0.001f * 0.001f;
|
||||
}
|
||||
|
||||
float ElapsedMillis()
|
||||
{
|
||||
return Elapsed() * 1000.0f;
|
||||
}
|
||||
|
||||
private:
|
||||
std::chrono::time_point<std::chrono::high_resolution_clock> m_Start;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif //TIMER_H
|
||||
@ -75,7 +75,7 @@ namespace Hazel
|
||||
else if (Input::IsMouseButtonPressed(SDL_BUTTON_LEFT))
|
||||
MouseRotate(delta);
|
||||
else if (Input::IsMouseButtonPressed(SDL_BUTTON_RIGHT))
|
||||
MouseZoom(delta.y);
|
||||
MouseZoom(-delta.y);
|
||||
}
|
||||
|
||||
UpdateView();
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
#include <Hazel/Debug/Instrumentor.h>
|
||||
#include "RendererCommand.h"
|
||||
#include "Shader.h"
|
||||
#include "UniformBuffer.h"
|
||||
#include "glm/ext/matrix_transform.hpp"
|
||||
|
||||
|
||||
@ -51,6 +52,13 @@ namespace Hazel
|
||||
glm::vec4 QuadVertexPosition[4];
|
||||
|
||||
Renderer2D::Statistic Stats;
|
||||
|
||||
struct CameraData
|
||||
{
|
||||
glm::mat4 ViewProjection;
|
||||
};
|
||||
CameraData CameraBuffer;
|
||||
Ref<UniformBuffer> CameraUniformBuffer;
|
||||
};
|
||||
|
||||
static Renderer2DStorage s_Data;
|
||||
@ -128,6 +136,8 @@ namespace Hazel
|
||||
s_Data.QuadVertexPosition[1] = {0.5f, -0.5f, 0.0f, 1.0f};
|
||||
s_Data.QuadVertexPosition[2] = {0.5f, 0.5f, 0.0f, 1.0f};
|
||||
s_Data.QuadVertexPosition[3] = {-0.5f, 0.5f, 0.0f, 1.0f};
|
||||
|
||||
s_Data.CameraUniformBuffer = UniformBuffer::Create(sizeof(Renderer2DStorage::CameraBuffer), 0);
|
||||
}
|
||||
|
||||
void Renderer2D::BeginScene(const Camera& camera, const glm::mat4& tranform)
|
||||
@ -135,10 +145,11 @@ namespace Hazel
|
||||
HZ_PROFILE_FUNCTION();
|
||||
|
||||
const glm::mat4 viewProjection = camera.GetProjection() * glm::inverse(tranform);
|
||||
s_Data.CameraBuffer.ViewProjection = viewProjection;
|
||||
s_Data.CameraUniformBuffer->SetData(&s_Data.CameraBuffer, sizeof(Renderer2DStorage::CameraBuffer));
|
||||
|
||||
|
||||
s_Data.TextureShader->Bind();
|
||||
s_Data.TextureShader->SetMat4("u_ViewProjection", viewProjection);
|
||||
// s_Data.TextureShader->Bind();
|
||||
// s_Data.TextureShader->SetMat4("u_ViewProjection", viewProjection);
|
||||
|
||||
StartBatch();
|
||||
}
|
||||
@ -147,10 +158,13 @@ namespace Hazel
|
||||
{
|
||||
HZ_PROFILE_FUNCTION();
|
||||
|
||||
const glm::mat4 vieweProjection = camera.GetViewProjection();
|
||||
const glm::mat4 viewProjection = camera.GetViewProjection();
|
||||
|
||||
s_Data.TextureShader->Bind();
|
||||
s_Data.TextureShader->SetMat4("u_ViewProjection", vieweProjection);
|
||||
s_Data.CameraBuffer.ViewProjection = viewProjection;
|
||||
s_Data.CameraUniformBuffer->SetData(&s_Data.CameraBuffer, sizeof(Renderer2DStorage::CameraBuffer));
|
||||
|
||||
// s_Data.TextureShader->Bind();
|
||||
// s_Data.TextureShader->SetMat4("u_ViewProjection", viewProjection);
|
||||
|
||||
StartBatch();
|
||||
}
|
||||
@ -158,8 +172,10 @@ namespace Hazel
|
||||
void Renderer2D::BeginScene(const OrthographicCamera& camera)
|
||||
{
|
||||
HZ_PROFILE_FUNCTION();
|
||||
s_Data.TextureShader->Bind();
|
||||
s_Data.TextureShader->SetMat4("u_ViewProjection", camera.GetViewProjectionMatrix());
|
||||
// s_Data.TextureShader->Bind();
|
||||
// s_Data.TextureShader->SetMat4("u_ViewProjection", camera.GetViewProjectionMatrix());
|
||||
s_Data.CameraBuffer.ViewProjection = camera.GetViewProjectionMatrix();
|
||||
s_Data.CameraUniformBuffer->SetData(&s_Data.CameraBuffer, sizeof(Renderer2DStorage::CameraBuffer));
|
||||
|
||||
StartBatch();
|
||||
}
|
||||
|
||||
@ -29,7 +29,7 @@ namespace Hazel
|
||||
virtual void SetViewPort(uint32_t x, uint32_t y, uint32_t width, uint32_t height) = 0;
|
||||
virtual void Clear() = 0;
|
||||
|
||||
virtual void DrawIndexed(const std::shared_ptr<VertexArray>& vertexArray, uint32_t indexCount = 0) = 0;
|
||||
virtual void DrawIndexed(const std::shared_ptr<VertexArray>& vertexArray, uint32_t indexCount) = 0;
|
||||
|
||||
inline static API GetAPI() {return s_API; }
|
||||
|
||||
|
||||
@ -31,7 +31,11 @@ namespace Hazel {
|
||||
s_RendererAPI->Clear();
|
||||
}
|
||||
|
||||
inline static void DrawIndexed(const std::shared_ptr<VertexArray>& vertexArray, uint32_t indexCount = 0)
|
||||
inline static void DrawIndexed(const std::shared_ptr<VertexArray>& vertexArray)
|
||||
{
|
||||
s_RendererAPI->DrawIndexed(vertexArray, -1);
|
||||
}
|
||||
inline static void DrawIndexed(const std::shared_ptr<VertexArray>& vertexArray, const uint32_t indexCount)
|
||||
{
|
||||
s_RendererAPI->DrawIndexed(vertexArray, indexCount);
|
||||
}
|
||||
|
||||
29
Hazel/src/Hazel/Renderer/UniformBuffer.cpp
Normal file
29
Hazel/src/Hazel/Renderer/UniformBuffer.cpp
Normal file
@ -0,0 +1,29 @@
|
||||
//
|
||||
// Created by sfd on 25-6-8.
|
||||
//
|
||||
|
||||
#include "UniformBuffer.h"
|
||||
|
||||
#include <Platform/OpenGL/OpenGLUniformBuffer.h>
|
||||
|
||||
#include "Renderer.h"
|
||||
|
||||
namespace Hazel
|
||||
{
|
||||
Ref<UniformBuffer> UniformBuffer::Create(uint32_t size, uint32_t binding)
|
||||
{
|
||||
switch (Renderer::GetAPI())
|
||||
{
|
||||
case RendererAPI::API::NONE:
|
||||
HZ_CORE_ERROR("NONE is not Support!");
|
||||
return nullptr;
|
||||
case RendererAPI::API::OPENGL:
|
||||
return CreateRef<OpenGLUniformBuffer>(size, binding);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
HZ_CORE_ERROR("Unknown RendererAPI!");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
23
Hazel/src/Hazel/Renderer/UniformBuffer.h
Normal file
23
Hazel/src/Hazel/Renderer/UniformBuffer.h
Normal file
@ -0,0 +1,23 @@
|
||||
//
|
||||
// Created by sfd on 25-6-8.
|
||||
//
|
||||
|
||||
#ifndef UNIFORMBUFFER_H
|
||||
#define UNIFORMBUFFER_H
|
||||
|
||||
#include "Hazel/Core/Core.h"
|
||||
|
||||
namespace Hazel
|
||||
{
|
||||
class HAZEL_API UniformBuffer
|
||||
{
|
||||
public:
|
||||
virtual ~UniformBuffer() {}
|
||||
virtual void SetData(const void* data, uint32_t size, uint32_t offset = 0) = 0;
|
||||
|
||||
static Ref<UniformBuffer> Create(uint32_t size, uint32_t binding);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif //UNIFORMBUFFER_H
|
||||
@ -35,7 +35,11 @@ namespace Hazel
|
||||
|
||||
void OpenGLRendererAPI::DrawIndexed(const std::shared_ptr<Hazel::VertexArray>& vertexArray, const uint32_t indexCount)
|
||||
{
|
||||
const uint32_t count = indexCount ? indexCount : vertexArray->GetIndexBuffer()->GetCount();
|
||||
uint32_t count;
|
||||
if (indexCount != -1)
|
||||
count = indexCount;
|
||||
else
|
||||
count = vertexArray->GetIndexBuffer()->GetCount();
|
||||
glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_INT, nullptr);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
@ -7,14 +7,90 @@
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
#include <array>
|
||||
#include <filesystem>
|
||||
#include <Hazel/Core/Log.h>
|
||||
#include <Hazel/Debug/Instrumentor.h>
|
||||
#include <shaderc/shaderc.hpp>
|
||||
|
||||
#include <spirv_cross.hpp>
|
||||
#include <spirv_glsl.hpp>
|
||||
#include <Hazel/Core/Timer.h>
|
||||
|
||||
#include "glm/gtc/type_ptr.hpp"
|
||||
#include "spdlog/fmt/bundled/compile.h"
|
||||
|
||||
namespace Hazel
|
||||
{
|
||||
namespace Utils
|
||||
{
|
||||
static GLenum ShaderTypeFromString(const std::string& type)
|
||||
{
|
||||
if (type == "vertex")
|
||||
return GL_VERTEX_SHADER;
|
||||
if (type == "fragment" || type == "pixel")
|
||||
return GL_FRAGMENT_SHADER;
|
||||
|
||||
HZ_CORE_ERROR("Unknown shader type!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char* GLShaderStageToString(GLenum stage)
|
||||
{
|
||||
switch (stage)
|
||||
{
|
||||
case GL_VERTEX_SHADER: return "GL_VERTEX_SHADER";
|
||||
case GL_FRAGMENT_SHADER: return "GL_FRAGMENT_SHADER";
|
||||
}
|
||||
HZ_CORE_ERROR("Unknown shader stage!");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static shaderc_shader_kind GLShaderStageToShaderC(GLenum stage)
|
||||
{
|
||||
switch (stage)
|
||||
{
|
||||
case GL_VERTEX_SHADER: return shaderc_glsl_vertex_shader;
|
||||
case GL_FRAGMENT_SHADER: return shaderc_glsl_fragment_shader;
|
||||
}
|
||||
HZ_CORE_ERROR("Unknown shader stage!");
|
||||
return (shaderc_shader_kind)0;
|
||||
}
|
||||
|
||||
static const char* GLShaderStageCachedOpenGLFileExtension(uint32_t stage)
|
||||
{
|
||||
switch (stage)
|
||||
{
|
||||
case GL_VERTEX_SHADER: return ".cached_opengl.vert";
|
||||
case GL_FRAGMENT_SHADER: return ".cached_opengl.frag";
|
||||
}
|
||||
HZ_CORE_ERROR("cannot find opengl shader cache");
|
||||
return "";
|
||||
}
|
||||
|
||||
static const char* GLShaderStageCachedVulkanFileExtension(uint32_t stage)
|
||||
{
|
||||
switch (stage)
|
||||
{
|
||||
case GL_VERTEX_SHADER: return ".cached_vulkan.vert";
|
||||
case GL_FRAGMENT_SHADER: return ".cached_vulkan.frag";
|
||||
}
|
||||
HZ_CORE_ERROR("cannot find vulkan shader cache");
|
||||
return "";
|
||||
}
|
||||
|
||||
static const char* GetCacheDirectory()
|
||||
{
|
||||
return "assets/cache/shader/opengl";
|
||||
}
|
||||
|
||||
static void CreateCacheDirectoryIfNeeded()
|
||||
{
|
||||
const std::string cacheDirectory = GetCacheDirectory();
|
||||
if (!std::filesystem::exists(cacheDirectory))
|
||||
std::filesystem::create_directories(cacheDirectory);
|
||||
}
|
||||
}
|
||||
|
||||
static GLenum ShaderTypeFromString(const std::string& type)
|
||||
{
|
||||
if (type == "vertex") return GL_VERTEX_SHADER;
|
||||
@ -27,8 +103,29 @@ namespace Hazel
|
||||
|
||||
|
||||
OpenGLShader::OpenGLShader(const std::string& filepath)
|
||||
: m_FilePath(filepath)
|
||||
{
|
||||
HZ_PROFILE_FUNCTION();
|
||||
|
||||
Utils::CreateCacheDirectoryIfNeeded();
|
||||
|
||||
|
||||
const std::string source = ReadFile(filepath);
|
||||
auto shaderSource = PreProcess(source);
|
||||
|
||||
{
|
||||
Timer timer;
|
||||
CompileOrGetVulkanBinaries(shaderSource);
|
||||
CompileOrGetOpenGLBinaries();
|
||||
CreateProgram();
|
||||
HZ_CORE_INFO("shader create took {0}ms",timer.ElapsedMillis());
|
||||
}
|
||||
|
||||
const auto lastSlash = filepath.find_last_of("\\/");
|
||||
const auto lastDot = filepath.find_last_of(".");
|
||||
m_Name = filepath.substr(lastSlash + 1, lastDot - lastSlash - 1);
|
||||
|
||||
/*
|
||||
std::string shaderSrc = ReadFile(filepath);
|
||||
auto shaderSources = PreProcess(shaderSrc);
|
||||
Compile(shaderSources);
|
||||
@ -39,7 +136,6 @@ namespace Hazel
|
||||
m_Name = filepath.substr(lastSlash + 1, lastDot - lastSlash - 1);
|
||||
|
||||
|
||||
/*
|
||||
auto lastSlash = filepath.find_last_of("\\/");
|
||||
lastSlash = lastSlash == std::string::npos ? 0 : lastSlash + 1;
|
||||
auto lastDot = filepath.rfind(".");
|
||||
@ -48,13 +144,19 @@ namespace Hazel
|
||||
*/
|
||||
}
|
||||
|
||||
OpenGLShader::OpenGLShader(const std::string& name, const std::string& vertexSrc, const std::string& fragmentSrc): m_Name(name)
|
||||
OpenGLShader::OpenGLShader(const std::string& name, const std::string& vertexSrc, const std::string& fragmentSrc)
|
||||
: m_Name(name)
|
||||
{
|
||||
HZ_PROFILE_FUNCTION();
|
||||
|
||||
std::unordered_map<GLenum, std::string> shaderSources;
|
||||
shaderSources[GL_VERTEX_SHADER] = vertexSrc;
|
||||
shaderSources[GL_FRAGMENT_SHADER] = fragmentSrc;
|
||||
Compile(shaderSources);
|
||||
// Compile(shaderSources);
|
||||
|
||||
CompileOrGetVulkanBinaries(shaderSources);
|
||||
CompileOrGetOpenGLBinaries();
|
||||
CreateProgram();
|
||||
}
|
||||
|
||||
|
||||
@ -249,6 +351,188 @@ namespace Hazel
|
||||
m_RendererID = program;
|
||||
}
|
||||
|
||||
void OpenGLShader::CompileOrGetVulkanBinaries(const std::unordered_map<GLenum, std::string>& shaderSources)
|
||||
{
|
||||
|
||||
GLuint program = glCreateProgram();
|
||||
|
||||
shaderc::Compiler compiler;
|
||||
shaderc::CompileOptions options;
|
||||
options.SetTargetEnvironment(shaderc_target_env_vulkan, shaderc_env_version_vulkan_1_2);
|
||||
const bool optimize = true;
|
||||
if (optimize)
|
||||
options.SetOptimizationLevel(shaderc_optimization_level_performance);
|
||||
|
||||
std::filesystem::path cacheDirectory = Utils::GetCacheDirectory();
|
||||
|
||||
auto& shaderData = m_VulkanSPIRV;
|
||||
shaderData.clear();
|
||||
for (auto&& [stage, source] : shaderSources)
|
||||
{
|
||||
std::filesystem::path shaderFilePath = m_FilePath;
|
||||
std::filesystem::path cachedPath = cacheDirectory / (shaderFilePath.filename().string() + Utils::GLShaderStageCachedVulkanFileExtension(stage));
|
||||
|
||||
std::ifstream in(cachedPath, std::ios::in | std::ios::binary);
|
||||
if (in.is_open())
|
||||
{
|
||||
in.seekg(0, std::ios::end);
|
||||
auto size = in.tellg();
|
||||
in.seekg(0, std::ios::beg);
|
||||
|
||||
auto& data = shaderData[stage];
|
||||
data.resize(size / sizeof(uint32_t));
|
||||
in.read((char*)data.data(), size);
|
||||
}
|
||||
else
|
||||
{
|
||||
shaderc::SpvCompilationResult module = compiler.CompileGlslToSpv(source, Utils::GLShaderStageToShaderC(stage), m_FilePath.c_str(), options);
|
||||
if (module.GetCompilationStatus() != shaderc_compilation_status_success)
|
||||
{
|
||||
HZ_CORE_ERROR(module.GetErrorMessage());
|
||||
assert(-1);
|
||||
}
|
||||
|
||||
shaderData[stage] = std::vector<uint32_t>(module.cbegin(), module.cend());
|
||||
|
||||
std::ofstream out(cachedPath, std::ios::out | std::ios::binary);
|
||||
if (out.is_open())
|
||||
{
|
||||
auto& data = shaderData[stage];
|
||||
out.write((char*)data.data(), data.size() * sizeof(uint32_t));
|
||||
out.flush();
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (auto&& [stage, data]: shaderData)
|
||||
Reflect(stage, data);
|
||||
}
|
||||
|
||||
void OpenGLShader::CompileOrGetOpenGLBinaries()
|
||||
{
|
||||
|
||||
auto& shaderData = m_OpenGLSPIRV;
|
||||
|
||||
shaderc::Compiler compiler;
|
||||
shaderc::CompileOptions options;
|
||||
options.SetTargetEnvironment(shaderc_target_env_opengl, shaderc_env_version_opengl_4_5);
|
||||
const bool optimize = false;
|
||||
if (optimize)
|
||||
options.SetOptimizationLevel(shaderc_optimization_level_performance);
|
||||
|
||||
std::filesystem::path cacheDirectory = Utils::GetCacheDirectory();
|
||||
|
||||
shaderData.clear();
|
||||
m_OpenGLSourceCode.clear();
|
||||
for (auto&& [stage, spirv] : m_VulkanSPIRV)
|
||||
{
|
||||
std::filesystem::path shaderFilePath = m_FilePath;
|
||||
std::filesystem::path cachedPath = cacheDirectory / (shaderFilePath.filename().string() + Utils::GLShaderStageCachedOpenGLFileExtension(stage));
|
||||
|
||||
std::ifstream in(cachedPath, std::ios::in | std::ios::binary);
|
||||
if (in.is_open())
|
||||
{
|
||||
in.seekg(0, std::ios::end);
|
||||
auto size = in.tellg();
|
||||
in.seekg(0, std::ios::beg);
|
||||
|
||||
auto& data = shaderData[stage];
|
||||
data.resize(size / sizeof(uint32_t));
|
||||
in.read((char*)data.data(), size);
|
||||
}
|
||||
else
|
||||
{
|
||||
spirv_cross::CompilerGLSL glslCompiler(spirv);
|
||||
m_OpenGLSourceCode[stage] = glslCompiler.compile();
|
||||
auto& source = m_OpenGLSourceCode[stage];
|
||||
|
||||
shaderc::SpvCompilationResult module = compiler.CompileGlslToSpv(source, Utils::GLShaderStageToShaderC(stage), m_FilePath.c_str());
|
||||
if (module.GetCompilationStatus() != shaderc_compilation_status_success)
|
||||
{
|
||||
HZ_CORE_ERROR(module.GetErrorMessage());
|
||||
assert(-1);
|
||||
}
|
||||
|
||||
shaderData[stage] = std::vector<uint32_t>(module.cbegin(), module.cend());
|
||||
|
||||
std::ofstream out(cachedPath, std::ios::out | std::ios::binary);
|
||||
if (out.is_open())
|
||||
{
|
||||
auto& data = shaderData[stage];
|
||||
out.write((char*)data.data(), data.size() * sizeof(uint32_t));
|
||||
out.flush();
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OpenGLShader::CreateProgram()
|
||||
{
|
||||
GLuint program = glCreateProgram();
|
||||
|
||||
std::vector<GLuint> shaderIDs;
|
||||
for (auto&& [stage, spirv] : m_OpenGLSPIRV)
|
||||
{
|
||||
GLuint shaderID = shaderIDs.emplace_back(glCreateShader(stage));
|
||||
glShaderBinary(1, &shaderID, GL_SHADER_BINARY_FORMAT_SPIR_V, spirv.data(), spirv.size() * sizeof(uint32_t));
|
||||
glSpecializeShader(shaderID, "main", 0, nullptr, nullptr);
|
||||
glAttachShader(program, shaderID);
|
||||
}
|
||||
|
||||
glLinkProgram(program);
|
||||
|
||||
GLint isLinked;
|
||||
glGetProgramiv(program, GL_LINK_STATUS, &isLinked);
|
||||
if (isLinked == GL_FALSE)
|
||||
{
|
||||
GLint maxLength;
|
||||
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLength);
|
||||
|
||||
std::vector<GLchar> infoLog(maxLength);
|
||||
glGetProgramInfoLog(program, maxLength, &maxLength, infoLog.data());
|
||||
HZ_CORE_ERROR("Shader linking failed ({0}):\n{1}", m_FilePath, infoLog.data());
|
||||
|
||||
glDeleteProgram(program);
|
||||
|
||||
for (auto id : shaderIDs)
|
||||
glDeleteShader(id);
|
||||
}
|
||||
|
||||
for (auto id : shaderIDs)
|
||||
{
|
||||
glDetachShader(program, id);
|
||||
glDeleteShader(id);
|
||||
}
|
||||
|
||||
m_RendererID = program;
|
||||
}
|
||||
|
||||
void OpenGLShader::Reflect(GLenum stage, const std::vector<uint32_t>& shaderData)
|
||||
{
|
||||
spirv_cross::Compiler compiler(shaderData);
|
||||
spirv_cross::ShaderResources resources = compiler.get_shader_resources();
|
||||
|
||||
HZ_CORE_INFO("OpenGLShader::Reflect - {0} {1}", Utils::GLShaderStageToString(stage), m_FilePath);
|
||||
HZ_CORE_TRACE(" {0} uniform buffers", resources.uniform_buffers.size());
|
||||
HZ_CORE_TRACE(" {0} resources", resources.sampled_images.size());
|
||||
|
||||
HZ_CORE_TRACE("Uniform buffers:");
|
||||
for (const auto& resource : resources.uniform_buffers)
|
||||
{
|
||||
const auto& bufferType = compiler.get_type(resource.base_type_id);
|
||||
uint32_t bufferSize = compiler.get_declared_struct_size(bufferType);
|
||||
uint32_t binding = compiler.get_decoration(resource.id, spv::DecorationBinding);
|
||||
int memberCount = bufferType.member_types.size();
|
||||
|
||||
HZ_CORE_TRACE(" {0}", resource.name);
|
||||
HZ_CORE_TRACE(" Size = {0}", bufferSize);
|
||||
HZ_CORE_TRACE(" Binding = {0}", binding);
|
||||
HZ_CORE_TRACE(" Members = {0}", memberCount);
|
||||
}
|
||||
}
|
||||
|
||||
void OpenGLShader::UploadUniformFloat3(const std::string& name, const glm::vec3& value) const
|
||||
{
|
||||
GLint location = glGetUniformLocation(m_RendererID, name.c_str());
|
||||
|
||||
@ -47,9 +47,20 @@ namespace Hazel
|
||||
std::unordered_map<GLenum, std::string> PreProcess(const std::string& source);
|
||||
void Compile(std::unordered_map<GLenum, std::string>& shaderSource);
|
||||
|
||||
void CompileOrGetVulkanBinaries(const std::unordered_map<GLenum, std::string>& shaderSources);
|
||||
void CompileOrGetOpenGLBinaries();
|
||||
void CreateProgram();
|
||||
void Reflect(GLenum stage, const std::vector<uint32_t>& shaderData);
|
||||
|
||||
private:
|
||||
uint32_t m_RendererID;
|
||||
std::string m_FilePath;
|
||||
std::string m_Name;
|
||||
|
||||
std::unordered_map<GLenum, std::vector<uint32_t>> m_VulkanSPIRV;
|
||||
std::unordered_map<GLenum, std::vector<uint32_t>> m_OpenGLSPIRV;
|
||||
|
||||
std::unordered_map<GLenum, std::string> m_OpenGLSourceCode;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
28
Hazel/src/Platform/OpenGL/OpenGLUniformBuffer.cpp
Normal file
28
Hazel/src/Platform/OpenGL/OpenGLUniformBuffer.cpp
Normal file
@ -0,0 +1,28 @@
|
||||
//
|
||||
// Created by sfd on 25-6-8.
|
||||
//
|
||||
|
||||
#include "OpenGLUniformBuffer.h"
|
||||
|
||||
#include <glad/glad.h>
|
||||
|
||||
namespace Hazel
|
||||
{
|
||||
OpenGLUniformBuffer::OpenGLUniformBuffer(uint32_t size, uint32_t binding)
|
||||
{
|
||||
glCreateBuffers(1, &m_RendererID);
|
||||
glNamedBufferData(m_RendererID, size, nullptr, GL_DYNAMIC_DRAW); // TODO: investigate usage hint
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER, binding, m_RendererID);
|
||||
}
|
||||
|
||||
OpenGLUniformBuffer::~OpenGLUniformBuffer()
|
||||
{
|
||||
glDeleteBuffers(1, &m_RendererID);
|
||||
}
|
||||
|
||||
|
||||
void OpenGLUniformBuffer::SetData(const void* data, uint32_t size, uint32_t offset)
|
||||
{
|
||||
glNamedBufferSubData(m_RendererID, offset, size, data);
|
||||
}
|
||||
}
|
||||
25
Hazel/src/Platform/OpenGL/OpenGLUniformBuffer.h
Normal file
25
Hazel/src/Platform/OpenGL/OpenGLUniformBuffer.h
Normal file
@ -0,0 +1,25 @@
|
||||
//
|
||||
// Created by sfd on 25-6-8.
|
||||
//
|
||||
|
||||
#ifndef OPENGLUNIFORMBUFFER_H
|
||||
#define OPENGLUNIFORMBUFFER_H
|
||||
#include <Hazel/Renderer/UniformBuffer.h>
|
||||
|
||||
namespace Hazel
|
||||
{
|
||||
class OpenGLUniformBuffer : public UniformBuffer
|
||||
{
|
||||
public:
|
||||
OpenGLUniformBuffer(uint32_t size, uint32_t binding);
|
||||
|
||||
virtual ~OpenGLUniformBuffer();
|
||||
|
||||
virtual void SetData(const void* data, uint32_t size, uint32_t offset = 0) override;
|
||||
private:
|
||||
uint32_t m_RendererID = 0;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif //OPENGLUNIFORMBUFFER_H
|
||||
1
Hazel/vendor/SPIRV-Cross
vendored
Submodule
1
Hazel/vendor/SPIRV-Cross
vendored
Submodule
Submodule Hazel/vendor/SPIRV-Cross added at 1a69a919fa
1
Hazel/vendor/shaderc
vendored
Submodule
1
Hazel/vendor/shaderc
vendored
Submodule
Submodule Hazel/vendor/shaderc added at a5a8caa195
@ -17,7 +17,9 @@ set(PROJECT_NAME "${PROJECT_NAME}-Editor")
|
||||
project(${PROJECT_NAME})
|
||||
file(GLOB_RECURSE SOURCES
|
||||
src/SandboxApp.cpp
|
||||
src/Editor/**.cpp)
|
||||
src/Editor/**.cpp
|
||||
src/logo/logo.rc
|
||||
)
|
||||
|
||||
add_executable(${PROJECT_NAME} ${SOURCES})
|
||||
|
||||
|
||||
@ -6,12 +6,13 @@
|
||||
layout(location = 0) in vec3 a_Position;
|
||||
layout(location = 1) in vec2 a_TexCoord;
|
||||
|
||||
uniform mat4 u_ViewProjection;
|
||||
uniform mat4 u_Transform;
|
||||
|
||||
layout(std140, binding = 0) uniform Camera
|
||||
{
|
||||
mat4 u_ViewProjection;
|
||||
};
|
||||
|
||||
void main() {
|
||||
gl_Position = u_ViewProjection * u_Transform * vec4(a_Position, 1.0f);
|
||||
gl_Position = u_ViewProjection * vec4(a_Position, 1.0f);
|
||||
}
|
||||
|
||||
#type fragment
|
||||
@ -19,8 +20,7 @@ void main() {
|
||||
|
||||
layout(location = 0) out vec4 color;
|
||||
|
||||
uniform vec4 u_Color;
|
||||
|
||||
void main() {
|
||||
color = u_Color;
|
||||
color = vec4(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
// Basic Texture Shader
|
||||
|
||||
#type vertex
|
||||
#version 460 core
|
||||
#version 450 core
|
||||
|
||||
layout(location = 0) in vec3 a_Position;
|
||||
layout(location = 1) in vec4 a_Color;
|
||||
@ -8,43 +10,55 @@ layout(location = 3) in float a_TexIndex;
|
||||
layout(location = 4) in float a_TilingFactor;
|
||||
layout(location = 5) in int a_EntityID;
|
||||
|
||||
uniform mat4 u_ViewProjection;
|
||||
//uniform mat4 u_Transform;
|
||||
layout(std140, binding = 0) uniform Camera
|
||||
{
|
||||
mat4 u_ViewProjection;
|
||||
};
|
||||
|
||||
out vec2 v_TexCoord;
|
||||
out vec4 v_Color;
|
||||
out flat float v_TexIndex;
|
||||
out float v_TilingFactor;
|
||||
out flat int v_EntityID;
|
||||
struct VertexOutput
|
||||
{
|
||||
vec4 Color;
|
||||
vec2 TexCoord;
|
||||
float TilingFactor;
|
||||
};
|
||||
|
||||
void main() {
|
||||
v_TexCoord = a_TexCoord;
|
||||
v_Color = a_Color;
|
||||
layout (location = 0) out VertexOutput Output;
|
||||
layout (location = 3) out flat float v_TexIndex;
|
||||
layout (location = 4) out flat int v_EntityID;
|
||||
|
||||
void main()
|
||||
{
|
||||
Output.Color = a_Color;
|
||||
Output.TexCoord = a_TexCoord;
|
||||
Output.TilingFactor = a_TilingFactor;
|
||||
v_TexIndex = a_TexIndex;
|
||||
v_TilingFactor = a_TilingFactor;
|
||||
v_EntityID = a_EntityID;
|
||||
|
||||
gl_Position = u_ViewProjection * vec4(a_Position, 1.0f);
|
||||
gl_Position = u_ViewProjection * vec4(a_Position, 1.0);
|
||||
}
|
||||
|
||||
#type fragment
|
||||
#version 460 core
|
||||
#version 450 core
|
||||
|
||||
layout(location = 0) out vec4 color;
|
||||
layout(location = 1) out int color2;
|
||||
layout(location = 0) out vec4 o_Color;
|
||||
layout(location = 1) out int o_EntityID;
|
||||
|
||||
in vec2 v_TexCoord;
|
||||
in vec4 v_Color;
|
||||
in flat float v_TexIndex;
|
||||
in float v_TilingFactor;
|
||||
in flat int v_EntityID;
|
||||
struct VertexOutput
|
||||
{
|
||||
vec4 Color;
|
||||
vec2 TexCoord;
|
||||
float TilingFactor;
|
||||
};
|
||||
|
||||
uniform vec4 u_Color;
|
||||
uniform sampler2D u_Textures[32];
|
||||
layout (location = 0) in VertexOutput Input;
|
||||
layout (location = 3) in flat float v_TexIndex;
|
||||
layout (location = 4) in flat int v_EntityID;
|
||||
|
||||
void main() {
|
||||
layout (binding = 0) uniform sampler2D u_Textures[32];
|
||||
|
||||
color = texture(u_Textures[int(v_TexIndex)], v_TexCoord * v_TilingFactor) * v_Color;
|
||||
// color = v_Color;
|
||||
color2 = v_EntityID;
|
||||
void main()
|
||||
{
|
||||
o_Color = texture(u_Textures[int(v_TexIndex)], Input.TexCoord * Input.TilingFactor) * Input.Color;
|
||||
|
||||
o_EntityID = v_EntityID;
|
||||
}
|
||||
|
||||
104
Sandbox/assets/shaders/quad.glsl
Normal file
104
Sandbox/assets/shaders/quad.glsl
Normal file
@ -0,0 +1,104 @@
|
||||
// Basic Texture Shader
|
||||
|
||||
#type vertex
|
||||
#version 450 core
|
||||
|
||||
layout(location = 0) in vec3 a_Position;
|
||||
layout(location = 1) in vec4 a_Color;
|
||||
layout(location = 2) in vec2 a_TexCoord;
|
||||
layout(location = 3) in float a_TexIndex;
|
||||
layout(location = 4) in float a_TilingFactor;
|
||||
layout(location = 5) in int a_EntityID;
|
||||
|
||||
layout(std140, binding = 0) uniform Camera
|
||||
{
|
||||
mat4 u_ViewProjection;
|
||||
};
|
||||
|
||||
struct VertexOutput
|
||||
{
|
||||
vec4 Color;
|
||||
vec2 TexCoord;
|
||||
float TilingFactor;
|
||||
};
|
||||
|
||||
layout (location = 0) out VertexOutput Output;
|
||||
layout (location = 3) out flat float v_TexIndex;
|
||||
layout (location = 4) out flat int v_EntityID;
|
||||
|
||||
void main()
|
||||
{
|
||||
Output.Color = a_Color;
|
||||
Output.TexCoord = a_TexCoord;
|
||||
Output.TilingFactor = a_TilingFactor;
|
||||
v_TexIndex = a_TexIndex;
|
||||
v_EntityID = a_EntityID;
|
||||
|
||||
gl_Position = u_ViewProjection * vec4(a_Position, 1.0);
|
||||
}
|
||||
|
||||
#type fragment
|
||||
#version 450 core
|
||||
|
||||
layout(location = 0) out vec4 o_Color;
|
||||
layout(location = 1) out int o_EntityID;
|
||||
|
||||
struct VertexOutput
|
||||
{
|
||||
vec4 Color;
|
||||
vec2 TexCoord;
|
||||
float TilingFactor;
|
||||
};
|
||||
|
||||
layout (location = 0) in VertexOutput Input;
|
||||
layout (location = 3) in flat float v_TexIndex;
|
||||
layout (location = 4) in flat int v_EntityID;
|
||||
|
||||
layout (binding = 0) uniform sampler2D u_Textures[32];
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 texColor = Input.Color;
|
||||
|
||||
switch(int(v_TexIndex))
|
||||
{
|
||||
case 0: texColor *= texture(u_Textures[ 0], Input.TexCoord * Input.TilingFactor); break;
|
||||
case 1: texColor *= texture(u_Textures[ 1], Input.TexCoord * Input.TilingFactor); break;
|
||||
case 2: texColor *= texture(u_Textures[ 2], Input.TexCoord * Input.TilingFactor); break;
|
||||
case 3: texColor *= texture(u_Textures[ 3], Input.TexCoord * Input.TilingFactor); break;
|
||||
case 4: texColor *= texture(u_Textures[ 4], Input.TexCoord * Input.TilingFactor); break;
|
||||
case 5: texColor *= texture(u_Textures[ 5], Input.TexCoord * Input.TilingFactor); break;
|
||||
case 6: texColor *= texture(u_Textures[ 6], Input.TexCoord * Input.TilingFactor); break;
|
||||
case 7: texColor *= texture(u_Textures[ 7], Input.TexCoord * Input.TilingFactor); break;
|
||||
case 8: texColor *= texture(u_Textures[ 8], Input.TexCoord * Input.TilingFactor); break;
|
||||
case 9: texColor *= texture(u_Textures[ 9], Input.TexCoord * Input.TilingFactor); break;
|
||||
case 10: texColor *= texture(u_Textures[10], Input.TexCoord * Input.TilingFactor); break;
|
||||
case 11: texColor *= texture(u_Textures[11], Input.TexCoord * Input.TilingFactor); break;
|
||||
case 12: texColor *= texture(u_Textures[12], Input.TexCoord * Input.TilingFactor); break;
|
||||
case 13: texColor *= texture(u_Textures[13], Input.TexCoord * Input.TilingFactor); break;
|
||||
case 14: texColor *= texture(u_Textures[14], Input.TexCoord * Input.TilingFactor); break;
|
||||
case 15: texColor *= texture(u_Textures[15], Input.TexCoord * Input.TilingFactor); break;
|
||||
case 16: texColor *= texture(u_Textures[16], Input.TexCoord * Input.TilingFactor); break;
|
||||
case 17: texColor *= texture(u_Textures[17], Input.TexCoord * Input.TilingFactor); break;
|
||||
case 18: texColor *= texture(u_Textures[18], Input.TexCoord * Input.TilingFactor); break;
|
||||
case 19: texColor *= texture(u_Textures[19], Input.TexCoord * Input.TilingFactor); break;
|
||||
case 20: texColor *= texture(u_Textures[20], Input.TexCoord * Input.TilingFactor); break;
|
||||
case 21: texColor *= texture(u_Textures[21], Input.TexCoord * Input.TilingFactor); break;
|
||||
case 22: texColor *= texture(u_Textures[22], Input.TexCoord * Input.TilingFactor); break;
|
||||
case 23: texColor *= texture(u_Textures[23], Input.TexCoord * Input.TilingFactor); break;
|
||||
case 24: texColor *= texture(u_Textures[24], Input.TexCoord * Input.TilingFactor); break;
|
||||
case 25: texColor *= texture(u_Textures[25], Input.TexCoord * Input.TilingFactor); break;
|
||||
case 26: texColor *= texture(u_Textures[26], Input.TexCoord * Input.TilingFactor); break;
|
||||
case 27: texColor *= texture(u_Textures[27], Input.TexCoord * Input.TilingFactor); break;
|
||||
case 28: texColor *= texture(u_Textures[28], Input.TexCoord * Input.TilingFactor); break;
|
||||
case 29: texColor *= texture(u_Textures[29], Input.TexCoord * Input.TilingFactor); break;
|
||||
case 30: texColor *= texture(u_Textures[30], Input.TexCoord * Input.TilingFactor); break;
|
||||
case 31: texColor *= texture(u_Textures[31], Input.TexCoord * Input.TilingFactor); break;
|
||||
}
|
||||
|
||||
if (texColor.a == 0.0)
|
||||
discard;
|
||||
|
||||
o_Color = texColor;
|
||||
o_EntityID = v_EntityID;
|
||||
}
|
||||
@ -63,7 +63,7 @@ namespace Hazel
|
||||
}
|
||||
|
||||
// update camera
|
||||
if (m_ViewportFocused && m_ViewportHovered)
|
||||
if (m_ViewportFocused)
|
||||
{
|
||||
m_CameraController.OnUpdate(ts);
|
||||
m_EditorCamera.OnUpdate(ts);
|
||||
@ -284,10 +284,9 @@ namespace Hazel
|
||||
snapValue = 0.25f;
|
||||
|
||||
float snapValues[3] = {snapValue, snapValue, snapValue};
|
||||
|
||||
if (ImGuizmo::Manipulate(glm::value_ptr(cameraView), glm::value_ptr(cameraProjection),
|
||||
ImGuizmo::OPERATION(m_GizmoType), ImGuizmo::LOCAL,
|
||||
glm::value_ptr(transform), nullptr, snap ? snapValues : nullptr))
|
||||
glm::value_ptr(transform), nullptr, snap ? snapValues : nullptr) && !Input::IsKeyPressed(SDL_SCANCODE_LALT))
|
||||
{
|
||||
if (ImGuizmo::IsUsing())
|
||||
{
|
||||
@ -352,11 +351,13 @@ namespace Hazel
|
||||
|
||||
void EditorLayer::OnEvent(SDL_Event& e)
|
||||
{
|
||||
if (m_ViewportFocused && m_ViewportHovered)
|
||||
if (m_ViewportFocused)
|
||||
{
|
||||
m_CameraController.OnEvent(e);
|
||||
m_EditorCamera.OnEvent(e);
|
||||
}
|
||||
if (e.button.clicks && m_ViewportHovered && !ImGuizmo::IsOver() && Input::IsMouseButtonPressed(SDL_BUTTON_LEFT) && !Input::IsKeyPressed(SDL_SCANCODE_LALT))
|
||||
m_SceneHierachyPanel.SetSelectedEntity(m_HoveredEntity);
|
||||
|
||||
#define SHORTCUT_NEW (SDL_KMOD_CTRL | SDLK_N)
|
||||
#define SHORTCUT_OPEN (SDL_KMOD_CTRL | SDLK_O)
|
||||
|
||||
@ -338,4 +338,9 @@ namespace Hazel
|
||||
ImGui::ColorEdit4("Color", glm::value_ptr(component.Color));
|
||||
});
|
||||
}
|
||||
|
||||
void SceneHierachyPanel::SetSelectedEntity(const Entity entity)
|
||||
{
|
||||
m_SelectionContext = entity;
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,6 +20,7 @@ namespace Hazel
|
||||
void OnImGuiRender();
|
||||
|
||||
void DrawComponents(Entity entity);
|
||||
void SetSelectedEntity(const Entity entity);
|
||||
|
||||
Entity GetSelectedEntity() const { return m_SelectionContext; }
|
||||
private:
|
||||
|
||||
Reference in New Issue
Block a user