简单添加鼠标拾取功能

This commit is contained in:
2025-06-06 21:49:43 +08:00
parent 8c0eb4314c
commit de75ee9481
12 changed files with 461 additions and 116 deletions

View File

@ -38,8 +38,8 @@ namespace Hazel
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // IF using Docking Branch io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // IF using Docking Branch
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;
io.Fonts->AddFontFromFileTTF("assets/fonts/OpenSans/OpenSans-Bold.ttf", 18.0f); io.Fonts->AddFontFromFileTTF("assets/fonts/OpenSans/OpenSans-Bold.ttf", 20.0f);
io.FontDefault = io.Fonts->AddFontFromFileTTF("assets/fonts/OpenSans/OpenSans-Regular.ttf", 18.0f); io.FontDefault = io.Fonts->AddFontFromFileTTF("assets/fonts/OpenSans/OpenSans-Regular.ttf", 20.0f);
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
{ {

View File

@ -4,6 +4,7 @@
#ifndef FRAMEBUFFER_H #ifndef FRAMEBUFFER_H
#define FRAMEBUFFER_H #define FRAMEBUFFER_H
#include <vector>
#include <Hazel/Core/Core.h> #include <Hazel/Core/Core.h>
#include "glm/vec2.hpp" #include "glm/vec2.hpp"
@ -11,10 +12,47 @@
namespace Hazel namespace Hazel
{ {
enum class FrameBufferTextureFormat
{
NONE = 0,
// Color
RGBA8,
RED_INTEGER,
// Depth/stencil
DEPTH24STENCIL8,
// Defaults
DEPTH = DEPTH24STENCIL8
};
struct FrameBufferTextureSpecification
{
FrameBufferTextureSpecification() = default;
FrameBufferTextureSpecification(FrameBufferTextureFormat format)
: TextureFormat(format)
{}
FrameBufferTextureFormat TextureFormat = FrameBufferTextureFormat::NONE;
// TODO: filtering / warp
};
struct FrameBufferAttachmentSpecification
{
FrameBufferAttachmentSpecification() = default;
FrameBufferAttachmentSpecification(const std::initializer_list<FrameBufferTextureSpecification> attachments)
: Attachments(attachments)
{}
std::vector<FrameBufferTextureSpecification> Attachments;
};
struct FrameBufferSpecification struct FrameBufferSpecification
{ {
uint32_t Width, Height; uint32_t Width = 0, Height = 0;
uint32_t Samples; FrameBufferAttachmentSpecification Attachments;
uint32_t Samples = 1;
bool SwapChainTarget = false; bool SwapChainTarget = false;
}; };
@ -24,9 +62,15 @@ namespace Hazel
{ {
public: public:
virtual ~FrameBuffer() = default; virtual ~FrameBuffer() = default;
virtual uint32_t GetColorAttachmentID(uint32_t index = 0) const = 0;
virtual int ReadPixel(uint32_t attachmentIndex, int x, int y) = 0;
virtual void ClearAttachment(uint32_t index, int value) = 0;
virtual uint32_t GetColorAttachmentRendererID(uint32_t index) const = 0;
// virtual FrameBufferSpecification& GetSpecification() = 0; // virtual FrameBufferSpecification& GetSpecification() = 0;
virtual const FrameBufferSpecification& GetSpecification() const = 0; virtual const FrameBufferSpecification& GetSpecification() const = 0;
virtual uint32_t GetColorAttachmentID() const = 0;
virtual void Bind() = 0; virtual void Bind() = 0;
virtual void UnBind() = 0; virtual void UnBind() = 0;

View File

@ -24,7 +24,9 @@ namespace Hazel
glm::vec2 TexCoord; glm::vec2 TexCoord;
float TexIndex; float TexIndex;
float TilingFactor; float TilingFactor;
// TODO:
// TODO: Editor Only
int EntityID;
}; };
struct Renderer2DStorage struct Renderer2DStorage
@ -68,7 +70,8 @@ namespace Hazel
{ShaderDataType::Float4, "a_Color"}, {ShaderDataType::Float4, "a_Color"},
{ShaderDataType::Float2, "a_TexCoord"}, {ShaderDataType::Float2, "a_TexCoord"},
{ShaderDataType::Float, "a_TexIndex"}, {ShaderDataType::Float, "a_TexIndex"},
{ShaderDataType::Float, "a_TilingFactor"} {ShaderDataType::Float, "a_TilingFactor"},
{ShaderDataType::Int, "a_EntityID"}
}); });
s_Data.QuadVertexArray->AddVertexBuffer(s_Data.QuadVertexBuffer); s_Data.QuadVertexArray->AddVertexBuffer(s_Data.QuadVertexBuffer);
@ -301,7 +304,7 @@ namespace Hazel
s_Data.Stats.QuadCount ++; s_Data.Stats.QuadCount ++;
} }
void Renderer2D::DrawQuad(const glm::mat4& transform, const glm::vec4& Color) void Renderer2D::DrawQuad(const glm::mat4& transform, const glm::vec4& Color, const int entityID)
{ {
HZ_PROFILE_FUNCTION(); HZ_PROFILE_FUNCTION();
if (s_Data.QuadIndexCount >= s_Data.MaxIndices) if (s_Data.QuadIndexCount >= s_Data.MaxIndices)
@ -309,9 +312,9 @@ namespace Hazel
FlushAndReset(); FlushAndReset();
} }
glm::vec2 texCoords[] = {{0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f}}; const glm::vec2 texCoords[] = {{0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f}};
const float textureIndex = 0.0f; constexpr float textureIndex = 0.0f;
const float tilingFactor = 1.0f; constexpr float tilingFactor = 1.0f;
for (unsigned int i = 0; i < 4; i++) for (unsigned int i = 0; i < 4; i++)
{ {
@ -320,6 +323,7 @@ namespace Hazel
s_Data.QuadVertexBufferPtr->TexCoord = texCoords[i]; s_Data.QuadVertexBufferPtr->TexCoord = texCoords[i];
s_Data.QuadVertexBufferPtr->TexIndex = textureIndex; s_Data.QuadVertexBufferPtr->TexIndex = textureIndex;
s_Data.QuadVertexBufferPtr->TilingFactor = tilingFactor; s_Data.QuadVertexBufferPtr->TilingFactor = tilingFactor;
s_Data.QuadVertexBufferPtr->EntityID = entityID;
s_Data.QuadVertexBufferPtr++; s_Data.QuadVertexBufferPtr++;
} }
s_Data.QuadIndexCount += 6; s_Data.QuadIndexCount += 6;
@ -328,7 +332,7 @@ namespace Hazel
} }
void Renderer2D::DrawQuad(const glm::mat4& transform, const Ref<Texture2D>& texture, float tilingFactor, void Renderer2D::DrawQuad(const glm::mat4& transform, const Ref<Texture2D>& texture, float tilingFactor,
const glm::vec4& tintColor) const glm::vec4& tintColor, const int entityID)
{ {
HZ_PROFILE_FUNCTION(); HZ_PROFILE_FUNCTION();
if (s_Data.QuadIndexCount >= s_Data.MaxIndices) if (s_Data.QuadIndexCount >= s_Data.MaxIndices)
@ -365,6 +369,7 @@ namespace Hazel
s_Data.QuadVertexBufferPtr->TexCoord = texCoords[i]; s_Data.QuadVertexBufferPtr->TexCoord = texCoords[i];
s_Data.QuadVertexBufferPtr->TexIndex = textureIndex; s_Data.QuadVertexBufferPtr->TexIndex = textureIndex;
s_Data.QuadVertexBufferPtr->TilingFactor = tilingFactor; s_Data.QuadVertexBufferPtr->TilingFactor = tilingFactor;
s_Data.QuadVertexBufferPtr->EntityID = entityID;
s_Data.QuadVertexBufferPtr++; s_Data.QuadVertexBufferPtr++;
} }
s_Data.QuadIndexCount += 6; s_Data.QuadIndexCount += 6;
@ -378,9 +383,7 @@ namespace Hazel
{ {
DrawRotateQuad({position.x, position.y, 0.0f}, size, rotation, color); DrawRotateQuad({position.x, position.y, 0.0f}, size, rotation, color);
} }
void Renderer2D::DrawRotateQuad(const glm::vec3& position, const glm::vec2& size, const float rotation, const glm::vec4& color)
void Renderer2D::DrawRotateQuad(const glm::vec3& position, const glm::vec2& size, const float rotation,
const glm::vec4& color)
{ {
HZ_PROFILE_FUNCTION(); HZ_PROFILE_FUNCTION();
@ -512,4 +515,9 @@ namespace Hazel
s_Data.Stats.QuadCount ++; s_Data.Stats.QuadCount ++;
} }
void Renderer2D::DrawSprite(const glm::mat4& transform, SpriteRendererComponent& src, int entityID)
{
DrawQuad(transform, src.Color, entityID);
}
} }

