添加组件圆,添加可视化碰撞器渲染

This commit is contained in:
2025-06-24 17:24:56 +08:00
parent 0032814ed6
commit a32ce57503
19 changed files with 635 additions and 58 deletions

View File

@ -30,6 +30,27 @@ namespace Hazel
int EntityID;
};
struct CircleVertex
{
glm::vec3 WorldPosition;
glm::vec3 LocalPosition;
glm::vec4 Color;
float Thickness;
float Fade;
// TODO: Editor Only
int EntityID;
};
struct LineVertex
{
glm::vec3 Position;
glm::vec4 Color;
// TODO: Editor Only
int EntityID;
};
struct Renderer2DStorage
{
const uint32_t MaxQuad = 10000;
@ -39,13 +60,32 @@ namespace Hazel
Ref<VertexArray> QuadVertexArray;
Ref<VertexBuffer> QuadVertexBuffer;
Ref<Shader> TextureShader;
Ref<Shader> QuadShader;
Ref<Texture2D> WhiteTexture;
Ref<VertexArray> CircleVertexArray;
Ref<VertexBuffer> CircleVertexBuffer;
Ref<Shader> CircleShader;
Ref<VertexArray> LineVertexArray;
Ref<VertexBuffer> LineVertexBuffer;
Ref<Shader> LineShader;
uint32_t QuadIndexCount = 0;
QuadVertex* QuadVertexBufferBase = nullptr;
QuadVertex* QuadVertexBufferPtr = nullptr;
uint32_t CircleIndexCount = 0;
CircleVertex* CircleVertexBufferBase = nullptr;
CircleVertex* CircleVertexBufferPtr = nullptr;
uint32_t LineVertexCount = 0;
LineVertex* LineVertexBufferBase = nullptr;
LineVertex* LineVertexBufferPtr = nullptr;
float LineWidth = 2.0f;
std::array<Ref<Texture2D>, MaxTextureSlots> TextureSlots;
uint32_t TextureSlotIndex = 1; // 0 use white texture
@ -67,6 +107,7 @@ namespace Hazel
{
HZ_PROFILE_FUNCTION();
///////////////Quad//////////////////
// s_Data = new Renderer2DStorage();
s_Data.QuadVertexArray = VertexArray::Create();
@ -104,8 +145,44 @@ namespace Hazel
Ref<IndexBuffer> quadIB = IndexBuffer::Create(quadIndices, s_Data.MaxIndices);
s_Data.QuadVertexArray->SetIndexBuffer(quadIB);
delete[] quadIndices;
////////////////////////////////////////
///////////////Circle//////////////////
s_Data.CircleVertexArray = VertexArray::Create();
//= VertexBuffer::Create(squareVertices, sizeof(squareVertices));
s_Data.CircleVertexBuffer = VertexBuffer::Create(s_Data.MaxVertices * sizeof(CircleVertex));
s_Data.CircleVertexBuffer->SetLayout(
{
{ShaderDataType::Float3, "a_WorldPostion"},
{ShaderDataType::Float3, "a_LocalPostion"},
{ShaderDataType::Float4, "a_Color"},
{ShaderDataType::Float, "a_Thickness"},
{ShaderDataType::Float, "a_Fade"},
{ShaderDataType::Int, "a_EntityID"}
});
s_Data.CircleVertexArray->AddVertexBuffer(s_Data.CircleVertexBuffer);
s_Data.CircleVertexArray->SetIndexBuffer(quadIB);
s_Data.CircleVertexBufferBase = new CircleVertex[s_Data.MaxVertices];
///////////////////////////////////////
/////////////// line//////////////////
s_Data.LineVertexArray = VertexArray::Create();
//= VertexBuffer::Create(squareVertices, sizeof(squareVertices));
s_Data.LineVertexBuffer = VertexBuffer::Create(s_Data.MaxVertices * sizeof(LineVertex));
s_Data.LineVertexBuffer->SetLayout(
{
{ShaderDataType::Float3, "a_Postion"},
{ShaderDataType::Float4, "a_Color"},
{ShaderDataType::Int, "a_EntityID"}
});
s_Data.LineVertexArray->AddVertexBuffer(s_Data.LineVertexBuffer);
// s_Data.LineVertexArray->SetIndexBuffer(quadIB);
s_Data.LineVertexBufferBase = new LineVertex[s_Data.MaxVertices];
///////////////////////////////////////
s_Data.WhiteTexture = Texture2D::Create(1, 1);
uint32_t whiteTextureData = 0xffffffff;
s_Data.WhiteTexture->SetData(&whiteTextureData, sizeof(uint32_t));
@ -117,9 +194,9 @@ namespace Hazel
samplers[i] = i;
}
s_Data.TextureShader = Shader::Create("assets/shaders/Texture.glsl");
s_Data.TextureShader->Bind();
s_Data.TextureShader->SetIntv("u_Textures", samplers, s_Data.MaxTextureSlots);
s_Data.QuadShader = Shader::Create("assets/shaders/Renderer2D_quad.glsl");
s_Data.CircleShader = Shader::Create("assets/shaders/Renderer2D_circle.glsl");
s_Data.LineShader = Shader::Create("assets/shaders/Renderer2D_line.glsl");
// set all texture slot to 0
s_Data.TextureSlots[0] = s_Data.WhiteTexture;
@ -184,27 +261,58 @@ namespace Hazel
{
HZ_PROFILE_FUNCTION();
const uint32_t datasize = reinterpret_cast<uint8_t*>(s_Data.QuadVertexBufferPtr) - reinterpret_cast<uint8_t*>(s_Data.QuadVertexBufferBase);
s_Data.QuadVertexBuffer->SetData(s_Data.QuadVertexBufferBase, datasize);
Flush();
}
void Renderer2D::Flush()
{
if (s_Data.QuadIndexCount)
{
const uint32_t datasize = reinterpret_cast<uint8_t*>(s_Data.QuadVertexBufferPtr) - reinterpret_cast<uint8_t*>(s_Data.QuadVertexBufferBase);
s_Data.QuadVertexBuffer->SetData(s_Data.QuadVertexBufferBase, datasize);
for (uint32_t i = 0; i < s_Data.TextureSlotIndex; i++)
{
s_Data.TextureSlots[i]->Bind(i);
}
s_Data.QuadShader->Bind();
RendererCommand::DrawIndexed(s_Data.QuadVertexArray, s_Data.QuadIndexCount);
s_Data.Stats.DrawCalls++;
}
if (s_Data.CircleIndexCount)
{
const uint32_t datasize = reinterpret_cast<uint8_t*>(s_Data.CircleVertexBufferPtr) - reinterpret_cast<uint8_t*>(s_Data.CircleVertexBufferBase);
s_Data.CircleVertexBuffer->SetData(s_Data.CircleVertexBufferBase, datasize);
auto& a = s_Data;
s_Data.CircleShader->Bind();
RendererCommand::DrawIndexed(s_Data.CircleVertexArray, s_Data.CircleIndexCount);
s_Data.Stats.DrawCalls++;
}
if (s_Data.LineVertexCount)
{
const uint32_t datasize = reinterpret_cast<uint8_t*>(s_Data.LineVertexBufferPtr) - reinterpret_cast<uint8_t*>(s_Data.LineVertexBufferBase);
s_Data.LineVertexBuffer->SetData(s_Data.LineVertexBufferBase, datasize);
auto& a = s_Data;
s_Data.LineShader->Bind();
RendererCommand::SetLineWidth(s_Data.LineWidth);
RendererCommand::DrawLines(s_Data.LineVertexArray, s_Data.LineVertexCount);
s_Data.Stats.DrawCalls++;
}
}
void Renderer2D::StartBatch()
{
s_Data.QuadIndexCount = 0;
s_Data.QuadVertexBufferPtr = s_Data.QuadVertexBufferBase;
s_Data.CircleIndexCount = 0;
s_Data.CircleVertexBufferPtr = s_Data.CircleVertexBufferBase;
s_Data.LineVertexCount = 0;
s_Data.LineVertexBufferPtr = s_Data.LineVertexBufferBase;
s_Data.TextureSlotIndex = 1;
}
@ -320,7 +428,7 @@ namespace Hazel
s_Data.Stats.QuadCount ++;
}
void Renderer2D::DrawQuad(const glm::mat4& transform, const glm::vec4& Color, const int entityID)
void Renderer2D::DrawQuad(const glm::mat4& transform, const glm::vec4& color, const int entityID)
{
HZ_PROFILE_FUNCTION();
if (s_Data.QuadIndexCount >= s_Data.MaxIndices)
@ -335,7 +443,7 @@ namespace Hazel
for (unsigned int i = 0; i < 4; i++)
{
s_Data.QuadVertexBufferPtr->Position = transform * s_Data.QuadVertexPosition[i];
s_Data.QuadVertexBufferPtr->Color = Color;
s_Data.QuadVertexBufferPtr->Color = color;
s_Data.QuadVertexBufferPtr->TexCoord = texCoords[i];
s_Data.QuadVertexBufferPtr->TexIndex = textureIndex;
s_Data.QuadVertexBufferPtr->TilingFactor = tilingFactor;
@ -532,6 +640,82 @@ namespace Hazel
s_Data.Stats.QuadCount ++;
}
void Renderer2D::DrawCircle(const glm::mat4& transform, const glm::vec4& color, const float thickness, const float fade, const int entityID)
{
HZ_PROFILE_FUNCTION();
// TODO: implement for circles
// if (s_Data.CircleIndexCount >= s_Data.MaxIndices)
// FlushAndReset();
for (size_t i = 0; i < 4; i++)
{
s_Data.CircleVertexBufferPtr->WorldPosition = transform * s_Data.QuadVertexPosition[i];
s_Data.CircleVertexBufferPtr->LocalPosition = s_Data.QuadVertexPosition[i] * 2.0f;
s_Data.CircleVertexBufferPtr->Color = color;
s_Data.CircleVertexBufferPtr->Thickness = thickness;
s_Data.CircleVertexBufferPtr->Fade = fade;
s_Data.CircleVertexBufferPtr->EntityID = entityID;
s_Data.CircleVertexBufferPtr++;
}
s_Data.CircleIndexCount += 6;
s_Data.Stats.QuadCount ++;
}
void Renderer2D::DrawLine(const glm::vec3& p0, const glm::vec3& p1, const glm::vec4& color, const int entityID)
{
s_Data.LineVertexBufferPtr->Position = p0;
s_Data.LineVertexBufferPtr->Color = color;
s_Data.LineVertexBufferPtr->EntityID = entityID;
s_Data.LineVertexBufferPtr++;
s_Data.LineVertexBufferPtr->Position = p1;
s_Data.LineVertexBufferPtr->Color = color;
s_Data.LineVertexBufferPtr->EntityID = entityID;
s_Data.LineVertexBufferPtr++;
s_Data.LineVertexCount += 2;
}
void Renderer2D::DrawRect(const glm::vec3& position, const glm::vec2& size, const glm::vec4& color, const int entityID)
{
const glm::vec3 p0 = glm::vec3(position.x - size.x * 0.5f, position.y - size.y * 0.5f, position.z);
const glm::vec3 p1 = glm::vec3(position.x + size.x * 0.5f, position.y - size.y * 0.5f, position.z);
const glm::vec3 p2 = glm::vec3(position.x + size.x * 0.5f, position.y + size.y * 0.5f, position.z);
const glm::vec3 p3 = glm::vec3(position.x - size.x * 0.5f, position.y + size.y * 0.5f, position.z);
DrawLine(p0, p1, color, entityID);
DrawLine(p1, p2, color, entityID);
DrawLine(p2, p3, color, entityID);
DrawLine(p3, p0, color, entityID);
}
void Renderer2D::DrawRect(const glm::mat4& transform, const glm::vec4& color, int entityID)
{
glm::vec3 lineVectices[4];
for (int i = 0; i < 4; i++)
{
lineVectices[i] = transform * s_Data.QuadVertexPosition[i];
}
DrawLine(lineVectices[0], lineVectices[1], color, entityID);
DrawLine(lineVectices[1], lineVectices[2], color, entityID);
DrawLine(lineVectices[2], lineVectices[3], color, entityID);
DrawLine(lineVectices[3], lineVectices[0], color, entityID);
}
float Renderer2D::GetLineWidth()
{
return s_Data.LineWidth;
}
void Renderer2D::SetLineWidth(const float width)
{
s_Data.LineWidth = width;
}
void Renderer2D::DrawSprite(const glm::mat4& transform, SpriteRendererComponent& src, int entityID)
{
if (src.Texture)

View File

@ -44,7 +44,7 @@ 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::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, const int entityID = -1);
static void DrawQuad(const glm::mat4& transform, const glm::vec4& color, 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), const int entityID = -1);
static void DrawRotateQuad(const glm::vec2& position, const glm::vec2& size, float rotation, const glm::vec4& color);
@ -54,6 +54,14 @@ 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::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 DrawCircle(const glm::mat4& transform, const glm::vec4& color, float thickness = 1.0f, float fade = 0.005f, int entityID = -1);
static void DrawLine(const glm::vec3& p0, const glm::vec3& p1, const glm::vec4& color, int entityID = -1);
static void DrawRect(const glm::vec3& position, const glm::vec2& size, const glm::vec4& color, int entityID = -1);
static void DrawRect(const glm::mat4& transform, const glm::vec4& color, int entityID = -1);
static float GetLineWidth();
static void SetLineWidth(float width);
static void DrawSprite(const glm::mat4& transform, SpriteRendererComponent& src, int entityID);

