- 작성한 코드

  • OpenGL에서 Vertex Buffer와 Index Buffer를 관리하는 Vertex Array 기능을 추상화. 
  • 두 개의 Vertex Array를 이용한 test code 작성

 

Vertex Array

// Vertex Array
std::shared_ptr<VertexArray> m_VertexArray.reset( VertexArray::Create() );

VertexArray는 OpenGL VertexArray의 기능에 초점을 맞춰서 추상화되었습니다.
VertexArray는 각각의 VertexBuffer 묶음과 IndexBuffer를 가리키는 포인터를 소유하고 있는 클래스입니다.
Normal Engine에서는 모든 리소스에 대한 개수를 관리하기 위해서 shared_ptr을 사용합니다.
위에처럼 Static Create 함수를 통해 관련 리소스를 생성할 수 있습니다.

 

Vertex Buffer와 Index Buffer를 Vertex Array에 등록하기

		// Vertex Buffer
		std::shared_ptr< VertexBuffer > vertexBuffer;
		vertexBuffer.reset( VertexBuffer::Create( vertices, sizeof( vertices ) ) );
        
		// Set Layout
		vertexBuffer->SetLayout( layout );

		// Index Buffer
		NRuint indexCount = sizeof( indices ) / sizeof( NRuint );
		std::shared_ptr<IndexBuffer> indexBuffer;
		indexBuffer.reset( IndexBuffer::Create( indices, indexCount ) );

		// Binding Vertex Buffer and Index Buffer in the Buffer Array
		m_VertexArray->AddVertexBuffer( vertexBuffer );
		m_VertexArray->SetIndexBuffer( indexBuffer );

Vertex Buffe와 Index Buffer를 각각 임의의 shared_ptr에 할당해준 후 AddVertexBuffer(), SetIndexBuffer() 함수에 각각 등록해줄 수 있습니다.

단, 주의할 점은 Vertex Buffer를 Vertex Array에 등록하기 전에 반드시 적절한 Layout을 생성하고 VertexBuffer에 바인딩 시켜주어야 합니다.  만약 Vertex Array에 등록하려는 Vertex Buffer에 적절한 Layout이 설정되어있지 않을 경우, 다음처럼 ASSERT에 걸리게 됩니다. (현재는 Debug 모드에서만 동작합니다.)

 

	void OpenGLVertexArray::AddVertexBuffer( const std::shared_ptr<VertexBuffer>& vertexBuffer )
	{
		glBindVertexArray( m_RenderID );
		vertexBuffer->Bind();

		const auto& BufferLayout = vertexBuffer->GetLayout();
		NR_CORE_ASSERT( BufferLayout.GetElementsSize(), "Vertex Buffer Has no layout!");
        
		...
	}

그리고 Layout은 굳이 각 VertexBuffer마다 따로 생성해서 사용할 필요는 없습니다.
만약 동일한 location과 속성을 가진 ShaderDataType을 사용하는 VertexBuffer일 경우는 동일한 Layout을 사용해도 무방합니다.
마찬가지 맥락으로 동일한 종류의 객체들을 여러개 만들어야할 상황에도 마찬가지로 VertexArray는 객체들 간에 공유가 가능합니다. 

 

Binding Vertex Array

	void Application::Run()
	{
		while ( m_Running )
		{
			glClearColor( 0.2f, 0.2f, 0.2f, 1.0f );
			glClear( GL_COLOR_BUFFER_BIT );

			m_SquareVertexArray->Bind();
			const auto& squareIndexBuffer = m_SquareVertexArray->GetIndexBuffer();
			glDrawElements( GL_TRIANGLES, squareIndexBuffer->GetIndexCount(), GL_UNSIGNED_INT, 0 );

			m_VertexArray->Bind();
			const auto& IndexBuffer = m_VertexArray->GetIndexBuffer();
			glDrawElements( GL_TRIANGLES, IndexBuffer->GetIndexCount(), GL_UNSIGNED_INT, 0 );

			....
		}
	}

다음처럼 glDrawElements에 각 인덱스 버퍼를 구성하는 원소들의 개수를 인자로 넣어서 순서에맞게 출력해주고 있습니다.
첫번째로 바인딩되는 Vertex Array는 사각형, 두번 째는 삼각형입니다.
glDrawElements는 직전에 바인딩된 VertexArray의 영향을 받으므로 Vertex Array의 바인딩 순서에 주의해야 합니다. ( 추후 그리기 관련 함수도 추상화될 예정입니다. )

 

출력 결과