A maneira mais rápida de desenhar quads no OpenGL ES?

22

Estou usando o OpenGL ES 2.0. Tenho um monte de quads para desenhar, gostaria de poder passar apenas 4 vértices por quad como se estivesse usando GL_QUADS, mas basicamente só quero saber a melhor maneira de desenhar um monte de quads separados.

Até agora, o que descobri que eu poderia fazer: -GL_TRIANGLES (6 vértices por quadrilátero) -Generar GL_TRIANGLE_STRIP (6 vértices por quadrilátero)

Possibilidades que encontrei: -GL_TRIANGLE_STRIPS com um valor de índice especial que redefine a faixa quádrupla (isso significaria 5 índices por quad, mas acho que isso não é possível é o OpenGL ES 2.0)

Jonathan
fonte

Respostas:

33

Basta usar o buffer de índice e GL_TRIANGLES. Nesse caso, você precisa de 4 vértices + 6 índices por quádruplo (6 índices adicionais podem parecer muito altos, mas, na realidade, não é - uma vez que você construiu seu buffer de índice, não precisa tocá-lo novamente). Veja esta página para mais informações (pesquise glDrawElements)

Código de exemplo simples:

GLfloat vertices[] = {-1, -1, 0, // bottom left corner
                      -1,  1, 0, // top left corner
                       1,  1, 0, // top right corner
                       1, -1, 0}; // bottom right corner

GLubyte indices[] = {0,1,2, // first triangle (bottom left - top left - top right)
                     0,2,3}; // second triangle (bottom left - top right - bottom right)

glVertexPointer(3, GL_FLOAT, 0, vertices);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices);

Além disso, se você estiver desenhando apenas um quad, precisará de apenas 4 vértices para desenhá-lo com tiras de triângulo ( como mostrado na wikipedia ), mas acho que você já sabia disso.

user4241
fonte
O truque tradicional para mesclar várias tiras de triângulo em uma única faixa é "triângulos degenerados": repetir o último elemento de uma faixa e o primeiro elemento da próxima faixa cria 2 triângulos com área zero, que não atraem nada. Considere os segundos índices quad (4, 5, 6, 7). O buffer de índice para GL_TRIANGLE_STRIP de dois quadriláteros pode ser: {0, 1, 2, 3, 3, 4,4, 5, 6, 7}. Os triângulos degenerados são 3,3,4e 3,4,4. Vale a pena fazer isso? Não, a menos que seus quadríceps tendam a aparecer em pares (ou mais) com arestas comuns. Se o 2º quad é {3, 2, 4, 5}, a tira é {0,1,3,2,5,4}.
Página Inicial>
8
E para deixar isso claro para quem vem e precisa desenhar um monte de quads: Por uma questão de desempenho, NÃO copie o código acima e faça uma chamada glDrawElements UMA VEZ PARA CADA QUAD . Em vez disso, crie UMA matriz de vértices e UMA matriz de índices que inclua TODOS os quadríceps que você deseja desenhar. Usando GL_TRIANGLES, dois quads podem ter índices {0,1,2, 0,2,3, 4,5,6, 4,6,7}ou é igualmente bom {0,1,2, 2,3,0, 4,5,6, 6,7,4}. Boa classe para ajudar este é glText-Android / SpriteBatch
ToolmakerSteve
6

O uso de buffers de índice não é necessariamente mais rápido, conforme indicado nos documentos da Apple: "Para obter o melhor desempenho, seus modelos devem ser enviados como uma única faixa triangular não indexada usando glDrawArrays" .

Portanto, embora a GL_TRIANGLE_STRIPa faça em 4 vértices sem a necessidade de um buffer de índice, e você possa usar um buffer de índice, é muito ruim tentar "salvar" a repetição de 2 vértices . Por esse motivo, sugiro que você desenhe 2 separados GL_TRIANGLESe repita os 2 vértices na diagonal .

bobobobo
fonte
8
Hum, não. O que esse documento diz é que seus modelos sejam enviados como uma única faixa triangular INDEXED. E a próxima frase é: "Para evitar especificar dados para o mesmo vértice várias vezes no buffer de vértice, use um buffer de índice separado e desenhe a faixa triangular usando a função glDrawElements". Foi exatamente o que você decidiu que era 'coxo'.
Davidf2281
3
Dado que o parágrafo doc agora se refere a glDrawElements em vez de glDrawArrays, provavelmente foi reescrito desde essa resposta. No entanto, o argumento do documento era que, para o desempenho, forneça uma única faixa (em vez de várias faixas, portanto várias chamadas gl). Nesta situação, acredito que a diferença entre usar índices ou não é insignificante ; o que importa é colocar tudo em uma única matriz de vértice (mais uma matriz de índice opcional), para que você possa fazer uma única chamada gl.
Home
0

O grande ganho na área de trabalho é mover os dados para os VBOs GL_STATIC_DRAW. Presumivelmente, isso também é verdade na GPU MBX do iPhone.

Vai
fonte
-2

Usar GL_TRIANGLE_FANpara um quad usa 4 vértices, não 6.

Mr. Blah
fonte
Sim, mas também GL_TRIANGLE_STRIP, como outras respostas já apontaram.
Anko
@Sr. Blah - Você perdeu o objetivo da pergunta, que é como fazer eficientemente um monte de quadriláteros. Não se deve fazer uma chamada gl para cada quad, mas sim combinar muitos quads em uma única matriz, que pode ser desenhada com uma única chamada gl. GL_TRIANGLE_FAN não ajudará com isso, portanto, raramente é útil na renderização de alto desempenho.
Página Inicial>