View File

@ -5,6 +5,8 @@
#ifndef RENDERER2D_H #ifndef RENDERER2D_H
#define RENDERER2D_H #define RENDERER2D_H
#include <Hazel/Scene/Components.h>
#include "Camera.h" #include "Camera.h"
#include "EditorCamera.h" #include "EditorCamera.h"
#include "OrthographicCamera.h" #include "OrthographicCamera.h"
@ -42,8 +44,8 @@ namespace Hazel
static void DrawQuad(const glm::vec2& position, const glm::vec2& size, const Ref<SubTexture2D>& subTexture, float tilingFactor = 1.0f, const glm::vec4& tintColor = glm::vec4(1.0f)); static void DrawQuad(const glm::vec2& position, const glm::vec2& size, const Ref<SubTexture2D>& subTexture, float tilingFactor = 1.0f, const glm::vec4& tintColor = glm::vec4(1.0f));
static void DrawQuad(const glm::vec3& position, const glm::vec2& size, const Ref<SubTexture2D>& subTexture, float tilingFactor = 1.0f, const glm::vec4& tintColor = glm::vec4(1.0f)); static void DrawQuad(const glm::vec3& position, const glm::vec2& size, const Ref<SubTexture2D>& subTexture, float tilingFactor = 1.0f, const glm::vec4& tintColor = glm::vec4(1.0f));
static void DrawQuad(const glm::mat4& transform, const glm::vec4& Color); static void DrawQuad(const glm::mat4& transform, const glm::vec4& Color, const int entityID = -1);
static void DrawQuad(const glm::mat4& transform, const Ref<Texture2D>& texture, float tilingFactor = 1.0f, const glm::vec4& tintColor = glm::vec4(1.0f)); static void DrawQuad(const glm::mat4& transform, const Ref<Texture2D>& texture, float tilingFactor = 1.0f, const glm::vec4& tintColor = glm::vec4(1.0f), const int entityID = -1);
static void DrawRotateQuad(const glm::vec2& position, const glm::vec2& size, float rotation, const glm::vec4& color); static void DrawRotateQuad(const glm::vec2& position, const glm::vec2& size, float rotation, const glm::vec4& color);
static void DrawRotateQuad(const glm::vec3& position, const glm::vec2& size, float rotation, const glm::vec4& color); static void DrawRotateQuad(const glm::vec3& position, const glm::vec2& size, float rotation, const glm::vec4& color);
@ -52,6 +54,9 @@ namespace Hazel
static void DrawRotateQuad(const glm::vec2& position, const glm::vec2& size, float rotation, const Ref<SubTexture2D>& subTexture, float tilingFactor = 1.0f, const glm::vec4& tintColor = glm::vec4(1.0f)); static void DrawRotateQuad(const glm::vec2& position, const glm::vec2& size, float rotation, const Ref<SubTexture2D>& subTexture, float tilingFactor = 1.0f, const glm::vec4& tintColor = glm::vec4(1.0f));
static void DrawRotateQuad(const glm::vec3& position, const glm::vec2& size, float rotation, const Ref<SubTexture2D>& subTexture, float tilingFactor = 1.0f, const glm::vec4& tintColor = glm::vec4(1.0f)); static void DrawRotateQuad(const glm::vec3& position, const glm::vec2& size, float rotation, const Ref<SubTexture2D>& subTexture, float tilingFactor = 1.0f, const glm::vec4& tintColor = glm::vec4(1.0f));
static void DrawSprite(const glm::mat4& transform, SpriteRendererComponent& src, int entityID);
static void Shutdown(); static void Shutdown();
struct Statistic struct Statistic

