GLSL Shader记录实体ID¶
这是最核心的地方,在绘制的时候用shader记录实体
Vertex¶
layout(location = 0) in vec3 a_Position;
layout(location = 1) in vec4 a_Color;
layout(location = 2) in vec2 a_TexCoord;
layout(location = 3) in float a_TexIndex;
layout(location = 4) in float a_TilingFactor;
layout(location = 5) in int a_EntityID;
uniform mat4 u_ViewProjection;
out vec4 v_Color;
out vec2 v_TexCoord;
out flat float v_TexIndex;
out float v_TilingFactor;
out flat int v_EntityID;
void main()
{
v_Color = a_Color;
v_TexCoord = a_TexCoord;
v_TexIndex = a_TexIndex;
v_TilingFactor = a_TilingFactor;
v_EntityID = a_EntityID;
gl_Position = u_ViewProjection * vec4(a_Position, 1.0);
}
Fragment¶
还是输出两个值,然后把之前的50换成对应的entityID
#type fragment
#version 450
layout(location = 0) out vec4 color;
layout(location = 1) out int color2;
in vec4 v_Color;
in vec2 v_TexCoord;
in flat float v_TexIndex;
in float v_TilingFactor;
in flat int v_EntityID;
uniform sampler2D u_Textures[32];
void main()
{
vec4 texColor = v_Color;
....
color = texColor;
color2 = v_EntityID;
}
渲染器:¶
先给每个绘制函数赋予一个实体ID(默认-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), int entityID = -1);
再加一个DrawSprite¶
根据spriteRenderer的Component进行绘制
static void DrawSprite(const glm::mat4& transform, SpriteRendererComponent& src, int entityID);
结构变化¶
主要还是新增entityid带来的变化
struct QuadVertex
{
glm::vec3 Position;
glm::vec4 Color;
glm::vec2 TexCoord;
float TexIndex;
float TilingFactor;
// Editor-only
int EntityID;
};
Vertexbuffer
void Renderer2D::Init()
{
CD_PROFILE_FUNCTION();
s_Data.QuadVertexArray = VertexArray::Create();
s_Data.QuadVertexBuffer = VertexBuffer::Create(s_Data.MaxVertices * sizeof(QuadVertex));
s_Data.QuadVertexBuffer->SetLayout({
{ ShaderDataType::Float3, "a_Position" },
{ ShaderDataType::Float4, "a_Color" },
{ ShaderDataType::Float2, "a_TexCoord" },
{ ShaderDataType::Float, "a_TexIndex" },
{ ShaderDataType::Float, "a_TilingFactor" },
{ ShaderDataType::Int, "a_EntityID" }
});
Scene绘制¶
在更新绘制的时候,需要把实体id传入
void Scene::OnUpdateEditor(Timestep ts, EditorCamera& camera)
{
Renderer2D::BeginScene(camera);
auto group = m_Registry.group<TransformComponent>(entt::get<SpriteRendererComponent>);
for (auto entity : group)
{
auto [transform, sprite] = group.get<TransformComponent, SpriteRendererComponent>(entity);
Renderer2D::DrawSprite(transform.GetTransform(), sprite, (int)entity);
}
Renderer2D::EndScene();
}
Editor Layer¶
新增悬停实体¶
Entity m_HoveredEntity;
每帧判断鼠标悬停实体,并赋予到悬停实体¶
由于是两个引用来构造赋值,不会创建新的空间,不需要new
if (mouseX >= 0 && mouseY >= 0 && mouseX < (int)viewportSize.x && mouseY < (int)viewportSize.y)
{
int pixelData = m_Framebuffer->ReadPixel(1, mouseX, mouseY);
m_HoveredEntity = pixelData == -1 ? Entity() : Entity((entt::entity)pixelData, m_ActiveScene.get());
}
拿到悬停石头后,我们通过Tag组件,将名字显示出来
ImGui::Text("Hovered Entity: %s", name.c_str());