我一直在努力设置某种几何形状的批处理一周左右,网上没有关于其他人如何实现这一点的大量信息。基本上我只想“捕捉”每个绘图调用,按纹理对相应的网格进行排序,然后一次性绘制共享纹理的所有网格。
我一直在做的是遍历网格中的每个顶点,通过模型 - 视图矩阵(将其放入世界空间)进行转换,然后将该顶点存储在更大的数组中以等待稍后的渲染。这很有效,但它的运行速度非常慢......因为我似乎正在用软件做什么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]]];
}
答案 0 :(得分:2)
所以你想要一个包含多个网格的绘图调用,每个网格都有自己独特的模型视图矩阵?如果您正在使用OpenGL ES 2.0,那么您可以使用一系列统一的 mat4 来执行此操作,然后将其应用于您的顶点着色器。
但是,我敢打赌你正在使用OpenGL ES 1.1。如果是这样,您可以使用GL_OES_matrix_palette扩展程序完成类似的操作,甚至在较旧的iPhone上也支持此扩展程序。但是,这个扩展可能会有性能损失,因为你需要向每个顶点发送一个混合权重。