OpenGl es 2.0 Создание геометрии - PullRequest
6 голосов
/ 25 апреля 2011

У меня есть 170 объектов для рисования, каждый из которых состоит из 312 вершин.У меня есть один объект, и я рисую его 170 раз с разными мартиксами, я понял, что мне не нужно вызывать некоторые функции, если я рисую их одну за другой, поэтому я вызываю их только в начале, это дает мне около 5 кадров в секунду, яЯ использую неиндексированные треугольники с drawArrays.

if(!started)
{
    glUseProgram( __programObject );
    glEnableVertexAttribArray(attPosition);
    glVertexAttribPointer(attPosition, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), vVertices);//3*sizeof(float)
    glEnableVertexAttribArray(attNormals);
    glVertexAttribPointer(attNormals, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), vNormals);//3*sizeof(float)
}

Есть ли способ сделать это быстрее под es 2.0?Я получаю около 23 кадров в секунду на sgx 540, снижение детализации вершин до 36 на объект не увеличивает частоту кадров, в матричных вычислениях (масштабирование, умножение, преобразование, преобразование, инвертирование) примерно 10 кадров в секунду, но они сделаны на процессоре, и я не думаю, чточто их перемещение в шейдеры - хорошая идея.Я знаю, что больше всего времени уходит на прохождение униформы каждый раз.Я знаю, что есть способ создать объекты и передать униформу и нарисовать ее одним вызовом, но я не могу найти учебник, описывающий его, вы знаете, где я могу его найти?

Ответы [ 2 ]

3 голосов
/ 26 апреля 2011

попытаться внедрить нормали и вершины в один массив следующим образом:

sqTex.getVertexBuffer().position(sqTex.VERT_OFFSET);
GLES20.glVertexAttribPointer(
                                GLES20.glGetAttribLocation(programTextured, "aPosition"), 3,
                                GLES20.GL_FLOAT, false, 5 * 4, sqTex.getVertexBuffer());
GLES20.glEnableVertexAttribArray(GLES20.glGetAttribLocation(programTextured, "aPosition"));

sqTex.getVertexBuffer().position(sqTex.TEXT_OFFSET);
GLES20.glVertexAttribPointer(
                                GLES20.glGetAttribLocation(programTextured, "aTextureCoord"), 2,
                                GLES20.GL_FLOAT, false, 5 * 4, sqTex.getVertexBuffer());
GLES20.glEnableVertexAttribArray(GLES20.glGetAttribLocation(programTextured, "aTextureCoord"));

В этом примере у меня есть один массив для вершин и текстовых координат

цитата из Руководства по программированию OpenGL ES 2.0:

 How to store different attributes of a vertex
We described the two most common ways of storing vertex attributes—
array of structures and structure of arrays. The question to ask is which allocation
method would be the most efficient for OpenGL ES 2.0 hardware
implementations. The answer is array of structures. The reason is that the
attribute data for each vertex can be read in sequential fashion and so will
most likely result in an efficient memory access pattern. A disadvantage of
using array of structures is when an application wants to modify specific
attributes. If a subset of vertex attribute data needs to be modified (e.g., texture
coordinates), this will result in strided updates to the vertex buffer.
When vertex buffer is supplied as a buffer object, the entire vertex attribute
buffer will need to be reloaded. One can avoid this inefficiency by storing
vertex attributes that are dynamic in nature in a separate buffer.

В этой книге также есть примеры использования таким образом

1 голос
/ 20 июля 2011

Вы можете попробовать передать данные для каждого экземпляра через атрибуты вместо униформ. Помогло иногда на десктопе OpenGL.

Итак, вершинный шейдер будет выглядеть так:

attribute vec3 position;
attribute mat4 proj_view_matrix;
void main()
{
    gl_Position = proj_view_matrix * position;
}

И код рендеринга будет выглядеть так:

glUseProgram( programObject );
glEnableVertexAttribArray(attPosition);
glVertexAttribPointer(attPosition, ..., pPositions);
glDisableVertexAttribArray(attProjViewMatrix+0);
glDisableVertexAttribArray(attProjViewMatrix+1);
glDisableVertexAttribArray(attProjViewMatrix+2);
glDisableVertexAttribArray(attProjViewMatrix+3);

foreach( instance )
{
    glVertexAttrib4fv(attProjViewMatrix+0, instance.proj_view_matrix.column0);
    glVertexAttrib4fv(attProjViewMatrix+1, instance.proj_view_matrix.column1);
    glVertexAttrib4fv(attProjViewMatrix+2, instance.proj_view_matrix.column2);
    glVertexAttrib4fv(attProjViewMatrix+3, instance.proj_view_matrix.column3);
    glDrawArrays( ... );
}
...