View File

@ -30,6 +30,8 @@ namespace Hazel
virtual void Clear() = 0;
virtual void DrawIndexed(const std::shared_ptr<VertexArray>& vertexArray, uint32_t indexCount) = 0;
virtual void DrawLines(const std::shared_ptr<VertexArray>& vertexArray, uint32_t vertexCount) = 0;
virtual void SetLineWidth(float width) = 0;
inline static API GetAPI() {return s_API; }

View File

@ -40,6 +40,15 @@ namespace Hazel {
s_RendererAPI->DrawIndexed(vertexArray, indexCount);
}
inline static void DrawLines(const std::shared_ptr<VertexArray>& vertexArray, const uint32_t vertexCount)
{
s_RendererAPI->DrawLines(vertexArray, vertexCount);
}
inline static void SetLineWidth(const float width)
{
s_RendererAPI->SetLineWidth(width);
}
private:

View File

@ -62,9 +62,20 @@ namespace Hazel
SpriteRendererComponent() = default;
SpriteRendererComponent(const SpriteRendererComponent&) = default;
SpriteRendererComponent(const glm::vec4& color) : Color(color)
SpriteRendererComponent(const glm::vec4& color) : Color(color) {}
};
struct CircleRendererComponent
{
}
glm::vec4 Color{1.0f, 1.0f, 1.0f, 1.0f};
float Radius = 0.5f;
float Thickness = 0.5f;
float Fade = 0.005f;
CircleRendererComponent() = default;
CircleRendererComponent(const CircleRendererComponent&) = default;
CircleRendererComponent(const glm::vec4& color) : Color(color) {}
};
struct TagComponent
@ -130,13 +141,24 @@ namespace Hazel
float Restitution = 0.0f; // 弹力
float RestitutionThreshold = 0.5f; // 弹力阈值
// Storage for runtime
void *RuntimeBody = nullptr;
BoxCollider2DComponent() = default;
BoxCollider2DComponent(const BoxCollider2DComponent&) = default;
};
struct CircleCollider2DComponent
{
glm::vec2 Offset = {0.0f, 0.0f};
float Radius = 0.5f;
// TODO(Yan): move into material texture in the future
float Density = 1.0f; // 密度
float Friction = 0.5f; // 摩擦力
float Restitution = 0.0f; // 弹力
float RestitutionThreshold = 0.5f; // 弹力阈值
CircleCollider2DComponent() = default;
CircleCollider2DComponent(const CircleCollider2DComponent&) = default;
};
}

