2014-06-09 85 views
1

我正在使用OpenGL,glew和GLFW为一个项目编写简单的游戏。我已经有一个使用Assimp的3D模型导入器,它也处理纹理。OpenGL批处理渲染网格

这是正路我画一个网格:

glBindBuffer(GL_ARRAY_BUFFER, m_Buffers[NORMAL_VB]); 
    glNormalPointer(GL_FLOAT, 0, NULL); 

    glBindBuffer(GL_ARRAY_BUFFER, m_Buffers[TEXCOORD_VB]); 
    glTexCoordPointer(2, GL_FLOAT, 0, NULL); 

    glBindBuffer(GL_ARRAY_BUFFER, m_Buffers[POS_VB]); 
    glVertexPointer(3, GL_FLOAT, 0, NULL); 

    //Render the triangles 
    glDrawArrays(GL_TRIANGLES, 0, m_Entries[i].NumIndices); 

我的问题是如何来报效百使用相同的网格移动实体,但每个人都有一个不同的世界位置和旋转?

如果我有数百个移动实体,每个帧我都会渲染相同的网格数百次,现在我可以注意到FPS的下降。

顺便说一句,我没有使用着色器,只是简单的画

+3

这是顶点着色器和实例化的目的。问题在于你正在使用'glVertexPointer(...)'等。我真的不知道你使用的是什么版本的GL;实例化在GL 3.1中被提升为核心,但是这个代码可能与GL 1.5一样久远。你能提一下你用什么版本的GL来简化答案吗? –

+0

@ AndonM.Coleman,其实我真的不知道我使用的是什么版本,但它可能是最后一个,我不知道 – andrepcg

+0

@ AndonM.Coleman,我仍然使用很多旧的和不赞成使用的函数 – andrepcg

回答

2

由于glVertexPointer()(和其他gl<Foo>Pointer()呼叫)在OpenGL 3已被取消,后来,我假设您目前没有使用一个OpenGL 3+核心配置文件。

实例化渲染有两种方法可能可用,都通过扩展提供; ARB_Draw_InstancedARB_Instanced_Arrays。无论是,或者两者都不可用于任何特定的卡/驱动程序。

ARB_Draw_Instanced提供glDrawArraysInstancedARB(),其工作基本上像你已经使用了glDrawArrays通话,而且还提供了gl_InstanceId整型变量用于着色器,然后你可以用它来读取矩阵或任何其他每个实例您需要从UBO,TBO或您希望用于将每个实例数据导入着色器的任何其他机制获取数据。理论上,这个扩展可以在OpenGL 1.1的早期版本中提供。

ARB_Instanced_Arrays提供glVertexAttribDivisorARB(),它允许您修改特定顶点属性的工作方式。在顶点着色器中,每个后续顶点通常从附加缓冲区中获取下一个属性值。所以第一个顶点获取缓冲区中第一个指定的位置,第二个顶点获取第二个位置,依此类推。使用这个函数,你可以告诉OpenGL根据实例而不是根据顶点推进提供给着色器的数据。例如,您可以创建一个通用顶点属性,其中包含要绘制的所有实例的世界位置,并告诉OpenGL仅更新实例之间的值,因此第一个实例的每个顶点都会获取第一个值,第二个实例的每个顶点都获取第二个值,依此类推。从着色器的角度来看,这些值现在被视为是顶点属性,而不是作为制服。理论上,这个扩展可能在OpenGL 2的早期版本中可用。

在我的硬件上,这两种方法在OpenGL 2.1上下文中都不可用(因为这些扩展或相关的方法没有公开) 。你的电脑可能和我一样。无法在OpenGL 2.1上下文中进行实例化渲染。或者你可能支持这两种方法。或者只是一个或另一个。同样,你给你程序的其他人可能会发现他们的计算机支持其中一种或另一种,或者两者都不支持。扩展就是这样,无论主机支持什么,你的程序都应该能够应付。

在我的情况下,不是根据计算机支持的情况来处理单独的实现,而是简单的解决方案是切换到OpenGL 3+上下文,其中两个接口都是非扩展形式。

glDrawArraysInstanced()(上述ARB接口的非扩展版本)在OpenGL 3.1中成为核心,因此保证每3.1核心配置文件中都存在。同样,glVertexAttribDivisor()已添加到OpenGL 3.3的核心配置文件中,并将在每3.3个核心配置文件中提供。

+0

什么让你认为这是OpenGL 2.1,出于好奇?我看到的唯一的东西是顶点数组(OpenGL 1.1)和缓冲区对象(OpenGL 1.5)。 –

+0

可能是一个严重的MacOsX偏见。 2.1在过去的十年中一直是超级违约。 –

+0

嗯,是的。 (回想起来,我写了* OpenGL 1.x代码,它使用了顶点数组,并检查是否支持缓冲对象)在这种情况下,我会补充说ARB_Instanced_Arrays可能早在OpenGL 1.1中就可用,而ARB_Draw_Instanced(因为它需要可编程着色器是有用的)至少需要OpenGL 2. –