add circle2d collider renderer, fixed a bug for renderer 2 value properties

This commit is contained in:
2026-01-20 02:04:16 +08:00
parent 323d646611
commit 2bfde2dfb0
5 changed files with 186 additions and 7 deletions

View File

@ -227,13 +227,25 @@ namespace Prism
if (selection.Entity.HasComponent<BoxCollider2DComponent>())
{
const auto& size = selection.Entity.GetComponent<BoxCollider2DComponent>().Size;
const auto& collider = selection.Entity.GetComponent<BoxCollider2DComponent>();
const auto& transform = selection.Entity.GetComponent<TransformComponent>();
Renderer::BeginRenderPass(SceneRenderer::GetFinalRenderPass(), false);
const auto viewProj = m_EditorCamera.GetViewProjection();
Renderer2D::BeginScene(viewProj, false);
Renderer2D::DrawRotatedQuad({ transform.Translation.x, transform.Translation.y }, size * 2.0f, transform.Rotation.z, { 1.0f, 0.0f, 1.0f, 1.0f });
Renderer2D::DrawRotatedRect({ transform.Translation.x + collider.Offset.x, transform.Translation.y + collider.Offset.y }, collider.Size * 2.0f, transform.Rotation.z, { 0.0f, 0.0f, 1.0f, 1.0f });
Renderer2D::EndScene();
Renderer::EndRenderPass();
}
if (selection.Entity.HasComponent<CircleCollider2DComponent>())
{
const auto& collider = selection.Entity.GetComponent<CircleCollider2DComponent>();
const TransformComponent& transform = selection.Entity.GetComponent<TransformComponent>();
Renderer::BeginRenderPass(SceneRenderer::GetFinalRenderPass(), false);
const auto viewProj = m_EditorCamera.GetViewProjection();
Renderer2D::BeginScene(viewProj, false);
Renderer2D::DrawCircle({ transform.Translation.x + collider.Offset.x, transform.Translation.y + collider.Offset.y}, collider.Radius, { 0.0f, 1.0f, 1.0f, 1.0f });
Renderer2D::EndScene();
Renderer::EndRenderPass();
}

View File

@ -0,0 +1,44 @@
// Basic Texture Shader
#type vertex
#version 430 core
layout(location = 0) in vec3 a_WorldPosition;
layout(location = 1) in float a_Thickness;
layout(location = 2) in vec2 a_LocalPosition;
layout(location = 3) in vec4 a_Color;
uniform mat4 u_ViewProjection;
out vec2 v_LocalPosition;
out float v_Thickness;
out vec4 v_Color;
void main()
{
v_LocalPosition = a_LocalPosition;
v_Thickness = a_Thickness;
v_Color = a_Color;
gl_Position = u_ViewProjection * vec4(a_WorldPosition, 1.0);
}
#type fragment
#version 430 core
layout(location = 0) out vec4 color;
in vec2 v_LocalPosition;
in float v_Thickness;
in vec4 v_Color;
void main()
{
float fade = 0.01;
float dist = sqrt(dot(v_LocalPosition, v_LocalPosition));
if (dist > 1.0 || dist < 1.0 - v_Thickness - fade)
discard;
float alpha = 1.0 - smoothstep(1.0f - fade, 1.0f, dist);
alpha *= smoothstep(1.0 - v_Thickness - fade, 1.0 - v_Thickness, dist);
color = v_Color;
color.a = alpha;
}

View File

@ -176,7 +176,7 @@ namespace Prism::UI {
s_IDBuffer[1] = '#';
memset(s_IDBuffer + 2, 0, 14);
snprintf(s_IDBuffer + 2, 14, "%x", s_Counter++);
if (ImGui::DragFloat3(s_IDBuffer, glm::value_ptr(value), delta))
if (ImGui::DragFloat2(s_IDBuffer, glm::value_ptr(value), delta))
modified = true;
ImGui::PopItemWidth();

View File

@ -26,6 +26,14 @@ namespace Prism
glm::vec4 Color;
};
struct CircleVertex
{
glm::vec3 WorldPosition;
float Thickness;
glm::vec2 LocalPosition;
glm::vec4 Color;
};
struct Renderer2DData
{
static constexpr uint32_t MaxQuads = 20000;
@ -65,6 +73,14 @@ namespace Prism
LineVertex* LineVertexBufferBase = nullptr;
LineVertex* LineVertexBufferPtr = nullptr;
// circles
Ref<Shader> CircleShader;
Ref<Pipeline> CirclePipeline;
Ref<VertexBuffer> CircleVertexBuffer;
uint32_t CircleIndexCount = 0;
CircleVertex* CircleVertexBufferBase = nullptr;
CircleVertex* CircleVertexBufferPtr = nullptr;
glm::mat4 CameraViewProj;
bool DepthTest = true;
@ -148,6 +164,22 @@ namespace Prism
s_Data.LineIndexBuffer = IndexBuffer::Create(lineIndices, s_Data.MaxLineIndices);
delete[] lineIndices;
}
{
s_Data.CircleShader = Shader::Create("assets/shaders/Renderer2D_Circle.glsl");
PipelineSpecification pipelineSpecification;
pipelineSpecification.Layout = {
{ ShaderDataType::Float3, "a_WorldPosition" },
{ ShaderDataType::Float, "a_Thickness" },
{ ShaderDataType::Float2, "a_LocalPosition" },
{ ShaderDataType::Float4, "a_Color" }
};
s_Data.CirclePipeline = Pipeline::Create(pipelineSpecification);
s_Data.CircleVertexBuffer = VertexBuffer::Create(s_Data.MaxVertices * sizeof(QuadVertex));
s_Data.CircleVertexBufferBase = new CircleVertex[s_Data.MaxVertices];
}
}
void Renderer2D::Shutdown()
@ -168,6 +200,9 @@ namespace Prism
s_Data.LineIndexCount = 0;
s_Data.LineVertexBufferPtr = s_Data.LineVertexBufferBase;
s_Data.CircleIndexCount = 0;
s_Data.CircleVertexBufferPtr = s_Data.CircleVertexBufferBase;
s_Data.TextureSlotIndex = 1;
}
@ -187,7 +222,7 @@ namespace Prism
s_Data.QuadVertexBuffer->Bind();
s_Data.QuadPipeline->Bind();
s_Data.QuadIndexBuffer->Bind();
Renderer::DrawIndexed(s_Data.QuadIndexCount, PrimitiveType::Triangles, false);
Renderer::DrawIndexed(s_Data.QuadIndexCount, PrimitiveType::Triangles, s_Data.DepthTest, false);
s_Data.Stats.DrawCalls++;
}
@ -203,7 +238,22 @@ namespace Prism
s_Data.LinePipeline->Bind();
s_Data.LineIndexBuffer->Bind();
Renderer::SetLineThickness(1.0f);
Renderer::DrawIndexed(s_Data.LineIndexCount, PrimitiveType::Lines, s_Data.DepthTest);
Renderer::DrawIndexed(s_Data.LineIndexCount, PrimitiveType::Lines, false, false);
s_Data.Stats.DrawCalls++;
}
dataSize = (uint8_t*)s_Data.CircleVertexBufferPtr - (uint8_t*)s_Data.CircleVertexBufferBase;
if (dataSize)
{
s_Data.CircleVertexBuffer->SetData(s_Data.CircleVertexBufferBase, dataSize);
s_Data.CircleShader->Bind();
s_Data.CircleShader->SetMat4("u_ViewProjection", s_Data.CameraViewProj);
s_Data.CircleVertexBuffer->Bind();
s_Data.CirclePipeline->Bind();
s_Data.QuadIndexBuffer->Bind();
Renderer::DrawIndexed(s_Data.CircleIndexCount, PrimitiveType::Triangles, false, false);
s_Data.Stats.DrawCalls++;
}
@ -449,6 +499,73 @@ namespace Prism
s_Data.Stats.QuadCount++;
}
void Renderer2D::DrawRotatedRect(const glm::vec2& position, const glm::vec2& size, float rotation, const glm::vec4& color)
{
DrawRotatedRect({ position.x, position.y, 0.0f }, size, rotation, color);
}
void Renderer2D::DrawRotatedRect(const glm::vec3& position, const glm::vec2& size, float rotation, const glm::vec4& color)
{
if (s_Data.LineIndexCount >= Renderer2DData::MaxLineIndices)
FlushAndResetLines();
const glm::mat4 transform = glm::translate(glm::mat4(1.0f), position) *
glm::rotate(glm::mat4(1.0f), rotation, { 0.0f, 0.0f, 1.0f }) *
glm::scale(glm::mat4(1.0f), { size.x, size.y, 1.0f });
const glm::vec3 positions[4] =
{
transform * s_Data.QuadVertexPositions[0],
transform * s_Data.QuadVertexPositions[1],
transform * s_Data.QuadVertexPositions[2],
transform * s_Data.QuadVertexPositions[3]
};
for (int i = 0; i < 4; i++)
{
const auto& v0 = positions[i];
const auto& v1 = positions[(i + 1) % 4];
s_Data.LineVertexBufferPtr->Position = v0;
s_Data.LineVertexBufferPtr->Color = color;
s_Data.LineVertexBufferPtr++;
s_Data.LineVertexBufferPtr->Position = v1;
s_Data.LineVertexBufferPtr->Color = color;
s_Data.LineVertexBufferPtr++;
s_Data.LineIndexCount += 2;
s_Data.Stats.LineCount++;
}
}
void Renderer2D::DrawCircle(const glm::vec2& position, float radius, const glm::vec4& color, float thickness)
{
DrawCircle({ position.x, position.y, 0.0f }, radius, color, thickness);
}
void Renderer2D::DrawCircle(const glm::vec3& position, float radius, const glm::vec4& color, float thickness)
{
if (s_Data.CircleIndexCount >= Renderer2DData::MaxIndices)
FlushAndReset();
const glm::mat4 transform = glm::translate(glm::mat4(1.0f), position) *
glm::scale(glm::mat4(1.0f), { radius * 2.0f, radius * 2.0f, 1.0f });
for (int i = 0; i < 4; i++)
{
s_Data.CircleVertexBufferPtr->WorldPosition = transform * s_Data.QuadVertexPositions[i];
s_Data.CircleVertexBufferPtr->Thickness = thickness;
s_Data.CircleVertexBufferPtr->LocalPosition = s_Data.QuadVertexPositions[i] * 2.0f;
s_Data.CircleVertexBufferPtr->Color = color;
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)
{
if (s_Data.LineIndexCount >= Renderer2DData::MaxLineIndices)

View File

@ -35,6 +35,12 @@ namespace Prism
static void DrawRotatedQuad(const glm::vec2& position, const glm::vec2& size, float rotation, const Ref<Texture2D>& texture, float tilingFactor = 1.0f, const glm::vec4& tintColor = glm::vec4(1.0f));
static void DrawRotatedQuad(const glm::vec3& position, const glm::vec2& size, float rotation, const Ref<Texture2D>& texture, float tilingFactor = 1.0f, const glm::vec4& tintColor = glm::vec4(1.0f));
static void DrawRotatedRect(const glm::vec2& position, const glm::vec2& size, float rotation, const glm::vec4& color);
static void DrawRotatedRect(const glm::vec3& position, const glm::vec2& size, float rotation, const glm::vec4& color);
static void DrawCircle(const glm::vec2& position, float radius, const glm::vec4& color, float thickness = 0.05f);
static void DrawCircle(const glm::vec3& position, float radius, const glm::vec4& color, float thickness = 0.05f);
static void DrawLine(const glm::vec3& p0, const glm::vec3& p1, const glm::vec4& color = glm::vec4(1.0f));
// Stats
struct Statistics
@ -43,8 +49,8 @@ namespace Prism
uint32_t QuadCount = 0;
uint32_t LineCount = 0;
uint32_t GetTotalVertexCount() { return QuadCount * 4 + LineCount * 2; }
uint32_t GetTotalIndexCount() { return QuadCount * 6 + LineCount * 2; }
uint32_t GetTotalVertexCount() const { return QuadCount * 4 + LineCount * 2; }
uint32_t GetTotalIndexCount() const { return QuadCount * 6 + LineCount * 2; }
};
static void ResetStats();
static Statistics GetStats();