添加鼠标点击实体事件,添加spirv着色器系统

This commit is contained in:
2025-06-09 13:19:14 +08:00
parent de75ee9481
commit f4aa895bbb
24 changed files with 664 additions and 54 deletions

6
.gitmodules vendored
View File

@ -17,3 +17,9 @@
[submodule "Hazel/vendor/ImGuizmo"] [submodule "Hazel/vendor/ImGuizmo"]
path = Hazel/vendor/ImGuizmo path = Hazel/vendor/ImGuizmo
url = https://github.com/CedricGuillemet/ImGuizmo.git 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

View File

@ -6,6 +6,8 @@ add_subdirectory(vendor/spdlog)
add_subdirectory(vendor/GLAD) add_subdirectory(vendor/GLAD)
add_subdirectory(vendor/glm) add_subdirectory(vendor/glm)
add_subdirectory(vendor/yaml-cpp) add_subdirectory(vendor/yaml-cpp)
add_subdirectory(vendor/shaderc)
add_subdirectory(vendor/SPIRV-Cross)
file(GLOB_RECURSE SOURCES "src/**.cpp") file(GLOB_RECURSE SOURCES "src/**.cpp")
@ -59,7 +61,9 @@ target_link_libraries(${PROJECT_NAME} PUBLIC
opengl32 opengl32
glm::glm glm::glm
yaml-cpp::yaml-cpp 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 HZ_BUILD_DLL IMGUI_API=__declspec\(dllexport\) STB_IMAGE_IMPLEMENTATION)# 编译DLL时定义
target_compile_definitions(${PROJECT_NAME} PRIVATE STB_IMAGE_IMPLEMENTATION) target_compile_definitions(${PROJECT_NAME} PRIVATE STB_IMAGE_IMPLEMENTATION)

View File

@ -0,0 +1,5 @@
//
// Created by sfd on 25-6-8.
//
#include "Timer.h"

View 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

View File

@ -75,7 +75,7 @@ namespace Hazel
else if (Input::IsMouseButtonPressed(SDL_BUTTON_LEFT)) else if (Input::IsMouseButtonPressed(SDL_BUTTON_LEFT))
MouseRotate(delta); MouseRotate(delta);
else if (Input::IsMouseButtonPressed(SDL_BUTTON_RIGHT)) else if (Input::IsMouseButtonPressed(SDL_BUTTON_RIGHT))
MouseZoom(delta.y); MouseZoom(-delta.y);
} }
UpdateView(); UpdateView();

View File