View File

@ -99,7 +99,8 @@ namespace Hazel
{ {
auto [transform, sprite] = group.get<TransformComponent, SpriteRendererComponent>(entity); auto [transform, sprite] = group.get<TransformComponent, SpriteRendererComponent>(entity);
Renderer2D::DrawQuad(transform.GetTransform(), sprite.Color); // Renderer2D::DrawQuad(transform.GetTransform(), sprite.Color);
Renderer2D::DrawSprite(transform.GetTransform(), sprite, (int)entity);
} }
Renderer2D::EndScene(); Renderer2D::EndScene();

View File

@ -188,7 +188,11 @@ namespace Hazel
YAML::Node data = YAML::Load(strStream.str()); YAML::Node data = YAML::Load(strStream.str());
if (!data["Scene"]) if (!data["Scene"])
{
HZ_CORE_WARN("cannot find key: Scene");
return false; return false;
}
auto sceneName = data["Scene"].as<std::string>(); auto sceneName = data["Scene"].as<std::string>();

View File

@ -11,22 +11,127 @@ namespace Hazel
static constexpr uint32_t s_MaxFrameBufferSize = 8192; static constexpr uint32_t s_MaxFrameBufferSize = 8192;
namespace Utils
{
static GLenum TextureTarget(bool multisample)
{
return multisample ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D;
}
static void CreateTextures(const bool multisample, uint32_t* outID, const uint32_t count)
{
glCreateTextures(TextureTarget(multisample), count, outID);
}
static void BindTexture(bool multisampleID, uint32_t id)
{
glBindTexture(TextureTarget(multisampleID), id);
}
static void AtttachColorTexture(uint32_t id, const int samples, const GLenum internalFormat,const GLenum format, const uint32_t width, const uint32_t height, int index)
{
const bool multisample = samples > 1;
if (multisample)
{
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, internalFormat, width, height, GL_FALSE);
}else
{
glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, format, GL_UNSIGNED_BYTE, nullptr);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + index, TextureTarget(multisample), id, 0);
}
static void AtttachDepthTexture(uint32_t id, const int samples, const GLenum format, const GLenum attachmentType, const uint32_t width, const uint32_t height)
{
const bool multisample = samples > 1;
if (multisample)
{
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, format, width, height, GL_FALSE);
}else
{
glTexStorage2D(GL_TEXTURE_2D, 1, format, width, height);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
glFramebufferTexture2D(GL_FRAMEBUFFER, attachmentType, TextureTarget(multisample), id, 0);
}
static bool IsDepthFormat(const FrameBufferTextureFormat format)
{
switch (format)
{
case FrameBufferTextureFormat::DEPTH24STENCIL8: return true;
}
return false;
}
static GLenum TextureFormatToGL(const FrameBufferTextureFormat format)
{
switch (format)
{
case FrameBufferTextureFormat::RGBA8: return GL_RGBA8;
case FrameBufferTextureFormat::RED_INTEGER: return GL_RED_INTEGER;
}
HZ_CORE_WARN("Unknown framebuffer texture format!");
return 0;
}
static GLenum GLDataType(const FrameBufferTextureFormat format)
{
switch (format)
{
case FrameBufferTextureFormat::RGBA8: return GL_FLOAT;
case FrameBufferTextureFormat::RED_INTEGER: return GL_INT;
}
HZ_CORE_WARN("Unknown framebuffer texture format!");
return 0;
}
}
OpenGLFrameBuffer::OpenGLFrameBuffer(const FrameBufferSpecification& spec) OpenGLFrameBuffer::OpenGLFrameBuffer(const FrameBufferSpecification& spec)
: m_Specification(spec) : m_Specification(spec)
{ {
for (auto spec : m_Specification.Attachments.Attachments)
{
if (!Utils::IsDepthFormat(spec.TextureFormat))
m_ColorAttachmentsSpecifications.emplace_back(spec);
else
m_DepthAttachmentSpecification = spec;
}
Invalidata(); Invalidata();
} }
OpenGLFrameBuffer::~OpenGLFrameBuffer() OpenGLFrameBuffer::~OpenGLFrameBuffer()
{ {
glDeleteFramebuffers(1, &m_RendererID); glDeleteFramebuffers(1, &m_RendererID);
glDeleteTextures(1, &m_ColorAttachment); glDeleteTextures(m_ColorAttachmentsSpecifications.size(), m_ColorAttachments.data());
glDeleteTextures(1, &m_DepthAttachment); glDeleteTextures(1, &m_DepthAttachment);
} }
void OpenGLFrameBuffer::Bind() void OpenGLFrameBuffer::Bind()
{ {
glBindFramebuffer(GL_FRAMEBUFFER, m_RendererID); glBindFramebuffer(GL_FRAMEBUFFER, m_RendererID);
constexpr int value = -1;
glClearTexImage(m_ColorAttachments[1], 0,GL_RED_INTEGER, GL_INT, &value);
} }
void OpenGLFrameBuffer::UnBind() void OpenGLFrameBuffer::UnBind()
@ -34,6 +139,32 @@ namespace Hazel
glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0);
} }
void OpenGLFrameBuffer::ClearAttachment(const uint32_t attachmentIndex, const int value)
{
if (attachmentIndex >= m_ColorAttachments.size())
{
HZ_CORE_ERROR("Attempting to clear an invalid attachment index");
}
const auto& spec = m_ColorAttachmentsSpecifications[attachmentIndex];
glClearTexImage(m_ColorAttachments[attachmentIndex], 0,Utils::TextureFormatToGL(spec.TextureFormat), GL_INT, &value);
}
int OpenGLFrameBuffer::ReadPixel(uint32_t attachmentIndex, int x, int y)
{
if (attachmentIndex >= m_ColorAttachmentsSpecifications.size())
{
HZ_CORE_ERROR("Attempting to read pixel from non-existant attachment");
}
glReadBuffer(GL_COLOR_ATTACHMENT0 + attachmentIndex);
int pixelData;
glReadPixels(x, y, 1, 1, GL_RED_INTEGER, GL_INT, &pixelData);
return pixelData;
}
void OpenGLFrameBuffer::Resize(const uint32_t width, const uint32_t height) void OpenGLFrameBuffer::Resize(const uint32_t width, const uint32_t height)
{ {
if (width == 0 || height == 0) if (width == 0 || height == 0)
@ -53,15 +184,68 @@ namespace Hazel
if (m_RendererID) if (m_RendererID)
{ {
glDeleteFramebuffers(1, &m_RendererID); glDeleteFramebuffers(1, &m_RendererID);
glDeleteTextures(1, &m_ColorAttachment); glDeleteTextures(m_ColorAttachmentsSpecifications.size(), m_ColorAttachments.data());
glDeleteTextures(1, &m_DepthAttachment); glDeleteTextures(1, &m_DepthAttachment);
m_ColorAttachments.clear();
m_DepthAttachment = 0;
glViewport(0, 0, m_Specification.Width, m_Specification.Height); glViewport(0, 0, m_Specification.Width, m_Specification.Height);
} }
glCreateFramebuffers(1, &m_RendererID); bool multisample = m_Specification.Samples > 1;
glBindFramebuffer(GL_FRAMEBUFFER, m_RendererID); glCreateFramebuffers(1, &m_RendererID); glBindFramebuffer(GL_FRAMEBUFFER, m_RendererID);
// Attachments
if (m_ColorAttachmentsSpecifications.size() > 0)
{
m_ColorAttachments.resize(m_ColorAttachmentsSpecifications.size());
Utils::CreateTextures(multisample, m_ColorAttachments.data(), m_ColorAttachments.size());
for (size_t i = 0; i < m_ColorAttachmentsSpecifications.size(); i++)
{
Utils::BindTexture(multisample, m_ColorAttachments[i]);
switch (m_ColorAttachmentsSpecifications[i].TextureFormat)
{
case FrameBufferTextureFormat::RGBA8:
Utils::AtttachColorTexture(m_ColorAttachments[i], m_Specification.Samples, GL_RGBA8, GL_RGBA, m_Specification.Width, m_Specification.Height, i);
break;
case FrameBufferTextureFormat::RED_INTEGER:
Utils::AtttachColorTexture(m_ColorAttachments[i], m_Specification.Samples, GL_R32I, GL_RED_INTEGER, m_Specification.Width, m_Specification.Height, i);
break;
}
}
}
if (m_DepthAttachmentSpecification.TextureFormat != FrameBufferTextureFormat::NONE)
{
Utils::CreateTextures(multisample, &m_DepthAttachment, 1);
Utils::BindTexture(multisample, m_DepthAttachment);
switch (m_DepthAttachmentSpecification.TextureFormat)
{
case FrameBufferTextureFormat::DEPTH24STENCIL8:
Utils::AtttachDepthTexture(m_DepthAttachment, m_Specification.Samples, GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL_ATTACHMENT, m_Specification.Width, m_Specification.Height);
break;
}
}
if (m_ColorAttachments.size() > 1)
{
if (m_ColorAttachments.size() > 4)
{
HZ_CORE_ERROR("Too many color attachments!");
}
constexpr GLenum buffers[4] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3};
glDrawBuffers(m_ColorAttachments.size(), buffers);
}
else if (m_ColorAttachments.empty())
{
// Only depth pass
glDrawBuffer(GL_NONE);
}
/*
glCreateTextures(GL_TEXTURE_2D, 1, &m_ColorAttachment); glCreateTextures(GL_TEXTURE_2D, 1, &m_ColorAttachment);
glBindTexture(GL_TEXTURE_2D, m_ColorAttachment); glBindTexture(GL_TEXTURE_2D, m_ColorAttachment);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_Specification.Width, m_Specification.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_Specification.Width, m_Specification.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
@ -76,9 +260,10 @@ namespace Hazel
glTexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH24_STENCIL8, m_Specification.Width, m_Specification.Height); glTexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH24_STENCIL8, m_Specification.Width, m_Specification.Height);
// glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, m_Specification.Width, m_Specification.Height, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, nullptr); // glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, m_Specification.Width, m_Specification.Height, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, nullptr);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, m_DepthAttachment, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, m_DepthAttachment, 0);
*/
{ {
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); const GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
switch(status) { switch(status) {
case GL_FRAMEBUFFER_COMPLETE: case GL_FRAMEBUFFER_COMPLETE:
break; break;

View File

@ -4,6 +4,7 @@
#ifndef OPENGLFRAMEBUFFER_H #ifndef OPENGLFRAMEBUFFER_H
#define OPENGLFRAMEBUFFER_H #define OPENGLFRAMEBUFFER_H
#include <Hazel/Core/Log.h>
#include <Hazel/Renderer/FrameBuffer.h> #include <Hazel/Renderer/FrameBuffer.h>
@ -19,15 +20,30 @@ namespace Hazel
void UnBind() override; void UnBind() override;
virtual const FrameBufferSpecification& GetSpecification() const override { return m_Specification; } virtual const FrameBufferSpecification& GetSpecification() const override { return m_Specification; }
virtual uint32_t GetColorAttachmentID() const override { return m_ColorAttachment; } virtual uint32_t GetColorAttachmentID(const uint32_t index = 0) const override {
if (index > m_ColorAttachments.size())
{
HZ_CORE_ERROR("Attempting to access color attachment that is out-of-bounds");
}
return m_ColorAttachments[index];
}
virtual void ClearAttachment(uint32_t attachmentIndex, int value) override;
virtual int ReadPixel(uint32_t attachmentIndex, int x, int y) override;
virtual void Resize(uint32_t width, uint32_t height) override; virtual void Resize(uint32_t width, uint32_t height) override;
virtual uint32_t GetColorAttachmentRendererID(const uint32_t index = 0) const override { return m_ColorAttachments[index]; }
void Invalidata(); void Invalidata();
private: private:
uint32_t m_RendererID = 0; uint32_t m_RendererID = 0;
uint32_t m_ColorAttachment = 0, m_DepthAttachment = 0;
FrameBufferSpecification m_Specification; FrameBufferSpecification m_Specification;
std::vector<FrameBufferTextureSpecification> m_ColorAttachmentsSpecifications;
FrameBufferTextureSpecification m_DepthAttachmentSpecification = FrameBufferTextureFormat::NONE;
std::vector<uint32_t> m_ColorAttachments;
uint32_t m_DepthAttachment = 0;
}; };
} }

