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

230518 자체 엔진 개발 : Batch Rendering (Rotated Texture)

mrawesome 2023. 6. 7. 23:32

https://github.com/ohbumjun/GameEngineTutorial/commit/83d0c39c858c040523c6ce84aed6511c30ab96a7

 

이번에는 Texture 를 BatchRendering 방식으로 그리되, Texture 또한 Rotate 시켜주고 싶다.

원리는 간단하다.

cpu 측에서 transform 계산해서 그 정보를 GPU 측에 넘겨주면 된다.

 

struct Renderer2DData
{
    // mesh local pos
    glm::vec4 QuadVertexPositions[4];
};

// Scene Initialize
s_Data.QuadVertexPositions[0] = { -0.5f, -0.5f, 0.f, 1.f };
s_Data.QuadVertexPositions[1] = {  0.5f, -0.5f, 0.f, 1.f };
s_Data.QuadVertexPositions[2] = {  0.5f,  0.5f, 0.f, 1.f };
s_Data.QuadVertexPositions[3] = { -0.5f,  0.5f, 0.f, 1.f };

Local Pos * World Matrix * View Matrix * Projection Matrix

이러한 순서로 값을 곱해주어야만 한다.

 

void Renderer2D::DrawRotatedQuad(const glm::vec3& pos, const glm::vec2& size, float rotation, const glm::vec4& color)
{
    glm::mat4 transform = glm::translate(glm::mat4(1.0f), pos)
        * glm::rotate(glm::mat4(1.f), glm::radians(rotation), { 0.f, 0.f, 1.f }) // z 축 회전
        * glm::scale(glm::mat4(1.f), { size.x, size.y, 1.f });

    const float texIndex = 0.f; // white texture
    const float tilingFactor = 1.f;

    // 시계 방향으로 4개의 정점 정보를 모두 세팅한다.
    // 왼쪽 아래
    s_Data.QuadVertexBufferPtr->Position = transform * s_Data.QuadVertexPositions[0];
    
    ...
    ...
    ...
}

그리고 "DrawRotatedQuad" 함수를 호출할 때 넘겨준  transform 관련 정보들로

"World Matrix" 를 구하고

각각의 정점 정보에 Local Pos * World Matrix 곱한 값을 세팅해준다.

 

#type vertex
#version 330 core
			
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;

uniform mat4 u_ViewProjection;
uniform mat4 u_Transform;

out vec4 v_Color;
out vec2 v_TexCoord;
out float v_TexIndex;
out float v_TilingFactor;

void main()
{
	v_Color      = a_Color;
	v_TexCoord = a_TexCoord;
	v_TexIndex = a_TexIndex;
	v_TilingFactor = a_TilingFactor;

	// 단일 DrawCall
	// gl_Position = u_ViewProjection * u_Transform * vec4(a_Position, 1.0);	

	gl_Position = u_ViewProjection * vec4(a_Position, 1.0);	
}

그러고 나면, 위와 같이 GPU 측에서는 a_Position 이라는 값이 Local Pos * World Matrix 값.

즉, World 공간에서의 위치가 될 것이다.