@ -9,6 +9,7 @@
#include <Hazel/Debug/Instrumentor.h> #include <Hazel/Debug/Instrumentor.h>
#include "RendererCommand.h" #include "RendererCommand.h"
#include "Shader.h" #include "Shader.h"
#include "UniformBuffer.h"
#include "glm/ext/matrix_transform.hpp" #include "glm/ext/matrix_transform.hpp"
@ -51,6 +52,13 @@ namespace Hazel
glm::vec4 QuadVertexPosition[4]; glm::vec4 QuadVertexPosition[4];
Renderer2D::Statistic Stats; Renderer2D::Statistic Stats;
struct CameraData
{
glm::mat4 ViewProjection;
};
CameraData CameraBuffer;
Ref<UniformBuffer> CameraUniformBuffer;
}; };
static Renderer2DStorage s_Data; 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[1] = {0.5f, -0.5f, 0.0f, 1.0f};
s_Data.QuadVertexPosition[2] = {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.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) void Renderer2D::BeginScene(const Camera& camera, const glm::mat4& tranform)
@ -135,10 +145,11 @@ namespace Hazel
HZ_PROFILE_FUNCTION(); HZ_PROFILE_FUNCTION();
const glm::mat4 viewProjection = camera.GetProjection() * glm::inverse(tranform); 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->Bind(); // s_Data.TextureShader->SetMat4("u_ViewProjection", viewProjection);
s_Data.TextureShader->SetMat4("u_ViewProjection", viewProjection);
StartBatch(); StartBatch();
} }
@ -147,10 +158,13 @@ namespace Hazel
{ {
HZ_PROFILE_FUNCTION(); HZ_PROFILE_FUNCTION();
const glm::mat4 vieweProjection = camera.GetViewProjection(); const glm::mat4 viewProjection = camera.GetViewProjection();
s_Data.TextureShader->Bind(); s_Data.CameraBuffer.ViewProjection = viewProjection;
s_Data.TextureShader->SetMat4("u_ViewProjection", vieweProjection); s_Data.CameraUniformBuffer->SetData(&s_Data.CameraBuffer, sizeof(Renderer2DStorage::CameraBuffer));
// s_Data.TextureShader->Bind();
// s_Data.TextureShader->SetMat4("u_ViewProjection", viewProjection);
StartBatch(); StartBatch();
} }
@ -158,8 +172,10 @@ namespace Hazel
void Renderer2D::BeginScene(const OrthographicCamera& camera) void Renderer2D::BeginScene(const OrthographicCamera& camera)
{ {
HZ_PROFILE_FUNCTION(); HZ_PROFILE_FUNCTION();
s_Data.TextureShader->Bind(); // s_Data.TextureShader->Bind();
s_Data.TextureShader->SetMat4("u_ViewProjection", camera.GetViewProjectionMatrix()); // 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(); StartBatch();
} }

View File

@ -29,7 +29,7 @@ namespace Hazel
virtual void SetViewPort(uint32_t x, uint32_t y, uint32_t width, uint32_t height) = 0; virtual void SetViewPort(uint32_t x, uint32_t y, uint32_t width, uint32_t height) = 0;
virtual void Clear() = 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; } inline static API GetAPI() {return s_API; }

View File

@ -31,7 +31,11 @@ namespace Hazel {
s_RendererAPI->Clear(); 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); s_RendererAPI->DrawIndexed(vertexArray, indexCount);
} }

View 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;
}
}

View 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

View File

@ -35,7 +35,11 @@ namespace Hazel
void OpenGLRendererAPI::DrawIndexed(const std::shared_ptr<Hazel::VertexArray>& vertexArray, const uint32_t indexCount) 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); glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_INT, nullptr);
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, 0);
} }

View File