View File

@ -73,11 +73,44 @@ namespace Hazel
uint32_t index = 0; uint32_t index = 0;
for (const auto& element : vertexBuffer->GetLayout()) for (const auto& element : vertexBuffer->GetLayout())
{ {
glEnableVertexAttribArray(index); switch (element.Type)
glVertexAttribPointer(index, element.GetComponentCount(), ShaderDataTypeToOpenGLBaseType(element.Type), {
element.Normalized ? GL_TRUE : GL_FALSE, vertexBuffer->GetLayout().GetStride(), case ShaderDataType::Float:
(void*)element.Offset); case ShaderDataType::Float2:
index ++; case ShaderDataType::Float3:
case ShaderDataType::Float4:
case ShaderDataType::Mat3:
case ShaderDataType::Mat4:
{
glEnableVertexAttribArray(index);
glVertexAttribPointer(index,
element.GetComponentCount(),
ShaderDataTypeToOpenGLBaseType(element.Type),
element.Normalized ? GL_TRUE : GL_FALSE,
vertexBuffer->GetLayout().GetStride(),
(const void*)element.Offset);
index++;
break;
}
case ShaderDataType::Int:
case ShaderDataType::Int2:
case ShaderDataType::Int3:
case ShaderDataType::Int4:
case ShaderDataType::Bool:
{
glEnableVertexAttribArray(index);
glVertexAttribIPointer(index,
element.GetComponentCount(),
ShaderDataTypeToOpenGLBaseType(element.Type),
vertexBuffer->GetLayout().GetStride(),
(const void*)element.Offset);
index++;
break;
}
default:
HZ_CORE_DEBUG("Unknown ShaderDataType!");
break;
}
} }
m_VertexBuffers.push_back(vertexBuffer); m_VertexBuffers.push_back(vertexBuffer);