View File

@ -90,10 +90,12 @@ namespace Hazel
CopyComponent<TransformComponent>(dstSceneRegistry, srcSceneRegistry, enttMap);
CopyComponent<SpriteRendererComponent>(dstSceneRegistry, srcSceneRegistry, enttMap);
CopyComponent<CircleRendererComponent>(dstSceneRegistry, srcSceneRegistry, enttMap);
CopyComponent<CameraComponent>(dstSceneRegistry, srcSceneRegistry, enttMap);
CopyComponent<NativeScriptComponent>(dstSceneRegistry, srcSceneRegistry, enttMap);
CopyComponent<RigidBody2DComponent>(dstSceneRegistry, srcSceneRegistry, enttMap);
CopyComponent<BoxCollider2DComponent>(dstSceneRegistry, srcSceneRegistry, enttMap);
CopyComponent<CircleCollider2DComponent>(dstSceneRegistry, srcSceneRegistry, enttMap);
return newScene;
}
@ -151,8 +153,9 @@ namespace Hazel
float hx = bc2d.Size.x * transform.Scale.x;
float hy = bc2d.Size.y * transform.Scale.y;
b2Polygon boxShape = b2MakeBox(hx, hy);
b2ShapeDef shapedef = b2DefaultShapeDef();
auto rot = b2Rot(cos(0), sin(0));
b2Polygon boxShape = b2MakeOffsetBox(hx, hy, b2Vec2(bc2d.Offset.x, bc2d.Offset.y), rot);
shapedef.density = bc2d.Density;
shapedef.material.friction = bc2d.Friction;
@ -161,6 +164,23 @@ namespace Hazel
b2CreatePolygonShape(body, &shapedef,&boxShape);
}
if (entity.HasComponent<CircleCollider2DComponent>())
{
auto& cc2d = entity.GetComponent<CircleCollider2DComponent>();
b2Circle circle;
circle.center.x = cc2d.Offset.x;
circle.center.y = cc2d.Offset.y;
circle.radius = transform.Scale.x * cc2d.Radius;
b2ShapeDef shapedef = b2DefaultShapeDef();
shapedef.density = cc2d.Density;
shapedef.material.friction = cc2d.Friction;
shapedef.material.restitution = cc2d.Restitution;
b2CreateCircleShape(body, &shapedef,&circle);
}
}
}
@ -232,19 +252,30 @@ namespace Hazel
}
if (mainCamera != nullptr)
if (mainCamera)
{
Renderer2D::BeginScene(mainCamera->GetProjection(), cameraTranform);
// Draw Sprites
auto group = m_Registry.group<TransformComponent>(entt::get<SpriteRendererComponent>);
for (auto entity : group)
{
auto [transform, sprite] = group.get<TransformComponent, SpriteRendererComponent>(entity);
// Renderer2D::DrawQuad(transform.GetTransform(), sprite.Color);
Renderer2D::DrawSprite(transform.GetTransform(), sprite, (int)entity);
}
// Draw Circles
auto view = m_Registry.view<TransformComponent, CircleRendererComponent>();
for (auto entity : view)
{
auto [transform, circle] = view.get<TransformComponent, CircleRendererComponent>(entity);
// Renderer2D::DrawQuad(transform.GetTransform(), sprite.Color);
Renderer2D::DrawCircle(transform.GetTransform(), circle.Color, circle.Thickness, circle.Fade, (int)entity);
}
Renderer2D::EndScene();
}
}
@ -254,6 +285,7 @@ namespace Hazel
{
Renderer2D::BeginScene(camera);
// Draw Sprites
auto group = m_Registry.group<TransformComponent>(entt::get<SpriteRendererComponent>);
for (auto entity : group)
{
@ -263,6 +295,16 @@ namespace Hazel
Renderer2D::DrawSprite(transform.GetTransform(), sprite, (int)entity);
}
// Draw Circles
auto view = m_Registry.view<TransformComponent, CircleRendererComponent>();
for (auto entity : view)
{
auto [transform, circle] = view.get<TransformComponent, CircleRendererComponent>(entity);
// Renderer2D::DrawQuad(transform.GetTransform(), sprite.Color);
Renderer2D::DrawCircle(transform.GetTransform(), circle.Color, circle.Thickness, circle.Fade, (int)entity);
}
Renderer2D::EndScene();
}
@ -291,10 +333,12 @@ namespace Hazel
CopyComponentIfExists<TransformComponent>(newEntity, entity);
CopyComponentIfExists<SpriteRendererComponent>(newEntity, entity);
CopyComponentIfExists<CircleRendererComponent>(newEntity, entity);
CopyComponentIfExists<CameraComponent>(newEntity, entity);
CopyComponentIfExists<NativeScriptComponent>(newEntity, entity);
CopyComponentIfExists<RigidBody2DComponent>(newEntity, entity);
CopyComponentIfExists<BoxCollider2DComponent>(newEntity, entity);
CopyComponentIfExists<CircleCollider2DComponent>(newEntity, entity);
}
Entity Scene::GetPrimaryCameraEntity()
@ -336,6 +380,11 @@ namespace Hazel
{
}
template<>
void Scene::OnComponentAdded<CircleRendererComponent>(Entity entity, CircleRendererComponent& component)
{
}
template<>
void Scene::OnComponentAdded<TagComponent>(Entity entity, TagComponent& component)
{
@ -356,13 +405,20 @@ namespace Hazel
{
}
template<>
void Scene::OnComponentAdded<CircleCollider2DComponent>(Entity entity, CircleCollider2DComponent& component)
{
}
template HAZEL_API void Scene::OnComponentAdded<IDComponent>(Entity, IDComponent&);
template HAZEL_API void Scene::OnComponentAdded<TransformComponent>(Entity, TransformComponent&);
template HAZEL_API void Scene::OnComponentAdded<CameraComponent>(Entity, CameraComponent&);
template HAZEL_API void Scene::OnComponentAdded<TagComponent>(Entity, TagComponent&);
template HAZEL_API void Scene::OnComponentAdded<SpriteRendererComponent>(Entity, SpriteRendererComponent&);
template HAZEL_API void Scene::OnComponentAdded<CircleRendererComponent>(Entity, CircleRendererComponent&);
template HAZEL_API void Scene::OnComponentAdded<NativeScriptComponent>(Entity, NativeScriptComponent&);
template HAZEL_API void Scene::OnComponentAdded<RigidBody2DComponent>(Entity, RigidBody2DComponent&);
template HAZEL_API void Scene::OnComponentAdded<BoxCollider2DComponent>(Entity, BoxCollider2DComponent&);
template HAZEL_API void Scene::OnComponentAdded<CircleCollider2DComponent>(Entity, CircleCollider2DComponent&);
}

View File

@ -42,6 +42,12 @@ namespace Hazel
Entity GetPrimaryCameraEntity();
template<typename... Components>
auto GetAllEntitiesWith()
{
return m_Registry.view<Components...>();
}
private:
template<typename T>
void OnComponentAdded(Entity entity, T& component);

View File

@ -200,6 +200,19 @@ namespace Hazel
out << YAML::EndMap; // CameraComponent
}
if (entity.HasComponent<CircleRendererComponent>())
{
out << YAML::Key << "CircleRendererComponent";
out << YAML::BeginMap; // CircleRendererComponent
auto& circleRendererComponent = entity.GetComponent<CircleRendererComponent>();
out << YAML::Key << "Color" << YAML::Value << circleRendererComponent.Color;
out << YAML::Key << "Radius" << YAML::Value << circleRendererComponent.Radius;
out << YAML::Key << "Thickness" << YAML::Value << circleRendererComponent.Thickness;
out << YAML::Key << "Fade" << YAML::Value << circleRendererComponent.Fade;
out << YAML::EndMap; // CircleRendererComponent
}
if (entity.HasComponent<SpriteRendererComponent>())
{
out << YAML::Key << "SpriteRendererComponent";
@ -237,6 +250,22 @@ namespace Hazel
out << YAML::EndMap; // BoxCollider2DComponent
}
if (entity.HasComponent<CircleCollider2DComponent>())
{
out << YAML::Key << "CircleCollider2DComponent";
out << YAML::BeginMap; // CircleCollider2DComponent
auto& cc2dComponent = entity.GetComponent<CircleCollider2DComponent>();
out << YAML::Key << "Offset" << YAML::Value << cc2dComponent.Offset;
out << YAML::Key << "Radius" << YAML::Value << cc2dComponent.Radius;
out << YAML::Key << "Density" << YAML::Value << cc2dComponent.Density;
out << YAML::Key << "Friction" << YAML::Value << cc2dComponent.Friction;
out << YAML::Key << "Restitution" << YAML::Value << cc2dComponent.Restitution;
out << YAML::Key << "Restitution" << YAML::Value << cc2dComponent.Restitution;
out << YAML::Key << "RestitutionThreshold" << YAML::Value << cc2dComponent.RestitutionThreshold;
out << YAML::EndMap; // CircleCollider2DComponent
}
out << YAML::EndMap; // entity
}
@ -333,6 +362,16 @@ namespace Hazel
sprite.Color = spriteRendererComponent["Color"].as<glm::vec4>();
}
auto circleRendererComponent = entity["CircleRendererComponent"];
if (circleRendererComponent)
{
auto& circle = deserializedEntity.AddComponent<CircleRendererComponent>();
circle.Color = circleRendererComponent["Color"].as<glm::vec4>();
circle.Radius = circleRendererComponent["Radius"].as<float>();
circle.Thickness = circleRendererComponent["Thickness"].as<float>();
circle.Fade = circleRendererComponent["Fade"].as<float>();
}
auto rigidBody2DComponent = entity["RigidBody2DComponent"];
if (rigidBody2DComponent)
{
@ -353,6 +392,17 @@ namespace Hazel
bc2d.RestitutionThreshold = boxCollider2DComponent["RestitutionThreshold"].as<float>();
}
auto circleCollider2DComponent = entity["CircleCollider2DComponent"];
if (circleCollider2DComponent)
{
auto& cc2d = deserializedEntity.AddComponent<CircleCollider2DComponent>();
cc2d.Offset = circleCollider2DComponent["Offset"].as<glm::vec2>();
cc2d.Radius = circleCollider2DComponent["Radius"].as<float>();
cc2d.Density = circleCollider2DComponent["Density"].as<float>();
cc2d.Friction = circleCollider2DComponent["Friction"].as<float>();
cc2d.Restitution = circleCollider2DComponent["Restitution"].as<float>();
cc2d.RestitutionThreshold = circleCollider2DComponent["RestitutionThreshold"].as<float>();
}
}
}

View File

@ -4,8 +4,8 @@
#include "OpenGLRendererAPI.h"
#include <glad/glad.h>
#include <Hazel/Debug/Instrumentor.h>
#include <SDL3/SDL_opengl.h>
namespace Hazel
{
@ -14,6 +14,7 @@ namespace Hazel
HZ_PROFILE_FUNCTION();
glEnable(GL_BLEND);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LINE_SMOOTH);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
@ -40,7 +41,27 @@ namespace Hazel
count = indexCount;
else
count = vertexArray->GetIndexBuffer()->GetCount();
if (count <= 0)
return;
vertexArray->Bind();
glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_INT, nullptr);
glBindTexture(GL_TEXTURE_2D, 0);
}
void OpenGLRendererAPI::DrawLines(const std::shared_ptr<Hazel::VertexArray>& vertexArray, const uint32_t vertexCount)
{
uint32_t count;
if (vertexCount != -1)
count = vertexCount;
else
count = vertexArray->GetIndexBuffer()->GetCount();
if (count <= 0)
return;
vertexArray->Bind();
glDrawArrays(GL_LINES, 0, count);
}
void OpenGLRendererAPI::SetLineWidth(const float width)
{
glLineWidth(width);
}
}

View File

@ -17,6 +17,8 @@ namespace Hazel
virtual void SetViewPort(uint32_t x, uint32_t y, uint32_t width, uint32_t height) override;
virtual void Clear() override;
virtual void DrawIndexed(const std::shared_ptr<Hazel::VertexArray>& vertexArray, uint32_t indexCount = 0) override;
virtual void DrawLines(const std::shared_ptr<Hazel::VertexArray>& vertexArray, uint32_t vertexCount = 0) override;
virtual void SetLineWidth(float width) override;
};
}

View File

@ -130,7 +130,7 @@ namespace Hazel
auto shaderSources = PreProcess(shaderSrc);
Compile(shaderSources);
// example: /assets/shaders/Texture.glsl
// example: /assets/shaders/Renderer2D_quad.glsl
auto lastSlash = filepath.find_last_of("\\/");
auto lastDot = filepath.find_last_of(".");
m_Name = filepath.substr(lastSlash + 1, lastDot - lastSlash - 1);

View File

@ -0,0 +1,72 @@
// Basic circle Texture Shader
#type vertex
#version 450 core
layout(location = 0) in vec3 a_WorldPosition;
layout(location = 1) in vec3 a_LocalPosition;
layout(location = 2) in vec4 a_Color;
layout(location = 3) in float a_Thickness;
layout(location = 4) in float a_Fade;
layout(location = 5) in int a_EntityID;
layout(std140, binding = 0) uniform Camera
{
mat4 u_ViewProjection;
};
struct VertexOutput
{
vec3 LocalPosition;
vec4 Color;
float Thickness;
float Fade;
};
layout (location = 0) out VertexOutput Output;
layout (location = 4) out flat int v_EntityID;
void main()
{
Output.LocalPosition = a_LocalPosition;
Output.Color = a_Color;
Output.Thickness = a_Thickness;
Output.Fade = a_Fade;
v_EntityID = a_EntityID;
gl_Position = u_ViewProjection * vec4(a_WorldPosition, 1.0);
}
#type fragment
#version 450 core
layout(location = 0) out vec4 o_Color;
layout(location = 1) out int o_EntityID;
struct VertexOutput
{
vec3 LocalPosition;
vec4 Color;
float Thickness;
float Fade;
};
layout (location = 0) in VertexOutput Input;
layout (location = 4) in flat int v_EntityID;
void main()
{
float distance = 1.0f - length(Input.LocalPosition);
float circle = smoothstep(0.0f, Input.Fade, distance);
circle *= smoothstep(Input.Thickness + Input.Fade, Input.Thickness, distance);
if(circle == 0.0f)
discard;
o_Color = Input.Color;
o_Color.a *= circle;
o_EntityID = v_EntityID;
}

