terça-feira, agosto 28, 2012

Mapeamento de malha de terreno em Vertex Buffer Object


Para gerar o terreno criei uma malha  de vetores de n * n, cada item da matriz representa um quadrado formado por dois trianglos, então no caso de uma matriz de 32 x 32, teremos 2.048 trianglos, 4096 vértices (x,y,z), 6.144 índices (i) e 6.144 coordenadas de textura (u,v).

Este primeiro é responsável por preparar a malha de terreno, aqui é o ponto ideal para criar montanhas e crateras através do eixo z
                numIndexs = (height * width * 6);
                        numVecs = (height * width * 4);
                        vecs = new vec3d[numVecs];
                        texCoord = new TexCoord2[numVecs];
                        indexs = new dTriIndex[numVecs];
                      for (int y=0; y< h; y++)
                         for (int x=0; x< w; x++)
                        {
                         int offset = w*y+x;
                         vecs[offset].x = (x*scale);
                         vecs[offset].y = (y*scale);
                        vecs[offset].z = 0.0f;
                        }

Depois de preparada a malha com todas as suas depressões e montanhas, mapeamos os índices do terreno como percebeu o numero de índice é bem maior que o número de vértices isto porque eles são compartilhados entre os trianglos assim não repetimos um vértice que tem as mesmas coordenadas.


 int nIndex = 0;       
 for(int y=0; y
        for(int x=0; x
        {
            //a
            int  a = w*y+x;
            //b
            int  b = w*y+(x+1);
            //c
            int   c = w*(y+1)+(x+1);
            //d
            int d = w*(y+1)+x;

            //Triangulo 1
            indexs[nIndex] = a;
            nIndex++;

            indexs[nIndex] = b;
            nIndex++;

            indexs[nIndex] = c;
            nIndex++;

            //Triangulo 2
            indexs[nIndex] = c;
            nIndex++;

            indexs[nIndex] = d;
            nIndex++;

            indexs[nIndex] = a;
            nIndex++;
    }




 O desenho é feito através de um VertexBufferObject herdado da classe Mesh as texturas também estão armazenadas no Mesh e por final a classe Terrain que contém as características do terreno e a implementação dos algoritmos de carga das informações dos vértices, texturas e índices (blocos acima).



Depois de mapeado copio os buffers para a memória do hardware através da classe quem implementa o VBO
vbo = new VertexBufferObject();
vbo->glMode = GL_TRIANGLES;

 vbo->setVertices(vecs,numVecs);
 vbo->setIndexs(indexs,numIndexs);
 vbo->setTexCoords(texCoord,numIndexs);

Por fim no método Draw, faço a render do terreno.

    glPushMatrix();
    glMatrixMode(GL_MODELVIEW);
    glTranslatef(iPosition.x,iPosition.y,iPosition.z);
    //Draw Here
    texture->begin();
    vbo->draw();
   texture->end();
   glPopMatrix();

Este foi um terreno de 32x32 a ideia agora é criar terrenos de até 2048x2048, para isso vou precisar dividir o terreno em várias partes menores e só deixar na memória as partes que estão sendo visualizadas pelo ator, além de possibilitar multi textura é um grande desafio pela frente.



Sem comentários: