iphone - 我可以在不手动转换所有顶点的情况下进行 openGL 几何批处理吗?

标签 iphone opengl-es

我已经尝试设置某种几何批处理大约一周了,网上没有大量关于其他人如何实现这一点的信息。基本上我只想“捕获”每个绘制调用,按纹理对相应的网格进行排序,然后一次性绘制共享纹理的所有网格。

我一直在做的是遍历网格中的每个顶点,通过模型 View 矩阵对其进行转换(将其放入世界空间中),然后将该顶点存储在更大的数组中以等待稍后的渲染。这是可行的,但它运行得非常慢......因为看起来我在软件中所做的事情就像openGL在硬件中所做的那样(所有矩阵变换)。是否有其他方法可以进行批处理而不需要您手动进行转换?我可以说“嘿,GL,这里有一堆顶点,这是它们应该如何转换”,然后以愉快的方式发送它?

我应该提到我是在 iPhone 上执行此操作,因此我受到 openGLES 和有限硬件的约束。我看过Stanford ngmoco presentation on optimizations ,我一直在关注this guide为我自己的纹理批处理程序建模。

这是我正在做的事情的一个例子。这是针对蒙皮网格的...我使用 PowerVR 的 .pod 格式,该格式导出顶点信息的交错数组。

TextureBatcher * tb = [TextureBatcher getSharedTextureBatcher];

// The next line gives me the indices of the verts used by this batch
GLushort * indices = (GLushort*) (mesh.sFaces.pData + (uint) &((GLushort *)0)[3 * mesh.sBoneBatches.pnBatchOffset[batchNum]]);
[tb addIndices:indices Count:i32Tris * 3];

NSMutableSet * alreadyVisitedIndices = [NSMutableSet setWithCapacity:i32Tris*3];

for(int i = 0; i < i32Tris*3; i++){
 if([alreadyVisitedIndices containsObject:[NSNumber numberWithInt:indices[i]]]){
  continue;
 } else {
  GLfloat * verts   = (GLfloat*)(mesh.pInterleaved + (uint)mesh.sVertex.pData   + (indices[i]*mesh.sVertex.nStride));
  GLfloat * normals = (GLfloat*)(mesh.pInterleaved + (uint)mesh.sNormals.pData  + (indices[i]*mesh.sNormals.nStride));
  GLfloat * uvs     = (GLfloat*)(mesh.pInterleaved + (uint)mesh.psUVW[uvSet].pData + (indices[i]*mesh.psUVW[uvSet].nStride));


  PVRTVec4 vert = PVRTVec4(verts[0], verts[1], verts[2], 1);
  PVRTVec4 normal = PVRTVec4(normals[0], normals[1], normals[2], 0); //w=0 to skip translation      
  GLfloat u = uvs[0];
  GLfloat v = uvs[1];

  PVRTVec4 newVert = PVRTVec4(0.f);
  PVRTVec4 newNormal = PVRTVec4(0.f);
  if(bSkinning){
   for(int j = 0; j < mesh.sBoneIdx.n; j++){
    PVRTMat4 mat = boneMatrices[(mesh.pInterleaved + (uint)mesh.sBoneIdx.pData + (indices[i]*mesh.sBoneIdx.nStride))[j]];
    GLfloat weight = ((GLfloat*)(mesh.pInterleaved + (uint)mesh.sBoneWeight.pData + (indices[i]*mesh.sBoneWeight.nStride)))[j];
    PVRTMat4 weightedMatrix = mat * weight;

    newVert += weightedMatrix * vert;
    // TODO this should use the inverse transpose but whatever it works.
    newNormal += weightedMatrix * normal;
   }

   [tb addVertex: newVert Normal: newNormal U: u V: v];
  }
  else {
   [tb addVertex: (mModelView * vert) Normal: (mModelView * normal) U: u V: v];
  }
  [alreadyVisitedIndices addObject:[NSNumber numberWithInt:indices[i]]];
 }

最佳答案

所以您希望一次绘制调用包含多个网格,每个网格都有自己独特的模型 View 矩阵?如果您使用的是 OpenGL ES 2.0,那么您可以使用统一的 ma​​t4 数组来完成此操作,然后将其应用到您的顶点着色器中。

但是,我打赌您使用的是 OpenGL ES 1.1。如果是这样,您可以使用 GL_OES_matrix_palette 完成类似的操作扩展,甚至在较旧的 iPhone 上也支持。不过,此扩展可能会影响性能,因为您需要向每个顶点发送混合权重。

关于iphone - 我可以在不手动转换所有顶点的情况下进行 openGL 几何批处理吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1684518/

相关文章:

iphone - 每次启动应用程序时播放声音

ios - GLSL ES 裁剪顶点到远平面

iphone - 立方体边缘出现白边

iphone - CABasicAnimation 在动画完成后不更改其位置属性

iphone - 错误 : Whitelist rejection in Phonegap

iphone - 无法发推文图片

iphone - 在AppStore上发布多语言iphone游戏的最佳方法是什么?

objective-c - 使用 XCODE 4.2 编译 iOS 5.0 时出现 Libpng 错误

iphone - OpenGL ES 不会删除我在内存中的纹理

ios - 在 iOS 上扫描蓝牙 2.1(旧版)设备