View File

@ -0,0 +1,49 @@
// Basic Line 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 int a_EntityID;
layout(std140, binding = 0) uniform Camera
{
mat4 u_ViewProjection;
};
struct VertexOutput
{
vec4 Color;
};
layout (location = 0) out VertexOutput Output;
layout (location = 1) out flat int v_EntityID;
void main()
{
Output.Color = a_Color;
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;
};
layout (location = 0) in VertexOutput Input;
layout (location = 1) in flat int v_EntityID;
void main()
{
o_Color = Input.Color;
o_EntityID = v_EntityID;
}

View File

@ -1,4 +1,4 @@
// Basic Texture Shader
// Basic quad Texture Shader
#type vertex
#version 450 core

View File

@ -96,7 +96,6 @@ namespace Hazel
break;
}
// Renderer2D::BeginScene(m_CameraController.GetCamera());
auto [mx, my] = ImGui::GetMousePos();
mx -= m_ViewPortBounds[0].x;
@ -104,8 +103,8 @@ namespace Hazel
const glm::vec2 viewPortSize = m_ViewPortBounds[1] - m_ViewPortBounds[0];
my = viewPortSize.y - my;
int mouseX = (int)mx;
int mouseY = (int)my;
const int mouseX = (int)mx;
const int mouseY = (int)my;
if (mouseX >= 0 && mouseY >= 0 && mouseX < m_ViewPortSize.x && mouseY < m_ViewPortSize.y)
{
@ -117,11 +116,54 @@ namespace Hazel
// 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_CheckerBoardTexture);
OnOverLayRender();
// Renderer2D::EndScene();
m_FrameBuffer->UnBind();
}
void EditorLayer::OnOverLayRender()
{
if (m_SceneState == SceneState::Play)
{
Entity camera = m_ActiveScene->GetPrimaryCameraEntity();
Renderer2D::BeginScene(camera.GetComponent<CameraComponent>().Camera, camera.GetComponent<TransformComponent>().GetTransform());
}else
{
Renderer2D::BeginScene(m_EditorCamera);
}
if (m_ShowPhysicsColliders)
{
// box collider
auto bcview = m_ActiveScene->GetAllEntitiesWith<TransformComponent, BoxCollider2DComponent>();
for (auto entity : bcview)
{
auto [tc, bc2D] = bcview.get<TransformComponent, BoxCollider2DComponent>(entity);
glm::vec3 translation = tc.Translation + glm::vec3(bc2D.Offset, 0.001f);
glm::vec3 scale = tc.Scale * glm::vec3(bc2D.Size * 2.0f, 1.0f);
glm::mat4 transform = glm::translate(glm::mat4(1.0f), translation) * glm::rotate(
glm::mat4(1.0f), tc.Rotation.z, glm::vec3(0.0f, 0.0f, 1.0f)) * glm::scale(glm::mat4(1.0f), scale);
Renderer2D::DrawRect(transform, glm::vec4(0.2, 1.0f, 0.2f, 1.0f));
}
// circle collider
auto ccview = m_ActiveScene->GetAllEntitiesWith<TransformComponent, CircleCollider2DComponent>();
for (auto entity : ccview)
{
auto [tc, cc2D] = ccview.get<TransformComponent, CircleCollider2DComponent>(entity);
glm::vec3 translation = tc.Translation + glm::vec3(cc2D.Offset, 0.001f);
glm::vec3 scale = tc.Scale * glm::vec3(cc2D.Radius * 2.0f);
glm::mat4 transform = glm::translate(glm::mat4(1.0f), translation) * glm::scale(glm::mat4(1.0f), scale);
Renderer2D::DrawCircle(transform, glm::vec4(0.2, 1.0f, 0.2f, 1.0f), Renderer2D::GetLineWidth() * 0.01f);
}
}
Renderer2D::EndScene();
}
void EditorLayer::OnImGuiRender()
{
static bool showDockspace = true;
@ -229,12 +271,25 @@ namespace Hazel
ImGui::Separator();
auto editorCameraPos = m_EditorCamera.GetPosition();
ImGui::Text("Editor Camera(%.3f, %.3f, %.3f)", editorCameraPos.x, editorCameraPos.y, editorCameraPos.z);
ImGui::Text("Editor Camera Distance: %f", m_EditorCamera.GetDistance());
float lineWidth = Renderer2D::GetLineWidth();
if (ImGui::DragFloat("LineWidth", &lineWidth, 0.01f, 0.0f, 10.0f))
{
Renderer2D::SetLineWidth(lineWidth);
}
// std::string name = "none";
// if (m_HoveredEntity)
// name = m_HoveredEntity.GetComponent<TagComponent>().Tag;
// ImGui::Text("Hovered Entity: %s", name.c_str());
ImGui::Separator();
ImGui::Checkbox("Show Colliders", &m_ShowPhysicsColliders);
ImGui::End();
}
@ -464,11 +519,12 @@ namespace Hazel
#define SHORTCUT_CTRL_D (SDL_KMOD_CTRL + SDLK_D)
if (e.key.down && e.key.repeat == 0)
{
const auto mod = SDL_GetModState();
const auto ctrl = (mod & SDL_KMOD_CTRL) ? SDL_KMOD_CTRL : 0;
const auto shift = (mod & SDL_KMOD_SHIFT) ? SDL_KMOD_SHIFT : 0;
if (e.key.down && e.key.repeat == 0)
{
switch (ctrl + shift + e.key.key)
{
case SHORTCUT_EXIT:
@ -539,7 +595,6 @@ namespace Hazel
}
ImGui::PopStyleVar(2);
ImGui::PopStyleColor(3);
ImGui::End();

View File

@ -41,6 +41,8 @@ namespace Hazel
void ChangeOptMode(unsigned int mode);
void OnOverLayRender();
private:
OrthographicCameraController m_CameraController;
@ -63,12 +65,15 @@ namespace Hazel
glm::vec2 m_ViewPortBounds[2];
Ref<FrameBuffer> m_FrameBuffer;
Ref<FrameBuffer> m_RuntimeFrameBuffer;
SceneHierachyPanel m_SceneHierachyPanel;
ContentBroswerPanel m_ContentBroswerPanel;
int m_GizmoType = -1;
bool m_ShowPhysicsColliders = false;
enum class SceneState
{
Edit = 0, Play = 1

View File

@ -265,13 +265,22 @@ namespace Hazel
if (!m_SelectionContext.HasComponent<SpriteRendererComponent>())
{
if (ImGui::MenuItem("Sprite"))
if (ImGui::MenuItem("Sprite Renderer"))
{
m_SelectionContext.AddComponent<SpriteRendererComponent>();
ImGui::CloseCurrentPopup();
}
}
if (!m_SelectionContext.HasComponent<CircleRendererComponent>())
{
if (ImGui::MenuItem("Circle Renderer"))
{
m_SelectionContext.AddComponent<CircleRendererComponent>();
ImGui::CloseCurrentPopup();
}
}
if (!m_SelectionContext.HasComponent<RigidBody2DComponent>())
{
if (ImGui::MenuItem("RigidBody 2D"))
@ -290,6 +299,15 @@ namespace Hazel
}
}
if (!m_SelectionContext.HasComponent<CircleCollider2DComponent>())
{
if (ImGui::MenuItem("Circle Collider 2D"))
{
m_SelectionContext.AddComponent<CircleCollider2DComponent>();
ImGui::CloseCurrentPopup();
}
}
ImGui::EndPopup();
}
ImGui::PopItemWidth();
@ -385,6 +403,13 @@ namespace Hazel
ImGui::DragFloat("Tiling Color", &component.TilingFactor, 0.1f, 0.0f, 100.f);
});
DrawComponent<CircleRendererComponent>("Circle Renderer", entity, [](auto& component)
{
ImGui::ColorEdit4("Color", glm::value_ptr(component.Color));
// ImGui::DragFloat("Radius", &component.Radius, 0.01f, 0.0f, 1.f);
ImGui::DragFloat("Thickness", &component.Thickness, 0.01f, 0.0f, 1.f);
ImGui::DragFloat("Fade", &component.Fade, 0.00001f, 0.0f, 1.f);
});
DrawComponent<RigidBody2DComponent>("Rigidbody 2D", entity, [](auto& component)
{
@ -415,8 +440,19 @@ namespace Hazel
DrawComponent<BoxCollider2DComponent>("Box Collider 2D", entity, [](auto& component)
{
ImGui::DragFloat2("Offset", glm::value_ptr(component.Offset));
ImGui::DragFloat2("Size", glm::value_ptr(component.Size));
ImGui::DragFloat2("Offset", glm::value_ptr(component.Offset), 0.001f);
ImGui::DragFloat2("Size", glm::value_ptr(component.Size), 0.001f);
ImGui::DragFloat("Density", &component.Density, 0.01f, 0.0f);
ImGui::DragFloat("Friction", &component.Friction, 0.01f, 0.0f, 1.0f);
ImGui::DragFloat("Restitution", &component.Restitution, 0.01f, 0.0f, 1.0f);
ImGui::DragFloat("Restitution Threshold", &component.RestitutionThreshold, 0.01f, 0.0f);
});
DrawComponent<CircleCollider2DComponent>("Circle Collider 2D", entity, [](auto& component)
{
ImGui::DragFloat2("Offset", glm::value_ptr(component.Offset), 0.001f);
ImGui::DragFloat("Radius", &component.Radius, 0.001f);
ImGui::DragFloat("Density", &component.Density, 0.01f, 0.0f);
ImGui::DragFloat("Friction", &component.Friction, 0.01f, 0.0f, 1.0f);

View File

@ -132,8 +132,8 @@ ExampleLayer::ExampleLayer() : Layer("ExampleLayer"), m_CameraController(1280.0f
// Texture.Shader
// m_TextureShader = Hazel::Shader::Create("assets/shaders/Texture.glsl");
auto textureShader = m_ShaderLibrary.Load("assets/shaders/Texture.glsl");
// m_TextureShader = Hazel::Shader::Create("assets/shaders/Renderer2D_quad.glsl");
auto textureShader = m_ShaderLibrary.Load("assets/shaders/Renderer2D_quad.glsl");
// Texture