View File

@ -6,20 +6,23 @@ layout(location = 1) in vec4 a_Color;
layout(location = 2) in vec2 a_TexCoord; layout(location = 2) in vec2 a_TexCoord;
layout(location = 3) in float a_TexIndex; 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;
uniform mat4 u_ViewProjection; uniform mat4 u_ViewProjection;
//uniform mat4 u_Transform; //uniform mat4 u_Transform;
out vec2 v_TexCoord; out vec2 v_TexCoord;
out vec4 v_Color; out vec4 v_Color;
out float v_TexIndex; out flat float v_TexIndex;
out float v_TilingFactor; out float v_TilingFactor;
out flat int v_EntityID;
void main() { void main() {
v_TexCoord = a_TexCoord; v_TexCoord = a_TexCoord;
v_Color = a_Color; v_Color = a_Color;
v_TexIndex = a_TexIndex; v_TexIndex = a_TexIndex;
v_TilingFactor = a_TilingFactor; 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.0f);
} }
@ -28,11 +31,13 @@ void main() {
#version 460 core #version 460 core
layout(location = 0) out vec4 color; layout(location = 0) out vec4 color;
layout(location = 1) out int color2;
in vec2 v_TexCoord; in vec2 v_TexCoord;
in vec4 v_Color; in vec4 v_Color;
in float v_TexIndex; in flat float v_TexIndex;
in float v_TilingFactor; in float v_TilingFactor;
in flat int v_EntityID;
uniform vec4 u_Color; uniform vec4 u_Color;
uniform sampler2D u_Textures[32]; uniform sampler2D u_Textures[32];
@ -41,4 +46,5 @@ void main() {
color = texture(u_Textures[int(v_TexIndex)], v_TexCoord * v_TilingFactor) * v_Color; color = texture(u_Textures[int(v_TexIndex)], v_TexCoord * v_TilingFactor) * v_Color;
// color = v_Color; // color = v_Color;
color2 = v_EntityID;
} }

View File

@ -27,6 +27,7 @@ namespace Hazel
FrameBufferSpecification spec; FrameBufferSpecification spec;
spec.Width = Application::Get().GetWindow().GetWidth(); spec.Width = Application::Get().GetWindow().GetWidth();
spec.Height = Application::Get().GetWindow().GetHeight(); spec.Height = Application::Get().GetWindow().GetHeight();
spec.Attachments = { FrameBufferTextureFormat::RGBA8, FrameBufferTextureFormat::RED_INTEGER,FrameBufferTextureFormat::DEPTH };
m_FrameBuffer = FrameBuffer::Create(spec); m_FrameBuffer = FrameBuffer::Create(spec);
m_ViewPortSize = { spec.Width, spec.Height }; m_ViewPortSize = { spec.Width, spec.Height };
@ -73,12 +74,28 @@ namespace Hazel
RendererCommand::SetClearColor(m_BackgroundColor); RendererCommand::SetClearColor(m_BackgroundColor);
RendererCommand::Clear(); RendererCommand::Clear();
m_FrameBuffer->ClearAttachment(1, -1);
// Renderer2D::BeginScene(m_CameraController.GetCamera()); // Renderer2D::BeginScene(m_CameraController.GetCamera());
// update Scene // update Scene
m_ActiveScene->OnUpdateEditor(ts, m_EditorCamera); m_ActiveScene->OnUpdateEditor(ts, m_EditorCamera);
auto [mx, my] = ImGui::GetMousePos();
mx -= m_ViewPortBounds[0].x;
my -= m_ViewPortBounds[0].y;
const glm::vec2 viewPortSize = m_ViewPortBounds[1] - m_ViewPortBounds[0];
my = viewPortSize.y - my;
int mouseX = (int)mx;
int mouseY = (int)my;
if (mouseX >= 0 && mouseY >= 0 && mouseX < m_ViewPortSize.x && mouseY < m_ViewPortSize.y)
{
int pixelData = m_FrameBuffer->ReadPixel(1, mouseX, mouseY);
m_HoveredEntity = pixelData == -1 ? Entity{} : Entity{ (entt::entity)pixelData, m_ActiveScene.get()};
}
// Renderer2D::DrawQuad({0, 0.5f}, {1.0f, 1.0f}, {0.2f, 0.3f, 0.8f, 1.0f}); // Renderer2D::DrawQuad({0, 0.5f}, {1.0f, 1.0f}, {0.2f, 0.3f, 0.8f, 1.0f});
// Renderer2D::DrawQuad({0, -0.5f}, {1.0f, 1.0f}, {0.8f, 0.2f, 0.2f, 1.0f}); // Renderer2D::DrawQuad({0, -0.5f}, {1.0f, 1.0f}, {0.8f, 0.2f, 0.2f, 1.0f});
// Renderer2D::DrawQuad({-1, 0}, {1, 1}, m_LogoTexture); // Renderer2D::DrawQuad({-1, 0}, {1, 1}, m_LogoTexture);
@ -138,9 +155,9 @@ namespace Hazel
ImGui::PopStyleVar(2); ImGui::PopStyleVar(2);
// Submit the DockSpace // Submit the DockSpace
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
ImGuiStyle& style = ImGui::GetStyle(); ImGuiStyle& style = ImGui::GetStyle();
style.WindowMinSize.x = 350.0f; style.WindowMinSize.x = 350.0f;
if (io.ConfigFlags & ImGuiConfigFlags_DockingEnable) if (io.ConfigFlags & ImGuiConfigFlags_DockingEnable)
{ {
ImGuiID dockspace_id = ImGui::GetID("MyDockSpace"); ImGuiID dockspace_id = ImGui::GetID("MyDockSpace");
@ -156,14 +173,14 @@ namespace Hazel
// ImGui::MenuItem("Fullscreen", NULL, &opt_fullscreen); // ImGui::MenuItem("Fullscreen", NULL, &opt_fullscreen);
// ImGui::MenuItem("Padding", NULL, &opt_padding); // ImGui::MenuItem("Padding", NULL, &opt_padding);
// ImGui::Separator(); // ImGui::Separator();
if (ImGui::MenuItem("New", "Ctrl+N")) if (ImGui::MenuItem("New", "Ctrl+N"))
NewScene(); NewScene();
if (ImGui::MenuItem("Open...", "Ctrl+O")) if (ImGui::MenuItem("Open...", "Ctrl+O"))
OpenScene(); OpenScene();
if (ImGui::MenuItem("Save As...", "Ctrl+Shift+S")) if (ImGui::MenuItem("Save As...", "Ctrl+Shift+S"))
SaveScene(); SaveScene();
ImGui::Separator(); ImGui::Separator();
if (ImGui::MenuItem("Exit")) { Hazel::Application::Get().Close(); } if (ImGui::MenuItem("Exit")) { Hazel::Application::Get().Close(); }
ImGui::EndMenu(); ImGui::EndMenu();
@ -172,10 +189,10 @@ namespace Hazel
ImGui::EndMenuBar(); ImGui::EndMenuBar();
} }
// Scene Hierachy Panel // Scene Hierachy Panel
m_SceneHierachyPanel.OnImGuiRender(); m_SceneHierachyPanel.OnImGuiRender();
// Render Status // Render Status
{ {
ImGui::Begin("Render Status"); ImGui::Begin("Render Status");
@ -189,15 +206,25 @@ namespace Hazel
ImGui::Separator(); ImGui::Separator();
ImGui::Text("viewPortSize: (%.2f, %.2f)", m_ViewPortSize.x, m_ViewPortSize.y); ImGui::Text("viewPortSize: (%.2f, %.2f)", m_ViewPortSize.x, m_ViewPortSize.y);
ImGui::Separator();
std::string name = "none";
if (m_HoveredEntity)
name = m_HoveredEntity.GetComponent<TagComponent>().Tag;
ImGui::Text("Hovered Entity: %s", name.c_str());
ImGui::End(); ImGui::End();
} }
// ViewPort // ViewPort
{ {
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, {0.0f, 0.0f}); ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, {0.0f, 0.0f});
ImGui::Begin("Viewport"); ImGui::Begin("Viewport");
m_ViewportFocused = ImGui::IsWindowFocused(); auto viewportOffet = ImGui::GetCursorPos();
m_ViewportHovered = ImGui::IsWindowHovered(); m_ViewportFocused = ImGui::IsWindowFocused();
m_ViewportHovered = ImGui::IsWindowHovered();
ImVec2 viewPortPanelSize = ImGui::GetContentRegionAvail(); ImVec2 viewPortPanelSize = ImGui::GetContentRegionAvail();
@ -209,21 +236,34 @@ namespace Hazel
ImGui::Image(m_FrameBuffer->GetColorAttachmentID(), {m_ViewPortSize.x, m_ViewPortSize.y}, {0, 1}, ImGui::Image(m_FrameBuffer->GetColorAttachmentID(), {m_ViewPortSize.x, m_ViewPortSize.y}, {0, 1},
{1, 0}); {1, 0});
Entity selectedEntity = m_SceneHierachyPanel.GetSelectedEntity();
if (selectedEntity)
{
ImGuizmo::SetOrthographic(false);
ImGuizmo::SetDrawlist();
const float windowWidth = ImGui::GetWindowWidth(); auto windowsSize = ImGui::GetWindowSize();
const float windowHeight = ImGui::GetWindowHeight(); ImVec2 minBound = ImGui::GetWindowPos();
const ImVec2 windowPos = ImGui::GetWindowPos();
ImGuizmo::SetRect(windowPos.x,windowPos.y,windowWidth,windowHeight); minBound.x += viewportOffet.x;
minBound.y += viewportOffet.y + m_ViewPortSize.y - windowsSize.y;
// auto cameraEntity = m_ActiveScene->GetPrimaryCameraEntity(); ImVec2 maxBound = {minBound.x + windowsSize.x, minBound.y + windowsSize.y};
if (m_GizmoType != -1) m_ViewPortBounds[0] = {minBound.x, minBound.y};
m_ViewPortBounds[1] = {maxBound.x, maxBound.y};
// ImGuizmo
Entity selectedEntity = m_SceneHierachyPanel.GetSelectedEntity();
if (selectedEntity)
{
ImGuizmo::SetOrthographic(false);
ImGuizmo::SetDrawlist();
const float windowWidth = ImGui::GetWindowWidth();
const float windowHeight = ImGui::GetWindowHeight();
const ImVec2 windowPos = ImGui::GetWindowPos();
ImGuizmo::SetRect(windowPos.x, windowPos.y, windowWidth, windowHeight);
// auto cameraEntity = m_ActiveScene->GetPrimaryCameraEntity();
if (m_GizmoType != -1)
{ {
// const auto& camera = cameraEntity.GetComponent<CameraComponent>().Camera; // const auto& camera = cameraEntity.GetComponent<CameraComponent>().Camera;
auto& tc = selectedEntity.GetComponent<TransformComponent>(); auto& tc = selectedEntity.GetComponent<TransformComponent>();
@ -231,38 +271,40 @@ namespace Hazel
// const glm::mat4& cameraProjection = camera.GetProjection(); // const glm::mat4& cameraProjection = camera.GetProjection();
// glm::mat4 cameraView = glm::inverse(cameraEntity.GetComponent<TransformComponent>().GetTransform()); // glm::mat4 cameraView = glm::inverse(cameraEntity.GetComponent<TransformComponent>().GetTransform());
glm::mat4 cameraProjection = m_EditorCamera.GetProjection(); glm::mat4 cameraProjection = m_EditorCamera.GetProjection();
glm::mat4 cameraView = m_EditorCamera.GetViewMatrix(); glm::mat4 cameraView = m_EditorCamera.GetViewMatrix();
glm::mat4 transform = tc.GetTransform(); glm::mat4 transform = tc.GetTransform();
bool snap = SDL_GetModState() & SDL_KMOD_CTRL; bool snap = SDL_GetModState() & SDL_KMOD_CTRL;
float snapValue = 0.5f; float snapValue = 0.5f;
if (m_GizmoType == ImGuizmo::OPERATION::TRANSLATE) if (m_GizmoType == ImGuizmo::OPERATION::TRANSLATE)
snapValue = 0.25f; snapValue = 0.25f;
else if (m_GizmoType == ImGuizmo::OPERATION::ROTATE) else if (m_GizmoType == ImGuizmo::OPERATION::ROTATE)
snapValue = 15.0f; snapValue = 15.0f;
else if (m_GizmoType == ImGuizmo::OPERATION::SCALE) else if (m_GizmoType == ImGuizmo::OPERATION::SCALE)
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), ImGuizmo::OPERATION(m_GizmoType), ImGuizmo::LOCAL,glm::value_ptr(transform), nullptr, snap ? snapValues : nullptr)) 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))
{ {
if (ImGuizmo::IsUsing()) if (ImGuizmo::IsUsing())
{ {
glm::vec3 translation, rotation, scale; glm::vec3 translation, rotation, scale;
Hazel::Math::DecomposeTransform(transform, translation, rotation, scale); Hazel::Math::DecomposeTransform(transform, translation, rotation, scale);
glm::vec3 deltaRotation = rotation - tc.Rotation; glm::vec3 deltaRotation = rotation - tc.Rotation;
tc.Translation = translation; tc.Translation = translation;
tc.Rotation += deltaRotation; tc.Rotation += deltaRotation;
tc.Scale = scale; tc.Scale = scale;
} }
} }
} }
} }
ImGui::End(); ImGui::End();
ImGui::PopStyleVar(); ImGui::PopStyleVar();
@ -273,7 +315,7 @@ namespace Hazel
void EditorLayer::SaveScene() const void EditorLayer::SaveScene() const
{ {
std::string filepath = FileDiaglogs::SaveFile("Hazel Scene (*.scene)\0*.scene\0"); std::string filepath = FileDiaglogs::SaveFile("Hazel Scene (*.scene,*.yaml)\0*.scene;*.yaml\0*\0*.*\0\0");
if (!filepath.empty()) if (!filepath.empty())
{ {
SceneSerializer serializer(m_ActiveScene); SceneSerializer serializer(m_ActiveScene);
@ -283,7 +325,7 @@ namespace Hazel
void EditorLayer::OpenScene() void EditorLayer::OpenScene()
{ {
std::string filepath = FileDiaglogs::OpenFile("Hazel Scene (*.scene)\0*.scene\0"); std::string filepath = FileDiaglogs::OpenFile("Scene(*.scene, *.yaml)\0*.scene;*.yaml\0All files\0*.*\0\0");
if (!filepath.empty()) if (!filepath.empty())
{ {
m_ActiveScene = CreateRef<Scene>(); m_ActiveScene = CreateRef<Scene>();
@ -302,11 +344,10 @@ namespace Hazel
m_SceneHierachyPanel.SetContext(m_ActiveScene); m_SceneHierachyPanel.SetContext(m_ActiveScene);
} }
void EditorLayer::ChangeOptMode(unsigned int mode) void EditorLayer::ChangeOptMode(unsigned int mode)
{ {
if (m_ViewportHovered) if (m_ViewportHovered)
m_GizmoType = mode; m_GizmoType = mode;
} }
void EditorLayer::OnEvent(SDL_Event& e) void EditorLayer::OnEvent(SDL_Event& e)
@ -314,46 +355,45 @@ namespace Hazel
if (m_ViewportFocused && m_ViewportHovered) if (m_ViewportFocused && m_ViewportHovered)
{ {
m_CameraController.OnEvent(e); m_CameraController.OnEvent(e);
m_EditorCamera.OnEvent(e); m_EditorCamera.OnEvent(e);
} }
#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)
#define SHORTCUT_SAVE_ALL (SDL_KMOD_CTRL | SDL_KMOD_SHIFT | SDLK_S) #define SHORTCUT_SAVE_ALL (SDL_KMOD_CTRL | SDL_KMOD_SHIFT | SDLK_S)
const auto mod = SDL_GetModState(); const auto mod = SDL_GetModState();
const auto ctrl = (mod & SDL_KMOD_CTRL) ? SDL_KMOD_CTRL : 0; const auto ctrl = (mod & SDL_KMOD_CTRL) ? SDL_KMOD_CTRL : 0;
const auto shift = (mod & SDL_KMOD_SHIFT) ? SDL_KMOD_SHIFT : 0; const auto shift = (mod & SDL_KMOD_SHIFT) ? SDL_KMOD_SHIFT : 0;
switch (ctrl | shift | e.key.key) switch (ctrl | shift | e.key.key)
{ {
case SHORTCUT_NEW: case SHORTCUT_NEW:
NewScene(); NewScene();
break; break;
case SHORTCUT_OPEN: case SHORTCUT_OPEN:
OpenScene(); OpenScene();
break; break;
case SHORTCUT_SAVE_ALL: case SHORTCUT_SAVE_ALL:
SaveScene(); SaveScene();
break; break;
// GIZMO // GIZMO
case SDLK_Q: case SDLK_Q:
ChangeOptMode(-1); ChangeOptMode(-1);
break; break;
case SDLK_W: case SDLK_W:
ChangeOptMode(ImGuizmo::OPERATION::TRANSLATE); ChangeOptMode(ImGuizmo::OPERATION::TRANSLATE);
break; break;
case SDLK_E: case SDLK_E:
ChangeOptMode(ImGuizmo::OPERATION::SCALE); ChangeOptMode(ImGuizmo::OPERATION::SCALE);
break; break;
case SDLK_R: case SDLK_R:
ChangeOptMode(ImGuizmo::OPERATION::ROTATE); ChangeOptMode(ImGuizmo::OPERATION::ROTATE);
break; break;
default: default:
break; break;
} }
} }
} }

View File

@ -37,11 +37,14 @@ namespace Hazel
Ref<Scene> m_ActiveScene; Ref<Scene> m_ActiveScene;
EditorCamera m_EditorCamera; EditorCamera m_EditorCamera;
Entity m_HoveredEntity;
glm::vec4 m_BackgroundColor = { 0.2f, 0.2f, 0.2f, 1.0f }; glm::vec4 m_BackgroundColor = { 0.2f, 0.2f, 0.2f, 1.0f };
glm::vec4 m_SquareColor = { 0.2f, 0.2f, 0.2f, 1.0f }; glm::vec4 m_SquareColor = { 0.2f, 0.2f, 0.2f, 1.0f };
bool m_ViewportFocused = false, m_ViewportHovered = false; bool m_ViewportFocused = false, m_ViewportHovered = false;
glm::vec2 m_ViewPortSize = {0, 0}; glm::vec2 m_ViewPortSize = {0, 0};
glm::vec2 m_ViewPortBounds[2];
Ref<FrameBuffer> m_FrameBuffer; Ref<FrameBuffer> m_FrameBuffer;