@ -7,14 +7,90 @@
#include <fstream> #include <fstream>
#include <vector> #include <vector>
#include <array> #include <array>
#include <filesystem>
#include <Hazel/Core/Log.h> #include <Hazel/Core/Log.h>
#include <Hazel/Debug/Instrumentor.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 "glm/gtc/type_ptr.hpp"
#include "spdlog/fmt/bundled/compile.h" #include "spdlog/fmt/bundled/compile.h"
namespace Hazel 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) static GLenum ShaderTypeFromString(const std::string& type)
{ {
if (type == "vertex") return GL_VERTEX_SHADER; if (type == "vertex") return GL_VERTEX_SHADER;
@ -27,8 +103,29 @@ namespace Hazel
OpenGLShader::OpenGLShader(const std::string& filepath) OpenGLShader::OpenGLShader(const std::string& filepath)
: m_FilePath(filepath)
{ {
HZ_PROFILE_FUNCTION(); 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); std::string shaderSrc = ReadFile(filepath);
auto shaderSources = PreProcess(shaderSrc); auto shaderSources = PreProcess(shaderSrc);
Compile(shaderSources); Compile(shaderSources);
@ -39,7 +136,6 @@ namespace Hazel
m_Name = filepath.substr(lastSlash + 1, lastDot - lastSlash - 1); m_Name = filepath.substr(lastSlash + 1, lastDot - lastSlash - 1);
/*
auto lastSlash = filepath.find_last_of("\\/"); auto lastSlash = filepath.find_last_of("\\/");
lastSlash = lastSlash == std::string::npos ? 0 : lastSlash + 1; lastSlash = lastSlash == std::string::npos ? 0 : lastSlash + 1;
auto lastDot = filepath.rfind("."); 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(); HZ_PROFILE_FUNCTION();
std::unordered_map<GLenum, std::string> shaderSources; std::unordered_map<GLenum, std::string> shaderSources;
shaderSources[GL_VERTEX_SHADER] = vertexSrc; shaderSources[GL_VERTEX_SHADER] = vertexSrc;
shaderSources[GL_FRAGMENT_SHADER] = fragmentSrc; shaderSources[GL_FRAGMENT_SHADER] = fragmentSrc;
Compile(shaderSources); // Compile(shaderSources);
CompileOrGetVulkanBinaries(shaderSources);
CompileOrGetOpenGLBinaries();
CreateProgram();
} }
@ -249,6 +351,188 @@ namespace Hazel
m_RendererID = program; 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 void OpenGLShader::UploadUniformFloat3(const std::string& name, const glm::vec3& value) const
{ {
GLint location = glGetUniformLocation(m_RendererID, name.c_str()); GLint location = glGetUniformLocation(m_RendererID, name.c_str());

View File

@ -47,9 +47,20 @@ namespace Hazel
std::unordered_map<GLenum, std::string> PreProcess(const std::string& source); std::unordered_map<GLenum, std::string> PreProcess(const std::string& source);
void Compile(std::unordered_map<GLenum, std::string>& shaderSource); 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: private:
uint32_t m_RendererID; uint32_t m_RendererID;
std::string m_FilePath;
std::string m_Name; 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;
}; };
} }

View 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);
}
}

View 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/shaderc vendored Submodule

Submodule Hazel/vendor/shaderc added at a5a8caa195

View File

@ -17,7 +17,9 @@ set(PROJECT_NAME "${PROJECT_NAME}-Editor")
project(${PROJECT_NAME}) project(${PROJECT_NAME})
file(GLOB_RECURSE SOURCES file(GLOB_RECURSE SOURCES
src/SandboxApp.cpp src/SandboxApp.cpp
src/Editor/**.cpp) src/Editor/**.cpp
src/logo/logo.rc
)
add_executable(${PROJECT_NAME} ${SOURCES}) add_executable(${PROJECT_NAME} ${SOURCES})

View File

@ -6,12 +6,13 @@
layout(location = 0) in vec3 a_Position; layout(location = 0) in vec3 a_Position;
layout(location = 1) in vec2 a_TexCoord; layout(location = 1) in vec2 a_TexCoord;
uniform mat4 u_ViewProjection; layout(std140, binding = 0) uniform Camera
uniform mat4 u_Transform; {
mat4 u_ViewProjection;
};
void main() { void main() {
gl_Position = u_ViewProjection * u_Transform * vec4(a_Position, 1.0f); gl_Position = u_ViewProjection * vec4(a_Position, 1.0f);
} }
#type fragment #type fragment
@ -19,8 +20,7 @@ void main() {
layout(location = 0) out vec4 color; layout(location = 0) out vec4 color;
uniform vec4 u_Color;
void main() { void main() {
color = u_Color; color = vec4(1.0f, 0.0f, 0.0f, 1.0f);
} }

View File

@ -1,5 +1,7 @@
// Basic Texture Shader
#type vertex #type vertex
#version 460 core #version 450 core
layout(location = 0) in vec3 a_Position; layout(location = 0) in vec3 a_Position;
layout(location = 1) in vec4 a_Color; 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 = 4) in float a_TilingFactor;
layout(location = 5) in int a_EntityID; layout(location = 5) in int a_EntityID;
uniform mat4 u_ViewProjection; layout(std140, binding = 0) uniform Camera
//uniform mat4 u_Transform; {
mat4 u_ViewProjection;
};
out vec2 v_TexCoord; struct VertexOutput
out vec4 v_Color; {
out flat float v_TexIndex; vec4 Color;
out float v_TilingFactor; vec2 TexCoord;
out flat int v_EntityID; float TilingFactor;
};
void main() { layout (location = 0) out VertexOutput Output;
v_TexCoord = a_TexCoord; layout (location = 3) out flat float v_TexIndex;
v_Color = a_Color; 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_TexIndex = a_TexIndex;
v_TilingFactor = a_TilingFactor;
v_EntityID = a_EntityID; v_EntityID = a_EntityID;
gl_Position = u_ViewProjection * vec4(a_Position, 1.0f); gl_Position = u_ViewProjection * vec4(a_Position, 1.0);
} }
#type fragment #type fragment
#version 460 core #version 450 core
layout(location = 0) out vec4 color; layout(location = 0) out vec4 o_Color;
layout(location = 1) out int color2; layout(location = 1) out int o_EntityID;
in vec2 v_TexCoord; struct VertexOutput
in vec4 v_Color; {
in flat float v_TexIndex; vec4 Color;
in float v_TilingFactor; vec2 TexCoord;
in flat int v_EntityID; float TilingFactor;
};
uniform vec4 u_Color; layout (location = 0) in VertexOutput Input;
uniform sampler2D u_Textures[32]; 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; void main()
// color = v_Color; {
color2 = v_EntityID; o_Color = texture(u_Textures[int(v_TexIndex)], Input.TexCoord * Input.TilingFactor) * Input.Color;
o_EntityID = v_EntityID;
} }

View 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;
}

View File

@ -63,7 +63,7 @@ namespace Hazel
} }
// update camera // update camera
if (m_ViewportFocused && m_ViewportHovered) if (m_ViewportFocused)
{ {
m_CameraController.OnUpdate(ts); m_CameraController.OnUpdate(ts);
m_EditorCamera.OnUpdate(ts); m_EditorCamera.OnUpdate(ts);
@ -284,10 +284,9 @@ namespace Hazel
snapValue = 0.25f; snapValue = 0.25f;
float snapValues[3] = {snapValue, snapValue, snapValue}; float snapValues[3] = {snapValue, snapValue, snapValue};
if (ImGuizmo::Manipulate(glm::value_ptr(cameraView), glm::value_ptr(cameraProjection), if (ImGuizmo::Manipulate(glm::value_ptr(cameraView), glm::value_ptr(cameraProjection),
ImGuizmo::OPERATION(m_GizmoType), ImGuizmo::LOCAL, 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()) if (ImGuizmo::IsUsing())
{ {
@ -352,11 +351,13 @@ namespace Hazel
void EditorLayer::OnEvent(SDL_Event& e) void EditorLayer::OnEvent(SDL_Event& e)
{ {
if (m_ViewportFocused && m_ViewportHovered) if (m_ViewportFocused)
{ {
m_CameraController.OnEvent(e); m_CameraController.OnEvent(e);
m_EditorCamera.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_NEW (SDL_KMOD_CTRL | SDLK_N)
#define SHORTCUT_OPEN (SDL_KMOD_CTRL | SDLK_O) #define SHORTCUT_OPEN (SDL_KMOD_CTRL | SDLK_O)

View File

@ -338,4 +338,9 @@ namespace Hazel
ImGui::ColorEdit4("Color", glm::value_ptr(component.Color)); ImGui::ColorEdit4("Color", glm::value_ptr(component.Color));
}); });
} }
void SceneHierachyPanel::SetSelectedEntity(const Entity entity)
{
m_SelectionContext = entity;
}
} }

View File

@ -20,6 +20,7 @@ namespace Hazel
void OnImGuiRender(); void OnImGuiRender();
void DrawComponents(Entity entity); void DrawComponents(Entity entity);
void SetSelectedEntity(const Entity entity);
Entity GetSelectedEntity() const { return m_SelectionContext; } Entity GetSelectedEntity() const { return m_SelectionContext; }
private: private: