content browser and textures on entity sprites
This commit is contained in:
@@ -10,10 +10,25 @@
|
||||
int main(int argc, char **argv);
|
||||
|
||||
namespace OpenEngine {
|
||||
|
||||
struct ApplicationCommandLineArgs
|
||||
{
|
||||
int count = 0;
|
||||
char** args = nullptr;
|
||||
|
||||
const char* operator[](int index)
|
||||
{
|
||||
OE_CORE_ASSERT(index < count, "Index is higher than argument count.");
|
||||
|
||||
return args[index];
|
||||
};
|
||||
};
|
||||
|
||||
class Application
|
||||
{
|
||||
public:
|
||||
Application(const std::string& name = "OpenEngine Project");
|
||||
Application(const std::string& name,
|
||||
ApplicationCommandLineArgs& args);
|
||||
~Application();
|
||||
|
||||
virtual void OnEvent(Event& event);
|
||||
@@ -25,6 +40,7 @@ namespace OpenEngine {
|
||||
ImGuiLayer* GetImGuiLayer() { return imgui_layer.get(); };
|
||||
|
||||
inline static Application& Get() { return *instance; };
|
||||
ApplicationCommandLineArgs GetCommandLineArgs() const { return arguments; };
|
||||
|
||||
inline Window& GetWindow() { return *window; };
|
||||
|
||||
@@ -36,6 +52,7 @@ namespace OpenEngine {
|
||||
bool OnWindowResize(WindowResizeEvent& event);
|
||||
|
||||
private:
|
||||
ApplicationCommandLineArgs arguments;
|
||||
const std::string name;
|
||||
std::unique_ptr<Window> window;
|
||||
|
||||
@@ -49,7 +66,7 @@ namespace OpenEngine {
|
||||
};
|
||||
|
||||
// Is defined by client
|
||||
Application* CreateApplication();
|
||||
Application* CreateApplication(ApplicationCommandLineArgs args);
|
||||
}
|
||||
|
||||
#endif // APPLICATION_HPP
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
#ifndef ENTRY_POINT_HPP
|
||||
#define ENTRY_POINT_HPP
|
||||
|
||||
#include "open_engine/core.hpp"
|
||||
#include "open_engine/application.hpp"
|
||||
#include "open_engine/logging.hpp"
|
||||
|
||||
extern OpenEngine::Application* OpenEngine::CreateApplication();
|
||||
extern OpenEngine::Application* OpenEngine::CreateApplication(OpenEngine::ApplicationCommandLineArgs args);
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
OE_PROFILE_BEGIN_SESSION("Startup", "open_engine-startup.json");
|
||||
OpenEngine::Logger::Init();
|
||||
auto app = OpenEngine::CreateApplication();
|
||||
auto app = OpenEngine::CreateApplication({ argc, argv });
|
||||
OE_PROFILE_END_SESSION();
|
||||
|
||||
OE_PROFILE_BEGIN_SESSION("Runtime", "open_engine-runtime.json");
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace OpenEngine {
|
||||
public:
|
||||
OpenGLShader(const std::string& shader_path);
|
||||
OpenGLShader(const std::string& name, const std::string& vertex_src, const std::string& frament_src);
|
||||
virtual ~OpenGLShader() = default;
|
||||
virtual ~OpenGLShader();
|
||||
|
||||
virtual const std::string& GetName() const override { return name; };
|
||||
|
||||
@@ -44,11 +44,21 @@ namespace OpenEngine {
|
||||
private:
|
||||
std::string ReadFile(const std::string& shader_path);
|
||||
std::unordered_map<GLenum, std::string> PreProcess(const std::string& shader_source);
|
||||
void Compile(const std::unordered_map<GLenum, std::string> sources);
|
||||
|
||||
void CheckCompileErrors(unsigned int shader, const std::string& type);
|
||||
void CompileOrGetVulkanBinaries(const std::unordered_map<GLenum, std::string>& shader_sources);
|
||||
void CompileOrGetOpenGLBinaries();
|
||||
void CreateProgram();
|
||||
void Reflect(GLenum stage, const std::vector<uint32_t>& shader_data);
|
||||
//void CheckCompileErrors(unsigned int shader, const std::string& type);
|
||||
|
||||
private:
|
||||
std::string name;
|
||||
std::string file_path;
|
||||
|
||||
std::unordered_map<GLenum, std::vector<uint32_t>> vulkan_spirv;
|
||||
std::unordered_map<GLenum, std::vector<uint32_t>> opengl_spirv;
|
||||
|
||||
std::unordered_map<GLenum, std::string> m_OpenGLSourceCode;
|
||||
|
||||
u_int32_t id;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
#ifndef OPENGL_UNIFORM_BUFFER_HPP
|
||||
#define OPENGL_UNIFORM_BUFFER_HPP
|
||||
|
||||
#include "open_engine/renderer/uniform_buffer.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
namespace OpenEngine {
|
||||
|
||||
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 id = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // OPENGL_UNIFORM_BUFFER_HPP
|
||||
@@ -44,6 +44,9 @@ namespace OpenEngine {
|
||||
static void DrawQuad(const Transform& transform_data,
|
||||
const Ref<Texture2D>& texture, int entity_id,
|
||||
float tiling_factor = 1.0f);
|
||||
static void DrawQuad(const Transform& transform_data,
|
||||
const Ref<Texture2D>& texture, const glm::vec4& color,
|
||||
int entity_id, float tiling_factor = 1.0f);
|
||||
static void DrawQuad(const Transform& transform_data,
|
||||
const Ref<Subtexture2D>& subtexture, int entity_id,
|
||||
float tiling_factor = 1.0f);
|
||||
@@ -53,6 +56,9 @@ namespace OpenEngine {
|
||||
static void DrawQuad(const glm::mat4& transform,
|
||||
const Ref<Texture2D>& texture, int entity_id,
|
||||
float tiling_factor = 1.0f);
|
||||
static void DrawQuad(const glm::mat4& transform,
|
||||
const Ref<Texture2D>& texture, const glm::vec4& color,
|
||||
int entity_id, float tiling_factor = 1.0f);
|
||||
static void DrawQuad(const glm::mat4& transform,
|
||||
const Ref<Subtexture2D>& subtexture, int entity_id,
|
||||
float tiling_factor = 1.0f);
|
||||
|
||||
21
open_engine/include/open_engine/renderer/uniform_buffer.cpp
Normal file
21
open_engine/include/open_engine/renderer/uniform_buffer.cpp
Normal file
@@ -0,0 +1,21 @@
|
||||
#include <pch.hpp>
|
||||
|
||||
#include <renderer/uniform_buffer.hpp>
|
||||
#include <opengl/opengl_uniform_buffer.hpp>
|
||||
#include <renderer/renderer.hpp>
|
||||
|
||||
namespace OpenEngine {
|
||||
|
||||
Ref<UniformBuffer> UniformBuffer::Create(uint32_t size, uint32_t binding)
|
||||
{
|
||||
switch (Renderer::GetAPI())
|
||||
{
|
||||
case RendererAPI::API::None: OE_CORE_ASSERT(false, "RendererAPI::None is currently not supported!"); return nullptr;
|
||||
case RendererAPI::API::OpenGL: return CreateRef<OpenGLUniformBuffer>(size, binding);
|
||||
}
|
||||
|
||||
OE_CORE_ASSERT(false, "Unknown RendererAPI!");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
20
open_engine/include/open_engine/renderer/uniform_buffer.hpp
Normal file
20
open_engine/include/open_engine/renderer/uniform_buffer.hpp
Normal file
@@ -0,0 +1,20 @@
|
||||
#ifndef UNIFORM_BUFFER_HPP
|
||||
#define UNIFORM_BUFFER_HPP
|
||||
|
||||
#include <cstdint>
|
||||
#include <glm/fwd.hpp>
|
||||
namespace OpenEngine {
|
||||
|
||||
class 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 // UNIFORM_BUFFER_HPP
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "open_engine/scene/native_scriptable_entity.hpp"
|
||||
#include "open_engine/scene/scene_camera.hpp"
|
||||
#include "open_engine/renderer/texture.hpp"
|
||||
|
||||
#include <glm/ext/matrix_transform.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
@@ -45,6 +46,8 @@ namespace OpenEngine {
|
||||
struct SpriteRendererComponent
|
||||
{
|
||||
glm::vec4 color{ 1.0f, 1.0f, 1.0f, 1.0f };
|
||||
Ref<Texture2D> texture;
|
||||
float tiling_factor = 1.0f;
|
||||
|
||||
SpriteRendererComponent() = default;
|
||||
SpriteRendererComponent(const SpriteRendererComponent&) = default;
|
||||
|
||||
@@ -22,7 +22,10 @@ namespace OpenEngine {
|
||||
T& AddComponents(Args&&... args)
|
||||
{
|
||||
OE_ASSERT(!HasComponent<T>(), "Entity already has component.");
|
||||
return scene->registry.emplace<T>(handle, std::forward<Args>(args)...);
|
||||
|
||||
T& component = scene->registry.emplace<T>(handle, std::forward<Args>(args)...);
|
||||
scene->OnComponentAdded(*this, component);
|
||||
return component;
|
||||
};
|
||||
|
||||
template<typename T, typename ... Args>
|
||||
|
||||
@@ -27,6 +27,10 @@ namespace OpenEngine {
|
||||
|
||||
Entity GetPrimaryCamera();
|
||||
|
||||
private:
|
||||
template<typename T>
|
||||
void OnComponentAdded(Entity entity, T& component);
|
||||
|
||||
private:
|
||||
entt::registry registry;
|
||||
|
||||
|
||||
@@ -13,8 +13,9 @@
|
||||
#include <imgui.h>
|
||||
|
||||
namespace OpenEngine {
|
||||
Application::Application(const std::string& name)
|
||||
: name(name)
|
||||
Application::Application(const std::string& name,
|
||||
ApplicationCommandLineArgs& args)
|
||||
: name(name), arguments(args)
|
||||
{
|
||||
OE_PROFILE_FUNCTION();
|
||||
|
||||
|
||||
@@ -1,28 +1,117 @@
|
||||
#include <pch.hpp>
|
||||
|
||||
#include <opengl/opengl_shader.hpp>
|
||||
|
||||
#include <core.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
#include <opengl/opengl_shader.hpp>
|
||||
#include <instrumentor.hpp>
|
||||
#include <core/time.hpp>
|
||||
#include <logging.hpp>
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include <shaderc/shaderc.hpp>
|
||||
#include <spirv_cross/spirv_cross.hpp>
|
||||
#include <spirv_cross/spirv_glsl.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
#include <glm/glm.hpp>
|
||||
#include <filesystem>
|
||||
#include <glad/glad.h>
|
||||
#include <alloca.h>
|
||||
#include <cstddef>
|
||||
#include <fstream>
|
||||
//#include <alloca.h>
|
||||
|
||||
namespace OpenEngine {
|
||||
static GLenum ShaderTypeFromString(const std::string& type)
|
||||
|
||||
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;
|
||||
|
||||
OE_CORE_ASSERT(false, "Unknown shader type!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
OE_CORE_ASSERT(false, "No");
|
||||
return (shaderc_shader_kind)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";
|
||||
}
|
||||
OE_CORE_ASSERT(false, "No");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static const char* GetCacheDirectory()
|
||||
{
|
||||
// TODO: make sure the assets directory is valid
|
||||
return "assets/cache/shader/opengl";
|
||||
}
|
||||
|
||||
static void CreateCacheDirectoryIfNeeded()
|
||||
{
|
||||
std::string cache_directory = GetCacheDirectory();
|
||||
if (!std::filesystem::exists(cache_directory))
|
||||
std::filesystem::create_directories(cache_directory);
|
||||
}
|
||||
|
||||
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";
|
||||
}
|
||||
OE_CORE_ASSERT(false, "No");
|
||||
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";
|
||||
}
|
||||
OE_CORE_ASSERT(false, "No");
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
OpenGLShader::OpenGLShader(const std::string& filepath)
|
||||
: file_path(filepath)
|
||||
{
|
||||
if (type == "vertex")
|
||||
return GL_VERTEX_SHADER;
|
||||
if (type == "fragment" || type == "pixel")
|
||||
return GL_FRAGMENT_SHADER;
|
||||
OE_PROFILE_FUNCTION();
|
||||
|
||||
OE_CORE_ERROR("Could not compile shader! Unkown shader type: {}", type);
|
||||
Utils::CreateCacheDirectoryIfNeeded();
|
||||
|
||||
return 0;
|
||||
std::string source = ReadFile(filepath);
|
||||
auto shader_sources = PreProcess(source);
|
||||
|
||||
{
|
||||
CompileOrGetVulkanBinaries(shader_sources);
|
||||
CompileOrGetOpenGLBinaries();
|
||||
CreateProgram();
|
||||
}
|
||||
|
||||
// Extract name from filepath
|
||||
auto last_slash = filepath.find_last_of("/\\");
|
||||
last_slash = last_slash == std::string::npos ? 0 : last_slash + 1;
|
||||
auto lastDot = filepath.rfind('.');
|
||||
auto count = lastDot == std::string::npos ? filepath.size() - last_slash : lastDot - last_slash;
|
||||
name = filepath.substr(last_slash, count);
|
||||
}
|
||||
|
||||
OpenGLShader::OpenGLShader(const std::string& name, const std::string& vertex_src, const std::string& fragment_src)
|
||||
@@ -34,163 +123,263 @@ namespace OpenEngine {
|
||||
sources[GL_VERTEX_SHADER] = vertex_src;
|
||||
sources[GL_FRAGMENT_SHADER] = fragment_src;
|
||||
|
||||
Compile(sources);
|
||||
CompileOrGetVulkanBinaries(sources);
|
||||
CompileOrGetOpenGLBinaries();
|
||||
CreateProgram();
|
||||
}
|
||||
|
||||
OpenGLShader::OpenGLShader(const std::string& shader_path)
|
||||
OpenGLShader::~OpenGLShader()
|
||||
{
|
||||
OE_PROFILE_FUNCTION();
|
||||
|
||||
{
|
||||
OE_PROFILE_SCOPE("Compiling Shader");
|
||||
std::string source = ReadFile(shader_path);
|
||||
auto shader_sources = PreProcess(source);
|
||||
Compile(shader_sources);
|
||||
}
|
||||
|
||||
// Getting file name
|
||||
auto last_slash = shader_path.find_last_of("/\\");
|
||||
last_slash = last_slash == std::string::npos ? 0 : last_slash + 1;
|
||||
auto last_dot = shader_path.rfind('.');
|
||||
|
||||
auto count = last_dot == std::string::npos ? shader_path.size() - last_slash : last_dot - last_slash;
|
||||
name = shader_path.substr(last_slash, count);
|
||||
glDeleteProgram(id);
|
||||
}
|
||||
|
||||
void OpenGLShader::Compile(const std::unordered_map<GLenum, std::string> sources)
|
||||
{
|
||||
OE_PROFILE_FUNCTION();
|
||||
|
||||
GLuint program = glCreateProgram();
|
||||
GLenum *gl_shader_ids = (GLenum*)alloca(sources.size());
|
||||
|
||||
size_t shader_index = 0;
|
||||
for (auto& kv_pair : sources)
|
||||
{
|
||||
GLenum type = kv_pair.first;
|
||||
const std::string& source = kv_pair.second;
|
||||
|
||||
GLuint shader = glCreateShader(type);
|
||||
|
||||
const GLchar* source_cstr = source.c_str();
|
||||
glShaderSource(shader, 1, &source_cstr, 0);
|
||||
|
||||
glCompileShader(shader);
|
||||
|
||||
GLint is_compiled = 0;
|
||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &is_compiled);
|
||||
if (is_compiled == GL_FALSE)
|
||||
{
|
||||
GLint max_length = 0;
|
||||
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &max_length);
|
||||
|
||||
std::vector<GLchar> info_log(max_length);
|
||||
glGetShaderInfoLog(shader, max_length, &max_length, &info_log[0]);
|
||||
|
||||
glDeleteShader(shader);
|
||||
|
||||
OE_CORE_ERROR("{0}", info_log.data());
|
||||
OE_CORE_ERROR("Shader compilation failure!");
|
||||
break;
|
||||
}
|
||||
|
||||
glAttachShader(program, shader);
|
||||
gl_shader_ids[shader_index++] = shader;
|
||||
}
|
||||
|
||||
id = program;
|
||||
|
||||
glLinkProgram(program);
|
||||
|
||||
GLint is_linked = 0;
|
||||
glGetProgramiv(program, GL_LINK_STATUS, (int*)&is_linked);
|
||||
if (is_linked == GL_FALSE)
|
||||
{
|
||||
GLint max_length = 0;
|
||||
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &max_length);
|
||||
|
||||
// The maxLength includes the NULL character
|
||||
std::vector<GLchar> infoLog(max_length);
|
||||
glGetProgramInfoLog(program, max_length, &max_length, &infoLog[0]);
|
||||
|
||||
// We don't need the program anymore.
|
||||
glDeleteProgram(program);
|
||||
|
||||
for (int i = 0; i < sources.size(); i++)
|
||||
glDeleteShader(gl_shader_ids[i]);
|
||||
|
||||
OE_CORE_ERROR("{0}", infoLog.data());
|
||||
OE_CORE_ERROR("Shader link failure!");
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < sources.size(); i++) {
|
||||
glDetachShader(program, gl_shader_ids[i]);
|
||||
glDeleteShader(gl_shader_ids[i]);
|
||||
}
|
||||
}
|
||||
|
||||
std::unordered_map<GLenum, std::string> OpenGLShader::PreProcess(const std::string& shader_source)
|
||||
{
|
||||
OE_PROFILE_FUNCTION();
|
||||
|
||||
// TODO: Perhaps consider using getline to get the position of errors. or even regexes
|
||||
std::unordered_map<GLenum, std::string> sources;
|
||||
const char* type_token = "#type";
|
||||
|
||||
size_t type_token_lenght = strlen(type_token);
|
||||
size_t pos = shader_source.find(type_token, 0);
|
||||
while (pos != std::string::npos) {
|
||||
size_t eol = shader_source.find("\n", pos);
|
||||
if (eol == std::string::npos)
|
||||
OE_CORE_ERROR("Syntax error.");
|
||||
size_t begin = pos + type_token_lenght + 1;
|
||||
std::string type = shader_source.substr(begin, eol - begin);
|
||||
if (type != "vertex" && type != "fragment" && type != "pixel")
|
||||
OE_CORE_ERROR("Invalid shader type.");
|
||||
|
||||
size_t next_line_pos = shader_source.find_first_not_of("\n", eol);
|
||||
pos = shader_source.find(type_token, next_line_pos);
|
||||
sources[ShaderTypeFromString(type)] =
|
||||
shader_source.substr(next_line_pos, pos - (next_line_pos == std::string::npos ? shader_source.size() - 1 : next_line_pos));
|
||||
}
|
||||
|
||||
return sources;
|
||||
}
|
||||
|
||||
std::string OpenGLShader::ReadFile(const std::string& shader_path)
|
||||
std::string OpenGLShader::ReadFile(const std::string& filepath)
|
||||
{
|
||||
OE_PROFILE_FUNCTION();
|
||||
|
||||
std::string result;
|
||||
|
||||
std::ifstream input(shader_path);
|
||||
if (input) {
|
||||
input.seekg(0, std::ios::end);
|
||||
|
||||
size_t size = input.tellg();
|
||||
if (size != -1) {
|
||||
std::ifstream in(filepath, std::ios::in | std::ios::binary); // ifstream closes itself due to RAII
|
||||
if (in)
|
||||
{
|
||||
in.seekg(0, std::ios::end);
|
||||
size_t size = in.tellg();
|
||||
if (size != -1)
|
||||
{
|
||||
result.resize(size);
|
||||
input.seekg(0, std::ios::beg);
|
||||
input.read(&result[0], result.size());
|
||||
input.close();
|
||||
} else {
|
||||
OE_CORE_ERROR("Could not read from file {}", shader_path);
|
||||
in.seekg(0, std::ios::beg);
|
||||
in.read(&result[0], size);
|
||||
}
|
||||
} else {
|
||||
OE_CORE_ERROR("Shader file could not be open or does not exist: {}", shader_path);
|
||||
else
|
||||
{
|
||||
OE_CORE_ERROR("Could not read from file '{0}'", filepath);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
OE_CORE_ERROR("Could not open file '{0}'", filepath);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::unordered_map<GLenum, std::string> OpenGLShader::PreProcess(const std::string& source)
|
||||
{
|
||||
OE_PROFILE_FUNCTION();
|
||||
|
||||
std::unordered_map<GLenum, std::string> shader_sources;
|
||||
|
||||
const char* type_token = "#type";
|
||||
size_t type_token_length = strlen(type_token);
|
||||
size_t pos = source.find(type_token, 0); //Start of shader type declaration line
|
||||
while (pos != std::string::npos)
|
||||
{
|
||||
size_t eol = source.find_first_of("\r\n", pos); //End of shader type declaration line
|
||||
OE_CORE_ASSERT(eol != std::string::npos, "Syntax error");
|
||||
size_t begin = pos + type_token_length + 1; //Start of shader type name (after "#type " keyword)
|
||||
std::string type = source.substr(begin, eol - begin);
|
||||
OE_CORE_ASSERT(Utils::ShaderTypeFromString(type), "Invalid shader type specified");
|
||||
|
||||
size_t next_line_pos = source.find_first_not_of("\r\n", eol); //Start of shader code after shader type declaration line
|
||||
OE_CORE_ASSERT(next_line_pos != std::string::npos, "Syntax error");
|
||||
pos = source.find(type_token, next_line_pos); //Start of next shader type declaration line
|
||||
|
||||
shader_sources[Utils::ShaderTypeFromString(type)] = (pos == std::string::npos) ? source.substr(next_line_pos) : source.substr(next_line_pos, pos - next_line_pos);
|
||||
}
|
||||
|
||||
return shader_sources;
|
||||
}
|
||||
|
||||
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 cache_directory = Utils::GetCacheDirectory();
|
||||
|
||||
auto& shader_data = vulkan_spirv;
|
||||
shader_data.clear();
|
||||
for (auto&& [stage, source] : shaderSources)
|
||||
{
|
||||
std::filesystem::path shader_file_path = file_path;
|
||||
std::filesystem::path cached_path = cache_directory / (shader_file_path.filename().string() + Utils::GLShaderStageCachedVulkanFileExtension(stage));
|
||||
|
||||
std::ifstream in(cached_path, 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 = shader_data[stage];
|
||||
data.resize(size / sizeof(uint32_t));
|
||||
in.read((char*)data.data(), size);
|
||||
}
|
||||
else
|
||||
{
|
||||
shaderc::SpvCompilationResult module = compiler.CompileGlslToSpv(source, Utils::GLShaderStageToShaderC(stage), file_path.c_str(), options);
|
||||
if (module.GetCompilationStatus() != shaderc_compilation_status_success)
|
||||
{
|
||||
OE_CORE_ERROR(module.GetErrorMessage());
|
||||
OE_CORE_ASSERT(false, "No");
|
||||
}
|
||||
|
||||
shader_data[stage] = std::vector<uint32_t>(module.cbegin(), module.cend());
|
||||
|
||||
std::ofstream out(cached_path, std::ios::out | std::ios::binary);
|
||||
if (out.is_open())
|
||||
{
|
||||
auto& data = shader_data[stage];
|
||||
out.write((char*)data.data(), data.size() * sizeof(uint32_t));
|
||||
out.flush();
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (auto&& [stage, data]: shader_data)
|
||||
Reflect(stage, data);
|
||||
}
|
||||
|
||||
void OpenGLShader::CompileOrGetOpenGLBinaries()
|
||||
{
|
||||
auto& shader_data = opengl_spirv;
|
||||
|
||||
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 cache_directory = Utils::GetCacheDirectory();
|
||||
|
||||
shader_data.clear();
|
||||
m_OpenGLSourceCode.clear();
|
||||
for (auto&& [stage, spirv] : vulkan_spirv)
|
||||
{
|
||||
std::filesystem::path shader_file_path = file_path;
|
||||
std::filesystem::path cached_path = cache_directory / (shader_file_path.filename().string() + Utils::GLShaderStageCachedOpenGLFileExtension(stage));
|
||||
|
||||
std::ifstream in(cached_path, 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 = shader_data[stage];
|
||||
data.resize(size / sizeof(uint32_t));
|
||||
in.read((char*)data.data(), size);
|
||||
}
|
||||
else
|
||||
{
|
||||
spirv_cross::CompilerGLSL glsl_compiler(spirv);
|
||||
m_OpenGLSourceCode[stage] = glsl_compiler.compile();
|
||||
auto& source = m_OpenGLSourceCode[stage];
|
||||
|
||||
shaderc::SpvCompilationResult module = compiler.CompileGlslToSpv(source, Utils::GLShaderStageToShaderC(stage), file_path.c_str());
|
||||
if (module.GetCompilationStatus() != shaderc_compilation_status_success)
|
||||
{
|
||||
OE_CORE_ERROR(module.GetErrorMessage());
|
||||
OE_CORE_ASSERT(false, "No");
|
||||
}
|
||||
|
||||
shader_data[stage] = std::vector<uint32_t>(module.cbegin(), module.cend());
|
||||
|
||||
std::ofstream out(cached_path, std::ios::out | std::ios::binary);
|
||||
if (out.is_open())
|
||||
{
|
||||
auto& data = shader_data[stage];
|
||||
out.write((char*)data.data(), data.size() * sizeof(uint32_t));
|
||||
out.flush();
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OpenGLShader::CreateProgram()
|
||||
{
|
||||
GLuint program = glCreateProgram();
|
||||
|
||||
std::vector<GLuint> shader_ids;
|
||||
for (auto&& [stage, spirv] : opengl_spirv)
|
||||
{
|
||||
GLuint shaderID = shader_ids.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 is_linked;
|
||||
glGetProgramiv(program, GL_LINK_STATUS, &is_linked);
|
||||
if (is_linked == GL_FALSE)
|
||||
{
|
||||
GLint max_length;
|
||||
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &max_length);
|
||||
|
||||
std::vector<GLchar> info_log(max_length);
|
||||
glGetProgramInfoLog(program, max_length, &max_length, info_log.data());
|
||||
OE_CORE_ERROR("Shader linking failed ({0}):\n{1}", file_path, info_log.data());
|
||||
|
||||
glDeleteProgram(program);
|
||||
|
||||
for (auto id : shader_ids)
|
||||
glDeleteShader(id);
|
||||
}
|
||||
|
||||
for (auto id : shader_ids)
|
||||
{
|
||||
glDetachShader(program, id);
|
||||
glDeleteShader(id);
|
||||
}
|
||||
|
||||
id = program;
|
||||
}
|
||||
|
||||
void OpenGLShader::Reflect(GLenum stage, const std::vector<uint32_t>& shader_data)
|
||||
{
|
||||
spirv_cross::Compiler compiler(shader_data);
|
||||
spirv_cross::ShaderResources resources = compiler.get_shader_resources();
|
||||
|
||||
OE_CORE_TRACE("OpenGLShader::Reflect - {0} {1}", Utils::GLShaderStageToString(stage), file_path);
|
||||
OE_CORE_TRACE(" {0} uniform buffers", resources.uniform_buffers.size());
|
||||
OE_CORE_TRACE(" {0} resources", resources.sampled_images.size());
|
||||
|
||||
OE_CORE_TRACE("Uniform buffers:");
|
||||
for (const auto& resource : resources.uniform_buffers)
|
||||
{
|
||||
const auto& buffer_type = compiler.get_type(resource.base_type_id);
|
||||
uint32_t buffer_size = compiler.get_declared_struct_size(buffer_type);
|
||||
uint32_t binding = compiler.get_decoration(resource.id, spv::DecorationBinding);
|
||||
int member_count = buffer_type.member_types.size();
|
||||
|
||||
OE_CORE_TRACE(" {0}", resource.name);
|
||||
OE_CORE_TRACE(" Size = {0}", buffer_size);
|
||||
OE_CORE_TRACE(" Binding = {0}", binding);
|
||||
OE_CORE_TRACE(" Members = {0}", member_count);
|
||||
}
|
||||
}
|
||||
|
||||
void OpenGLShader::Bind() const
|
||||
{
|
||||
OE_PROFILE_FUNCTION();
|
||||
glUseProgram(id);
|
||||
}
|
||||
|
||||
void OpenGLShader::Unbind() const
|
||||
{
|
||||
OE_PROFILE_FUNCTION();
|
||||
glUseProgram(0);
|
||||
}
|
||||
|
||||
@@ -275,30 +464,4 @@ namespace OpenEngine {
|
||||
{
|
||||
glUniform4fv(glGetUniformLocation(id, name.c_str()), 1, glm::value_ptr(value));
|
||||
}
|
||||
|
||||
void OpenGLShader::CheckCompileErrors(unsigned int shader, const std::string& type)
|
||||
{
|
||||
int success = GL_FALSE;
|
||||
char infoLog[1024];
|
||||
if (type != "PROGRAM") {
|
||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
|
||||
if (success == GL_FALSE) {
|
||||
glGetShaderInfoLog(shader, 1024, NULL, infoLog);
|
||||
OE_CORE_ERROR("Shader of type {}, couldn't be compiled:", type);
|
||||
OE_CORE_ERROR("\t{}", infoLog);
|
||||
}
|
||||
} else {
|
||||
if (glGetProgramiv == nullptr) {
|
||||
OE_CORE_ERROR("OpenGL functions are not loaded!");
|
||||
return;
|
||||
}
|
||||
glGetProgramiv(shader, GL_LINK_STATUS, &success);
|
||||
if (success == GL_FALSE)
|
||||
{
|
||||
glGetProgramInfoLog(shader, 1024, NULL, infoLog);
|
||||
OE_CORE_ERROR("Program of type {}, couldn't be compiled:", type);
|
||||
OE_CORE_ERROR("\t{}", infoLog);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
27
open_engine/src/open_engine/opengl/opengl_uniform_buffer.cpp
Normal file
27
open_engine/src/open_engine/opengl/opengl_uniform_buffer.cpp
Normal file
@@ -0,0 +1,27 @@
|
||||
#include <pch.hpp>
|
||||
|
||||
#include <opengl/opengl_uniform_buffer.hpp>
|
||||
|
||||
#include <glad/glad.h>
|
||||
|
||||
namespace OpenEngine {
|
||||
|
||||
OpenGLUniformBuffer::OpenGLUniformBuffer(uint32_t size, uint32_t binding)
|
||||
{
|
||||
glCreateBuffers(1, &id);
|
||||
glNamedBufferData(id, size, nullptr, GL_DYNAMIC_DRAW);
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER, binding, id);
|
||||
}
|
||||
|
||||
OpenGLUniformBuffer::~OpenGLUniformBuffer()
|
||||
{
|
||||
glDeleteBuffers(1, &id);
|
||||
}
|
||||
|
||||
|
||||
void OpenGLUniformBuffer::SetData(const void* data, uint32_t size, uint32_t offset)
|
||||
{
|
||||
glNamedBufferSubData(id, offset, size, data);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -63,8 +63,7 @@ namespace OpenEngine {
|
||||
|
||||
void EditorCamera::OnUpdate()
|
||||
{
|
||||
if (Input::IsKeyPressed(Key::LeftAlt))
|
||||
{
|
||||
if (Input::IsKeyPressed(Key::LeftAlt)) {
|
||||
const glm::vec2& mouse{ Input::GetMouseX(), Input::GetMouseY() };
|
||||
glm::vec2 delta = (mouse - initial_mouse_position) * 0.003f;
|
||||
initial_mouse_position = mouse;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "renderer/editor_camera.hpp"
|
||||
#include "renderer/uniform_buffer.hpp"
|
||||
#include <pch.hpp>
|
||||
|
||||
#include <renderer/render_command.hpp>
|
||||
@@ -27,7 +28,7 @@ namespace OpenEngine {
|
||||
|
||||
struct Renderer2DData
|
||||
{
|
||||
static const uint32_t max_quads = 10000;
|
||||
static const uint32_t max_quads = 20000;
|
||||
static const uint32_t max_vertices = max_quads * 4;
|
||||
static const uint32_t max_indices = max_quads * 6;
|
||||
static const uint32_t max_texture_slots = 32;
|
||||
@@ -47,6 +48,13 @@ namespace OpenEngine {
|
||||
glm::vec4 quad_vertex_positioning[4];
|
||||
|
||||
Statistics stats;
|
||||
|
||||
struct CameraData
|
||||
{
|
||||
glm::mat4 view_projection;
|
||||
};
|
||||
CameraData camera_buffer;
|
||||
Ref<UniformBuffer> camera_uniform_buffer;
|
||||
};
|
||||
|
||||
static Renderer2DData renderer_data;
|
||||
@@ -100,8 +108,6 @@ namespace OpenEngine {
|
||||
samplers[i] = i;
|
||||
|
||||
renderer_data.texture_shader = Shader::Create("assets/shaders/texture.glsl");
|
||||
renderer_data.texture_shader->Bind();
|
||||
renderer_data.texture_shader->SetIntArray("u_Texture", samplers, renderer_data.max_texture_slots);
|
||||
|
||||
renderer_data.texture_slots[0] = renderer_data.white_texture;
|
||||
|
||||
@@ -109,6 +115,8 @@ namespace OpenEngine {
|
||||
renderer_data.quad_vertex_positioning[1] = {0.5, -0.5, 0.0f, 1.0f};
|
||||
renderer_data.quad_vertex_positioning[2] = {0.5, 0.5, 0.0f, 1.0f};
|
||||
renderer_data.quad_vertex_positioning[3] = {-0.5, 0.5, 0.0f, 1.0f};
|
||||
|
||||
renderer_data.camera_uniform_buffer = UniformBuffer::Create(sizeof(Renderer2DData), 0);
|
||||
}
|
||||
|
||||
void Renderer2D::Shutdown()
|
||||
@@ -130,8 +138,8 @@ namespace OpenEngine {
|
||||
{
|
||||
OE_PROFILE_FUNCTION();
|
||||
|
||||
renderer_data.texture_shader->Bind();
|
||||
renderer_data.texture_shader->SetMat4("u_ViewProjection", camera.GetViewProjectionMatrix());
|
||||
renderer_data.camera_buffer.view_projection = camera.GetViewProjectionMatrix();
|
||||
renderer_data.camera_uniform_buffer->SetData(&renderer_data.camera_buffer, sizeof(Renderer2DData::CameraData));
|
||||
|
||||
StartBatch();
|
||||
}
|
||||
@@ -140,10 +148,8 @@ namespace OpenEngine {
|
||||
{
|
||||
OE_PROFILE_FUNCTION();
|
||||
|
||||
glm::mat4 view_projection = camera.GetProjection() * glm::inverse(transform);
|
||||
|
||||
renderer_data.texture_shader->Bind();
|
||||
renderer_data.texture_shader->SetMat4("u_ViewProjection", view_projection);
|
||||
renderer_data.camera_buffer.view_projection = camera.GetProjection() * glm::inverse(transform);
|
||||
renderer_data.camera_uniform_buffer->SetData(&renderer_data.camera_buffer, sizeof(Renderer2DData::CameraData));
|
||||
|
||||
StartBatch();
|
||||
}
|
||||
@@ -152,10 +158,8 @@ namespace OpenEngine {
|
||||
{
|
||||
OE_PROFILE_FUNCTION();
|
||||
|
||||
glm::mat4 view_projection = camera.GetViewProjection();
|
||||
|
||||
renderer_data.texture_shader->Bind();
|
||||
renderer_data.texture_shader->SetMat4("u_ViewProjection", view_projection);
|
||||
renderer_data.camera_buffer.view_projection = camera.GetViewProjection();
|
||||
renderer_data.camera_uniform_buffer->SetData(&renderer_data.camera_buffer, sizeof(Renderer2DData::CameraData));
|
||||
|
||||
StartBatch();
|
||||
}
|
||||
@@ -180,6 +184,7 @@ namespace OpenEngine {
|
||||
for (int i = 0; i < renderer_data.texture_slot_index; i++)
|
||||
renderer_data.texture_slots[i]->Bind(i);
|
||||
|
||||
renderer_data.texture_shader->Bind();
|
||||
RenderCommand::DrawIndexed(renderer_data.vertex_array, renderer_data.quad_index_count);
|
||||
|
||||
renderer_data.stats.draw_calls++;
|
||||
@@ -225,6 +230,43 @@ namespace OpenEngine {
|
||||
DrawQuad(transform, texture, entity_id);
|
||||
}
|
||||
|
||||
void Renderer2D::DrawQuad(const Transform& transform_data,
|
||||
const Ref<Texture2D>& texture, const glm::vec4& color,
|
||||
int entity_id, float tiling_factor)
|
||||
{
|
||||
OE_PROFILE_FUNCTION();
|
||||
|
||||
constexpr size_t quad_vertex_count = 4;
|
||||
constexpr glm::vec2 texture_coords[] = { { 0.0f, 0.0f }, { 1.0f, 0.0f }, { 1.0f, 1.0f }, { 0.0f, 1.0f }};
|
||||
|
||||
if (renderer_data.quad_index_count >= Renderer2DData::max_indices)
|
||||
FlushAndReset();
|
||||
|
||||
glm::vec3 position = transform_data.position;
|
||||
glm::vec3 size = transform_data.size;
|
||||
|
||||
float texture_index = 0;
|
||||
for (uint32_t i = 1; i < renderer_data.texture_slot_index; i++) {
|
||||
if (*renderer_data.texture_slots[i].get() == *texture.get()) {
|
||||
texture_index = (float)i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (texture_index == 0) {
|
||||
if (renderer_data.texture_slot_index >= Renderer2DData::max_texture_slots)
|
||||
FlushAndReset();
|
||||
|
||||
texture_index = (float)renderer_data.texture_slot_index;
|
||||
renderer_data.texture_slots[renderer_data.texture_slot_index] = texture;
|
||||
renderer_data.texture_slot_index++;
|
||||
}
|
||||
|
||||
glm::mat4 transform = glm::translate(glm::mat4(1.0f), transform_data.position)
|
||||
* glm::rotate(glm::mat4(1.0f), glm::radians(transform_data.rotation), { 0.0f, 0.0f, 1.0f })
|
||||
* glm::scale(glm::mat4(1.0f), transform_data.size);
|
||||
}
|
||||
|
||||
void Renderer2D::DrawQuad(const Transform& transform_data,
|
||||
const Ref<Subtexture2D>& subtexture, int entity_id,
|
||||
float tiling_factor)
|
||||
@@ -333,6 +375,49 @@ namespace OpenEngine {
|
||||
renderer_data.stats.quad_count++;
|
||||
}
|
||||
|
||||
void Renderer2D::DrawQuad(const glm::mat4& transform,
|
||||
const Ref<Texture2D>& texture, const glm::vec4& color,
|
||||
int entity_id, float tiling_factor)
|
||||
{
|
||||
OE_PROFILE_FUNCTION();
|
||||
|
||||
constexpr size_t quad_vertex_count = 4;
|
||||
constexpr glm::vec2 texture_coords[] = { { 0.0f, 0.0f }, { 1.0f, 0.0f }, { 1.0f, 1.0f }, { 0.0f, 1.0f }};
|
||||
|
||||
if (renderer_data.quad_index_count >= Renderer2DData::max_indices)
|
||||
FlushAndReset();
|
||||
|
||||
float texture_index = 0;
|
||||
for (uint32_t i = 1; i < renderer_data.texture_slot_index; i++) {
|
||||
if (*renderer_data.texture_slots[i].get() == *texture.get()) {
|
||||
texture_index = (float)i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (texture_index == 0) {
|
||||
if (renderer_data.texture_slot_index >= Renderer2DData::max_texture_slots)
|
||||
FlushAndReset();
|
||||
|
||||
texture_index = (float)renderer_data.texture_slot_index;
|
||||
renderer_data.texture_slots[renderer_data.texture_slot_index] = texture;
|
||||
renderer_data.texture_slot_index++;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < quad_vertex_count; i++) {
|
||||
renderer_data.quad_vertex_ptr->position = transform * renderer_data.quad_vertex_positioning[i];
|
||||
renderer_data.quad_vertex_ptr->color = color;
|
||||
renderer_data.quad_vertex_ptr->tex_coord = texture_coords[i];
|
||||
renderer_data.quad_vertex_ptr->tex_index = texture_index;
|
||||
renderer_data.quad_vertex_ptr->tiling_factor = tiling_factor;
|
||||
renderer_data.quad_vertex_ptr->id = entity_id;
|
||||
renderer_data.quad_vertex_ptr++;
|
||||
}
|
||||
|
||||
renderer_data.quad_index_count += 6;
|
||||
renderer_data.stats.quad_count++;
|
||||
}
|
||||
|
||||
void Renderer2D::DrawQuad(const glm::mat4& transform,
|
||||
const Ref<Subtexture2D>& subtexture, int entity_id,
|
||||
float tiling_factor)
|
||||
|
||||
21
open_engine/src/open_engine/renderer/uniform_buffer.cpp
Normal file
21
open_engine/src/open_engine/renderer/uniform_buffer.cpp
Normal file
@@ -0,0 +1,21 @@
|
||||
#include <pch.hpp>
|
||||
|
||||
#include <renderer/uniform_buffer.hpp>
|
||||
#include <opengl/opengl_uniform_buffer.hpp>
|
||||
#include <renderer/renderer.hpp>
|
||||
|
||||
namespace OpenEngine {
|
||||
|
||||
Ref<UniformBuffer> UniformBuffer::Create(uint32_t size, uint32_t binding)
|
||||
{
|
||||
switch (Renderer::GetAPI())
|
||||
{
|
||||
case RendererAPI::API::None: OE_CORE_ASSERT(false, "RendererAPI::None is currently not supported!"); return nullptr;
|
||||
case RendererAPI::API::OpenGL: return CreateRef<OpenGLUniformBuffer>(size, binding);
|
||||
}
|
||||
|
||||
OE_CORE_ASSERT(false, "Unknown RendererAPI!");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
#include "core.hpp"
|
||||
#include <glm/trigonometric.hpp>
|
||||
#include <pch.hpp>
|
||||
|
||||
@@ -32,6 +33,7 @@ namespace OpenEngine {
|
||||
|
||||
void SceneCamera::SetViewportSize(uint32_t width, uint32_t height)
|
||||
{
|
||||
OE_CORE_ASSERT(width > 0 && height > 0, "Viewport size invalid.");
|
||||
aspect_ratio = (float)width / (float)height;
|
||||
|
||||
RecalculateProjection();
|
||||
|
||||
@@ -76,7 +76,12 @@ namespace OpenEngine {
|
||||
{
|
||||
auto [transform, sprite] = group.get<TransformComponent, SpriteRendererComponent>(entity);
|
||||
|
||||
Renderer2D::DrawQuad(GetTransformFromComp(transform), sprite.color, (int)entity);
|
||||
if (sprite.texture)
|
||||
Renderer2D::DrawQuad(GetTransformFromComp(transform),
|
||||
sprite.texture, sprite.color, (int)entity, sprite.tiling_factor);
|
||||
else
|
||||
Renderer2D::DrawQuad(GetTransformFromComp(transform),
|
||||
sprite.color, (int)entity);
|
||||
}
|
||||
|
||||
Renderer2D::EndScene();
|
||||
@@ -107,4 +112,37 @@ namespace OpenEngine {
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void Scene::OnComponentAdded(Entity entity, T& component)
|
||||
{
|
||||
static_assert(false);
|
||||
}
|
||||
|
||||
template<>
|
||||
void Scene::OnComponentAdded<TransformComponent>(Entity entity, TransformComponent& component)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
void Scene::OnComponentAdded<CameraComponent>(Entity entity, CameraComponent& component)
|
||||
{
|
||||
if (viewport_width > 0 && viewport_height > 0)
|
||||
component.camera.SetViewportSize(viewport_width, viewport_height);
|
||||
}
|
||||
|
||||
template<>
|
||||
void Scene::OnComponentAdded<SpriteRendererComponent>(Entity entity, SpriteRendererComponent& component)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
void Scene::OnComponentAdded<TagComponent>(Entity entity, TagComponent& component)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
void Scene::OnComponentAdded<NativeScriptComponent>(Entity entity, NativeScriptComponent& component)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user