English 中文(简体)
Can I do openGL geometry batching without transforming all the vertices by hand?
原标题:

I ve been trying to set up some sort of geometry batching for a week or so, there isn t a ton of information online as to how other people have implemented this. Basically I just want to catch every draw call, sort the corresponding meshes by texture, and then draw all meshes that share a texture in one go.

What I ve been doing is going through each vertex in the mesh, transform it by the Model-View matrix (to put it into world space), and then store that vertex in a larger array to await some later rendering. This works, but it runs terribly slowly... as it seems like I m doing in software what openGL would be doing in hardware (all the matrix transforms). Is there some other way to do batching that doesn t require you to do the transforms by hand? Can I say "hey, GL, here are a bunch of vertices and here s how they should be transformed" and then send it on its merry way?

I should mention I m doing this on iPhone, so I m bound by openGLES and the limited hardware. I ve watched the Stanford ngmoco presentation on optimizations, and I ve been following this guide to model my own texture batcher.

Here s an example of what I m doing. This is for skinned meshes... I use PowerVR s .pod format which exports an interleaved array of the vertex information.

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]]];
 }
最佳回答

So you d like a single draw call to contain multiple meshes, each with their own unique model-view matrix? If you re using OpenGL ES 2.0, then you could do this with an array of uniform mat4 s, which would then get applied in your vertex shader.

But, I bet you re using OpenGL ES 1.1. If so, you can accomplish something similar using the GL_OES_matrix_palette extension, which is supported even on older iPhones. There might be a performance hit with this extension though, since you need to send down a blending weight with each vertex.

问题回答

暂无回答




相关问题
Code sign Error

I have created a new iPhone application.I have two mach machines. I have created the certificate for running application in iPhone in one mac. Can I use the other mac for running the application in ...

ABPersonViewController Usage for displaying contact

Created a View based Project and added a contact to the AddressBook using ABAddressBookRef,ABRecordRef now i wanted to display the added contact ABPersonViewController is the method but how to use in ...

将音频Clips从Peter改为服务器

我不禁要问,那里是否有任何实例表明从Peit向服务器发送音响。 I m不关心电话或SIP风格的解决办法,只是一个简单的袖珍流程......

• 如何将搜查线重新定位?

我正试图把图像放在搜索条左边。 但是,问题始于这里,搜索条线不能重新布署。

热门标签