01 - Basic Block Rendering

Prologue가 매우 간략했습니다만.. 원래 이런 연재글은 짧게, 핵심적인 내용만 말을해야 됩니다.(절대 쓰기 귀찮아서가 아님)

Voxel Engine을 만들기에 앞서 가장 중점적으로 해야할 일은 block을 rendering할 수 있는 framework를 만드는 것입니다. 뭐.. 어느정도 프로그래밍을 해보신 분이라면 아주 쉽게 접근하실 수 있는 부분이지만 이 글은 초보를 위한 글이므로 사실 나도 잘 모름 기초부터 차근차근 설명해 나가겠습니다.

(아래의 코드들은 Opengl 코드 입니다. 아이디어만 뽑아 내면 됩니다. Directx도 가능)



A single cube

처음으로 해볼 것은 그냥 일반적인 정육면체, Cube를 그려보는 것입니다.



float l_length = 1.0f;
float l_height = 1.0f;
float l_width = 1.0f;

Vector3d blockPosition(0.0f, 0.0f, 0.0f);

pRenderer->PushMatrix();
pRenderer->TranslateWorldMatrix(blockPosition.x, blockPosition.y, blockPosition.z);
pRenderer->SetRenderMode(RM_SOLID);
pRenderer->EnableImmediateMode(IM_QUADS);
pRenderer->ImmediateColourAlpha(1.0f, 1.0f, 1.0f, 1.0f);
pRenderer->ImmediateNormal(0.0f, 0.0f, -1.0f);
pRenderer->ImmediateVertex(l_length, -l_height, -l_width);
pRenderer->ImmediateVertex(-l_length, -l_height, -l_width);
pRenderer->ImmediateVertex(-l_length, l_height, -l_width);
pRenderer->ImmediateVertex(l_length, l_height, -l_width);

pRenderer->ImmediateNormal(0.0f, 0.0f, 1.0f);
pRenderer->ImmediateVertex(-l_length, -l_height, l_width);
pRenderer->ImmediateVertex(l_length, -l_height, l_width);
pRenderer->ImmediateVertex(l_length, l_height, l_width);
pRenderer->ImmediateVertex(-l_length, l_height, l_width);

pRenderer->ImmediateNormal(1.0f, 0.0f, 0.0f);
pRenderer->ImmediateVertex(l_length, -l_height, l_width);
pRenderer->ImmediateVertex(l_length, -l_height, -l_width);
pRenderer->ImmediateVertex(l_length, l_height, -l_width);
pRenderer->ImmediateVertex(l_length, l_height, l_width);

pRenderer->ImmediateNormal(-1.0f, 0.0f, 0.0f);
pRenderer->ImmediateVertex(-l_length, -l_height, -l_width);
pRenderer->ImmediateVertex(-l_length, -l_height, l_width);
pRenderer->ImmediateVertex(-l_length, l_height, l_width);
pRenderer->ImmediateVertex(-l_length, l_height, -l_width);

pRenderer->ImmediateNormal(0.0f, -1.0f, 0.0f);
pRenderer->ImmediateVertex(-l_length, -l_height, -l_width);
pRenderer->ImmediateVertex(l_length, -l_height, -l_width);
pRenderer->ImmediateVertex(l_length, -l_height, l_width);
pRenderer->ImmediateVertex(-l_length, -l_height, l_width);

pRenderer->ImmediateNormal(0.0f, 1.0f, 0.0f);
pRenderer->ImmediateVertex(l_length, l_height, -l_width);
pRenderer->ImmediateVertex(-l_length, l_height, -l_width);
pRenderer->ImmediateVertex(-l_length, l_height, l_width);
pRenderer->ImmediateVertex(l_length, l_height, l_width);
pRenderer->DisableImmediateMode();
pRenderer->PopMatrix();



출처 Voxel 사이트

뭐 위의 코드를 요약해보자면 그겁니다. "Cube 그리자" 누구나 할 수 있는 간단한 코드입니다. 왜 이렇게 쉬운거 한거냐??  장애인인지 아닌지 판단해보고자 해본겁니다. ㅋㅋ 신기한 것은 이렇게 간단한 Cube하나 부터 시작하는데 나중에 최종 엔진을 완성할 쯤 되면 여러분은 아래와 같은 엄청난 world 를 만들수 있는 게임 엔진을 만들게 될겁니다. 그냥 나만 따라오면 다댄당께. 알겟?

voxel을 사용한 game world - 출처 igmur

A Multiple cube

가장 기초적인 Cube를 그려보았으니 이제는 나아가서 여러개의 Cube들을 그려보도록 합시다. Voxel Engine이라는게 쉽게 말하면 Cube를 쉽게 rendering해주는 tool이라고 생각하면 됩니다.

가장 쉽게 멍청하게 생각해보면 block structure을 만든 뒤 position component를 추가한 후 이것을 list로 만들어 가지고 있다가 rendering loop가 돌 때 list를 하나씩 읽어 나가면서 한 개 씩 위치에 따라 rendering 하는 방법이 있습니다. 음.. 개인적으로는 block structure에다가 position을 추가하고 싶지는 않습니다. 조금만 더 뒤에 나올 내용이긴 하지만 block structure은 매우 다양한 component를 가질 것이기 때문에 block structure 자체에는 최소한의 내용을 가지도록 하는 것이 좋습니다.

예를 들어, 아래와 같은 block이 있다고 하면

Block* m_pBlocks[32][32][32]

block에서 x, y, z를 사용하여 아래처럼 rendering하는 방법이 있습니다.

for(int x = 0; x < 32; x++) {
     for(int y = 0; y < 32; y++) {
          for(int z = 0; z < 32; z++) { pRenderer->TranslateWorldMatrix(x, y, z);
          // Render m_pBlocks[x][y][z]
          }
     }
}

비슷한 아이디어를 사용하면 1x1x1 짜리 Cube를 그릴수 있고 아래와 같이 하면 임의의 Cube를 그릴수도 있게 됩니다.

TranslateWorldMatrix(x*Block::BLOCK_RENDER_SIZE, y*Block::BLOCK_RENDER_SIZE, z*Block::BLOCK_RENDER_SIZE);


출처 Voxel 사이트
시작은 정말 쉽죠? 그냥 Cube를 그릴 줄 알면 절반은 끝나는 겁니다. 

다음 article은 block information으로 사용될 것들과 각 voxel들이 load/save해야 할 내용들에 대해서 알아보겠습니다.

SHARE

관리자는

우리끼리 맘대로 사용하려고 만든 사이트입니다. 아무거나 올려도 댐!

  • Image
  • Image
  • Image
  • Image
  • Image
    Blogger Comment
    Facebook Comment

0 개의 댓글:

댓글 쓰기