OpenGL es 2.0 几何实例化

发布于 2024-11-03 14:06:27 字数 760 浏览 1 评论 0原文

我有 170 个对象要绘制,每个对象都是由 312 个顶点构建的。 我有一个对象,我用不同的 martixes 绘制它 170 次,我发现如果我一个接一个地绘制它们,我不需要调用一些函数,所以我只在开始时调用它们,这给了我大约 5fps,我我正在使用带有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 下更快吗?我在 sgx 540 上得到大约 23fps, 将每个对象的顶点细节降低到 36 并不会增加帧速率,矩阵计算(缩放、乘法、平移、转调、反转)大约有 10fps,但它们是在 cpu 上制作的,我不认为将它们移动到着色器中是个好主意。我知道每次的大部分时间都花在了传递制服上。我知道有一种方法可以实例化对象并传递制服并在一次调用中绘制它,但我找不到任何描述它的教程,你知道我在哪里可以找到它吗?

i have 170 objects to draw, each is build from 312 vertexes.
I have one object and i am drawing it 170 times with diffrent martixes, i have figured out that i dont need to call some functions if i draw them one by one so i call them only at the begining, this gives me about 5fps, i am using non indexed triangles with 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)
}

Is there any way to make it faster under es 2.0 ? i am getting about 23fps on sgx 540,
lowering vertex detail to 36 per object does not increase frame rate, there are about 10fps in matrix calculations(scale, multiply, translate, transponse, invert) but they are made on cpu and i dont think that moving them into shaders is good idea. I know that most time is consumed on passing uniforms each time. I know that there is a way to instantiate objects and pass uniforms and draw it in one call but i cant find any tutorial describing it, do you know where i can find it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

难理解 2024-11-10 14:06:27

尝试将法线和顶点包含在一个数组中,如下所示:

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.

该书也有以这种方式使用的示例

try to inculde normals and vertices in one array like this:

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"));

In this example i have one array for vertices and tex coords

quot from OpenGL ES 2.0 Programming Guide:

 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.

That book also has examples of using in this manner

梅窗月明清似水 2024-11-10 14:06:27

您可以尝试通过属性而不是制服传递每个实例的数据。有时它对桌面 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( ... );
}

You can try passing your per-instance data through attributes instead of uniforms. It helped sometimes on desktop OpenGL.

So, vertex shader will look like this:

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

And rendering code will look like this:

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( ... );
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文