본문 바로가기

게임엔진/크로스플랫폼 : HazelEngine

230520 자체 엔진 개발 : Stats

StartNewBatch

- BeginScene 함수 내부에 다시 DrawCall 관련 reset 코드가 들어있는데

문제는 인자로 카메라를 받아야 한다는 것이었다.

 

하지만 TextureShade 나 Matrix 를 Bind 를 다시 할 필요는 없으므로

필요한 부분만 StartNewBatch 라는 별도의 함수로 만든다,

 

https://github.com/ohbumjun/GameEngineTutorial/commit/2b5ab7bfe09a17f20df0282d5603753891d36922

 

feat(Engine) Add Stats related code to Renderer2D class · ohbumjun/GameEngineTutorial@2b5ab7b

ohbumjun committed Jun 8, 2023

github.com

 

현재 몇번의 DrawCall 이 있었는지, 몇개의 Geometry 를 그렸는지 등을 실시간으로 확인하고 싶을 수 있다.

따라서 관련 정보를 별도의 구조체로 만들고 이 정보를 Imgui 를 통해 그리고자 한다.

 

struct Statistics
{
    uint32_t DrawCalls = 0;
    uint32_t QuadCount = 0;

    uint32_t GetTotalVertexCount() { return QuadCount * 4; }
    uint32_t GetTotalIndexCount() { return QuadCount * 6; }
};

 

해당 정보는 Rendering 과 관련된 정보이므로 Renderer2D Class 에 배치할 것이다

기존의 Renderer2DData 구조체의 멤버 변수로 세팅하고

Renderer2DData 자체는 static 변수로 만들어서 Renderer2D Class 에서 보다 쉽게 접근하게 할 것이다.

struct Renderer2DData
{
    static const uint32_t MaxQuads    = 10000;
    static const uint32_t MaxVertices = MaxQuads * 4;
    static const uint32_t MaxIndices  = MaxQuads * 6;
    static const uint32_t MaxTextureSlots = 32; 

    Ref<VertexArray> QuadVertexArray;
    Ref<VertexBuffer> QuadVertexBuffer;
    Ref<Shader> TextureShader;
    Ref<Texture2D> WhiteTexture;

    // 총 몇개의 quad indice 가 그려지고 있는가
    // Quad 를 그릴 때마다 + 6 해줄 것이다.
    uint32_t QuadIndexCount = 0;

    // QuadVertex 들을 담은 배열.을 가리키는 포인터
    QuadVertex* QuadVertexBufferBase = nullptr;

    // QuadVertexBufferBase 라는 배열 내에서 각 원소를 순회하기 위한 포인터
    QuadVertex* QuadVertexBufferPtr = nullptr;

    std::array<Ref<Texture2D>, MaxTextureSlots> TextureSlots;
    uint32_t TextureSlotIndex = 1; // 0 : Default White Texture 로 세팅

    // mesh local pos
    glm::vec4 QuadVertexPositions[4];

    Renderer2D::Statistics stats;
};

static Renderer2DData s_Data;

그리고 우리가 보고자 하는 데이터에 대한 변화가 있을 때마다 아래와 같이 정보를 변경해준다.

 

void Renderer2D::Flush()
{
    HZ_PROFILE_FUNCTION();

    // 모든 Texture 를 한꺼번에 Bind 해야 한다.
    // 0 번째에 기본적으로 Binding 된 WhiteTexture 도 Bind 해줘야 한다.
    for (uint32_t i = 0; i < s_Data.TextureSlotIndex; ++i)
    {
        s_Data.TextureSlots[i]->Bind(i);
    }

    // Batch Rendering 의 경우, 한번의 DrawCall 을 한다.
    RenderCommand::DrawIndexed(s_Data.QuadVertexArray, s_Data.QuadIndexCount);

#if STATISTICS
    s_Data.stats.DrawCalls++;
#endif
}

그리고 위와 같이 관련정보를 최종적으로 update 하고 나서

Imgui 관련 정보를 그리는 OnImguiRender 함수에서 관련 정보를 Imgui 에 표시해주고자 한다.

 

void SandBox2D::OnImGuiRender()
{
	ImGui::Begin("Settings");

	auto stats = Hazel::Renderer2D::GetStats();
	ImGui::Text("Renderer2D Stats:");
	ImGui::Text("Draw Calls: %d", stats.DrawCalls);
	ImGui::Text("Quads: %d", stats.QuadCount);
	ImGui::Text("Vertices: %d", stats.GetTotalVertexCount());
	ImGui::Text("Indices: %d", stats.GetTotalIndexCount());

	ImGui::ColorEdit4("Square Color", glm::value_ptr(m_SquareColor));

	// uint32_t textureID = m_CheckerboardTexture->GetRendererID();
	// ImGui::Image((void*)textureID, ImVec2{ 256.0f, 256.0f });

	ImGui::End();
}