/* ============ R_InitVBOs ============ */ void R_InitVBOs(void) { int dataSize; int offset; ri.Printf(PRINT_ALL, "------- R_InitVBOs -------\n"); tr.numVBOs = 0; tr.numIBOs = 0; dataSize = sizeof(tess.xyz[0]); dataSize += sizeof(tess.normal[0]); #ifdef USE_VERT_TANGENT_SPACE dataSize += sizeof(tess.tangent[0]); dataSize += sizeof(tess.bitangent[0]); #endif dataSize += sizeof(tess.vertexColors[0]); dataSize += sizeof(tess.texCoords[0][0]) * 2; dataSize += sizeof(tess.lightdir[0]); dataSize *= SHADER_MAX_VERTEXES; tess.vbo = R_CreateVBO("tessVertexArray_VBO", NULL, dataSize, VBO_USAGE_DYNAMIC); offset = 0; tess.vbo->ofs_xyz = offset; offset += sizeof(tess.xyz[0]) * SHADER_MAX_VERTEXES; tess.vbo->ofs_normal = offset; offset += sizeof(tess.normal[0]) * SHADER_MAX_VERTEXES; #ifdef USE_VERT_TANGENT_SPACE tess.vbo->ofs_tangent = offset; offset += sizeof(tess.tangent[0]) * SHADER_MAX_VERTEXES; tess.vbo->ofs_bitangent = offset; offset += sizeof(tess.bitangent[0]) * SHADER_MAX_VERTEXES; #endif // these next two are actually interleaved tess.vbo->ofs_st = offset; tess.vbo->ofs_lightmap = offset + sizeof(tess.texCoords[0][0]); offset += sizeof(tess.texCoords[0][0]) * 2 * SHADER_MAX_VERTEXES; tess.vbo->ofs_vertexcolor = offset; offset += sizeof(tess.vertexColors[0]) * SHADER_MAX_VERTEXES; tess.vbo->ofs_lightdir = offset; tess.vbo->stride_xyz = sizeof(tess.xyz[0]); tess.vbo->stride_normal = sizeof(tess.normal[0]); #ifdef USE_VERT_TANGENT_SPACE tess.vbo->stride_tangent = sizeof(tess.tangent[0]); tess.vbo->stride_bitangent = sizeof(tess.bitangent[0]); #endif tess.vbo->stride_vertexcolor = sizeof(tess.vertexColors[0]); tess.vbo->stride_st = sizeof(tess.texCoords[0][0]) * 2; tess.vbo->stride_lightmap = sizeof(tess.texCoords[0][0]) * 2; tess.vbo->stride_lightdir = sizeof(tess.lightdir[0]); dataSize = sizeof(tess.indexes[0]) * SHADER_MAX_INDEXES; tess.ibo = R_CreateIBO("tessVertexArray_IBO", NULL, dataSize, VBO_USAGE_DYNAMIC); R_BindNullVBO(); R_BindNullIBO(); GL_CheckErrors(); }
/* ============ R_InitVBOs ============ */ void R_InitVBOs( void ) { int dataSize; ri.Printf( PRINT_DEVELOPER, "------- R_InitVBOs -------\n" ); Com_InitGrowList( &tr.vbos, 100 ); Com_InitGrowList( &tr.ibos, 100 ); #if !defined( COMPAT_Q3A ) && !defined( COMPAT_ET ) dataSize = sizeof( vec4_t ) * SHADER_MAX_VERTEXES * 11; #else dataSize = sizeof( vec4_t ) * SHADER_MAX_VERTEXES * 10; #endif tess.vbo = R_CreateVBO( "tessVertexArray_VBO", NULL, dataSize, VBO_USAGE_DYNAMIC ); tess.vbo->ofsXYZ = 0; tess.vbo->ofsTexCoords = tess.vbo->ofsXYZ + sizeof( tess.xyz ); tess.vbo->ofsLightCoords = tess.vbo->ofsTexCoords + sizeof( tess.texCoords ); tess.vbo->ofsTangents = tess.vbo->ofsLightCoords + sizeof( tess.lightCoords ); tess.vbo->ofsBinormals = tess.vbo->ofsTangents + sizeof( tess.tangents ); tess.vbo->ofsNormals = tess.vbo->ofsBinormals + sizeof( tess.binormals ); tess.vbo->ofsColors = tess.vbo->ofsNormals + sizeof( tess.normals ); #if !defined( COMPAT_Q3A ) && !defined( COMPAT_ET ) tess.vbo->ofsPaintColors = tess.vbo->ofsColors + sizeof( tess.colors ); tess.vbo->ofsAmbientLight = tess.vbo->ofsPaintColors + sizeof( tess.PaintColors ); #endif tess.vbo->ofsAmbientLight = tess.vbo->ofsColors + sizeof( tess.colors ); tess.vbo->ofsDirectedLight = tess.vbo->ofsAmbientLight + sizeof( tess.ambientLights ); tess.vbo->ofsLightDirections = tess.vbo->ofsDirectedLight + sizeof( tess.directedLights ); tess.vbo->sizeXYZ = sizeof( tess.xyz ); tess.vbo->sizeTangents = sizeof( tess.tangents ); tess.vbo->sizeBinormals = sizeof( tess.binormals ); tess.vbo->sizeNormals = sizeof( tess.normals ); dataSize = sizeof( tess.indexes ); tess.ibo = R_CreateIBO( "tessVertexArray_IBO", NULL, dataSize, VBO_USAGE_DYNAMIC ); R_InitUnitCubeVBO(); // allocate a PBO for color grade map transfers glGenBuffers( 1, &tr.colorGradePBO ); glBindBuffer( GL_PIXEL_PACK_BUFFER, tr.colorGradePBO ); glBufferData( GL_PIXEL_PACK_BUFFER, REF_COLORGRADEMAP_STORE_SIZE * sizeof(color4ub_t), NULL, GL_STREAM_COPY ); glBindBuffer( GL_PIXEL_PACK_BUFFER, 0 ); R_BindNullVBO(); R_BindNullIBO(); GL_CheckErrors(); }
/* ============ R_InitVBOs ============ */ void R_InitVBOs( void ) { int dataSize; byte *data; ri.Printf( PRINT_ALL, "------- R_InitVBOs -------\n" ); Com_InitGrowList( &tr.vbos, 100 ); Com_InitGrowList( &tr.ibos, 100 ); dataSize = sizeof( vec4_t ) * SHADER_MAX_VERTEXES * 11; data = Com_Allocate( dataSize ); memset( data, 0, dataSize ); tess.vbo = R_CreateVBO( "tessVertexArray_VBO", data, dataSize, VBO_USAGE_DYNAMIC ); tess.vbo->ofsXYZ = 0; tess.vbo->ofsTexCoords = tess.vbo->ofsXYZ + sizeof( tess.xyz ); tess.vbo->ofsLightCoords = tess.vbo->ofsTexCoords + sizeof( tess.texCoords ); tess.vbo->ofsTangents = tess.vbo->ofsLightCoords + sizeof( tess.lightCoords ); tess.vbo->ofsBinormals = tess.vbo->ofsTangents + sizeof( tess.tangents ); tess.vbo->ofsNormals = tess.vbo->ofsBinormals + sizeof( tess.binormals ); tess.vbo->ofsColors = tess.vbo->ofsNormals + sizeof( tess.normals ); #if !defined( COMPAT_Q3A ) && !defined( COMPAT_ET ) tess.vbo->ofsPaintColors = tess.vbo->ofsColors + sizeof( tess.colors ); tess.vbo->ofsLightDirections = tess.vbo->ofsPaintColors + sizeof( tess.paintColors ); #endif tess.vbo->sizeXYZ = sizeof( tess.xyz ); tess.vbo->sizeTangents = sizeof( tess.tangents ); tess.vbo->sizeBinormals = sizeof( tess.binormals ); tess.vbo->sizeNormals = sizeof( tess.normals ); Com_Dealloc( data ); dataSize = sizeof( tess.indexes ); data = Com_Allocate( dataSize ); memset( data, 0, dataSize ); tess.ibo = R_CreateIBO( "tessVertexArray_IBO", data, dataSize, VBO_USAGE_DYNAMIC ); Com_Dealloc( data ); R_InitUnitCubeVBO(); R_BindNullVBO(); R_BindNullIBO(); GL_CheckErrors(); }
/* ============ R_InitVBOs ============ */ void R_InitVBOs(void) { int dataSize; byte *data; Ren_Print("------- R_InitVBOs -------\n"); Com_InitGrowList(&tr.vbos, 100); Com_InitGrowList(&tr.ibos, 100); dataSize = sizeof(vec4_t) * SHADER_MAX_VERTEXES * 11; data = (byte *)Com_Allocate(dataSize); memset(data, 0, dataSize); tess.vbo = R_CreateVBO("tessVertexArray_VBO", data, dataSize, VBO_USAGE_DYNAMIC); tess.vbo->ofsXYZ = 0; tess.vbo->ofsTexCoords = tess.vbo->ofsXYZ + sizeof(tess.xyz); tess.vbo->ofsLightCoords = tess.vbo->ofsTexCoords + sizeof(tess.texCoords); tess.vbo->ofsTangents = tess.vbo->ofsLightCoords + sizeof(tess.lightCoords); tess.vbo->ofsBinormals = tess.vbo->ofsTangents + sizeof(tess.tangents); tess.vbo->ofsNormals = tess.vbo->ofsBinormals + sizeof(tess.binormals); tess.vbo->ofsColors = tess.vbo->ofsNormals + sizeof(tess.normals); tess.vbo->sizeXYZ = sizeof(tess.xyz); tess.vbo->sizeTangents = sizeof(tess.tangents); tess.vbo->sizeBinormals = sizeof(tess.binormals); tess.vbo->sizeNormals = sizeof(tess.normals); Com_Dealloc(data); dataSize = sizeof(tess.indexes); data = (byte *)Com_Allocate(dataSize); memset(data, 0, dataSize); tess.ibo = R_CreateIBO("tessVertexArray_IBO", data, dataSize, VBO_USAGE_DYNAMIC); Com_Dealloc(data); R_InitUnitCubeVBO(); R_BindNullVBO(); R_BindNullIBO(); GL_CheckErrors(); }
void AddSurfaceToVBOSurfacesList2(growList_t *vboSurfaces, growList_t *vboTriangles, growList_t *vboVertexes, md5Model_t *md5, int skinIndex, const char *materialName, int numBoneReferences, int boneReferences[MAX_BONES]) { int j, k; int vertexesNum; byte *data; int dataSize; int dataOfs; GLuint ofsTexCoords; GLuint ofsTangents; GLuint ofsBinormals; GLuint ofsNormals; GLuint ofsBoneIndexes; GLuint ofsBoneWeights; int indexesNum; byte *indexes; int indexesSize; int indexesOfs; skelTriangle_t *tri; vec4_t tmp; int index; srfVBOMD5Mesh_t *vboSurf; md5Vertex_t *v; shader_t *shader; int shaderIndex; vertexesNum = vboVertexes->currentElements; indexesNum = vboTriangles->currentElements * 3; // create surface vboSurf = ri.Hunk_Alloc(sizeof(*vboSurf), h_low); Com_AddToGrowList(vboSurfaces, vboSurf); vboSurf->surfaceType = SF_VBO_MD5MESH; vboSurf->md5Model = md5; ri.Printf(PRINT_ALL, "AddSurfaceToVBOSurfacesList2: loading shader '%s'\n", materialName); shader = R_FindShader(materialName, SHADER_3D_DYNAMIC, qtrue); if (shader->defaultShader) { shaderIndex = 0; } else { shaderIndex = shader->index; } vboSurf->shader = R_GetShaderByHandle(shaderIndex); vboSurf->skinIndex = skinIndex; vboSurf->numIndexes = indexesNum; vboSurf->numVerts = vertexesNum; dataSize = vertexesNum * (sizeof(vec4_t) * 8); data = ri.Hunk_AllocateTempMemory(dataSize); dataOfs = 0; indexesSize = indexesNum * sizeof(int); indexes = ri.Hunk_AllocateTempMemory(indexesSize); indexesOfs = 0; //ri.Printf(PRINT_ALL, "AddSurfaceToVBOSurfacesList( %i verts, %i tris )\n", surf->numVerts, vboTriangles->currentElements); vboSurf->numBoneRemap = 0; Com_Memset(vboSurf->boneRemap, 0, sizeof(vboSurf->boneRemap)); Com_Memset(vboSurf->boneRemapInverse, 0, sizeof(vboSurf->boneRemapInverse)); //ri.Printf(PRINT_ALL, "referenced bones: "); for (j = 0; j < MAX_BONES; j++) { if (boneReferences[j] > 0) { vboSurf->boneRemap[j] = vboSurf->numBoneRemap; vboSurf->boneRemapInverse[vboSurf->numBoneRemap] = j; vboSurf->numBoneRemap++; //ri.Printf(PRINT_ALL, "(%i -> %i) ", j, vboSurf->boneRemap[j]); } } //ri.Printf(PRINT_ALL, "\n"); //for(j = 0, tri = surf->triangles; j < surf->numTriangles; j++, tri++) for (j = 0; j < vboTriangles->currentElements; j++) { tri = Com_GrowListElement(vboTriangles, j); for (k = 0; k < 3; k++) { index = tri->indexes[k]; Com_Memcpy(indexes + indexesOfs, &index, sizeof(int)); indexesOfs += sizeof(int); } } // feed vertex XYZ for (j = 0; j < vertexesNum; j++) { v = Com_GrowListElement(vboVertexes, j); for (k = 0; k < 3; k++) { tmp[k] = v->position[k]; } tmp[3] = 1; Com_Memcpy(data + dataOfs, ( vec_t * ) tmp, sizeof(vec4_t)); dataOfs += sizeof(vec4_t); } // feed vertex texcoords ofsTexCoords = dataOfs; for (j = 0; j < vertexesNum; j++) { v = Com_GrowListElement(vboVertexes, j); for (k = 0; k < 2; k++) { tmp[k] = v->texCoords[k]; } tmp[2] = 0; tmp[3] = 1; Com_Memcpy(data + dataOfs, ( vec_t * ) tmp, sizeof(vec4_t)); dataOfs += sizeof(vec4_t); } // feed vertex tangents ofsTangents = dataOfs; for (j = 0; j < vertexesNum; j++) { v = Com_GrowListElement(vboVertexes, j); for (k = 0; k < 3; k++) { tmp[k] = v->tangent[k]; } tmp[3] = 1; Com_Memcpy(data + dataOfs, ( vec_t * ) tmp, sizeof(vec4_t)); dataOfs += sizeof(vec4_t); } // feed vertex binormals ofsBinormals = dataOfs; for (j = 0; j < vertexesNum; j++) { v = Com_GrowListElement(vboVertexes, j); for (k = 0; k < 3; k++) { tmp[k] = v->binormal[k]; } tmp[3] = 1; Com_Memcpy(data + dataOfs, ( vec_t * ) tmp, sizeof(vec4_t)); dataOfs += sizeof(vec4_t); } // feed vertex normals ofsNormals = dataOfs; for (j = 0; j < vertexesNum; j++) { v = Com_GrowListElement(vboVertexes, j); for (k = 0; k < 3; k++) { tmp[k] = v->normal[k]; } tmp[3] = 1; Com_Memcpy(data + dataOfs, ( vec_t * ) tmp, sizeof(vec4_t)); dataOfs += sizeof(vec4_t); } // feed bone indices ofsBoneIndexes = dataOfs; for (j = 0; j < vertexesNum; j++) { v = Com_GrowListElement(vboVertexes, j); for (k = 0; k < MAX_WEIGHTS; k++) { if (k < v->numWeights) { index = vboSurf->boneRemap[v->weights[k]->boneIndex]; } else { index = 0; } Com_Memcpy(data + dataOfs, &index, sizeof(int)); dataOfs += sizeof(int); } } // feed bone weights ofsBoneWeights = dataOfs; for (j = 0; j < vertexesNum; j++) { v = Com_GrowListElement(vboVertexes, j); for (k = 0; k < MAX_WEIGHTS; k++) { if (k < v->numWeights) { tmp[k] = v->weights[k]->boneWeight; } else { tmp[k] = 0; } } Com_Memcpy(data + dataOfs, ( vec_t * ) tmp, sizeof(vec4_t)); dataOfs += sizeof(vec4_t); } vboSurf->vbo = R_CreateVBO(va("staticMD5Mesh_VBO %i", vboSurfaces->currentElements), data, dataSize, VBO_USAGE_STATIC); vboSurf->vbo->ofsXYZ = 0; vboSurf->vbo->ofsTexCoords = ofsTexCoords; vboSurf->vbo->ofsLightCoords = ofsTexCoords; vboSurf->vbo->ofsTangents = ofsTangents; vboSurf->vbo->ofsBinormals = ofsBinormals; vboSurf->vbo->ofsNormals = ofsNormals; vboSurf->vbo->ofsBoneIndexes = ofsBoneIndexes; vboSurf->vbo->ofsBoneWeights = ofsBoneWeights; vboSurf->ibo = R_CreateIBO(va("staticMD5Mesh_IBO %i", vboSurfaces->currentElements), indexes, indexesSize, VBO_USAGE_STATIC); ri.Hunk_FreeTempMemory(indexes); ri.Hunk_FreeTempMemory(data); // megs /* ri.Printf(PRINT_ALL, "md5 mesh data VBO size: %d.%02d MB\n", dataSize / (1024 * 1024), (dataSize % (1024 * 1024)) * 100 / (1024 * 1024)); ri.Printf(PRINT_ALL, "md5 mesh tris VBO size: %d.%02d MB\n", indexesSize / (1024 * 1024), (indexesSize % (1024 * 1024)) * 100 / (1024 * 1024)); */ ri.Printf(PRINT_ALL, "created VBO surface %i with %i vertices and %i triangles\n", vboSurfaces->currentElements, vboSurf->numVerts, vboSurf->numIndexes / 3); }
static void AddSurfaceToVBOSurfacesListMDM( growList_t *vboSurfaces, growList_t *vboTriangles, mdmModel_t *mdm, mdmSurfaceIntern_t *surf, int skinIndex, int numBoneReferences, int boneReferences[ MAX_BONES ] ) { int j, k, lod; int vertexesNum; byte *data; int dataSize; int dataOfs; GLuint ofsTexCoords; GLuint ofsTangents; GLuint ofsBinormals; GLuint ofsNormals; GLuint ofsBoneIndexes; GLuint ofsBoneWeights; int indexesNum; byte *indexes; int indexesSize; int indexesOfs; skelTriangle_t *tri; vec4_t tmp; int index; srfVBOMDMMesh_t *vboSurf; md5Vertex_t *v; // vec4_t tmpColor = { 1, 1, 1, 1 }; static int32_t collapse[ MDM_MAX_VERTS ]; vertexesNum = surf->numVerts; indexesNum = vboTriangles->currentElements * 3; // create surface vboSurf = ri.Hunk_Alloc( sizeof( *vboSurf ), h_low ); Com_AddToGrowList( vboSurfaces, vboSurf ); vboSurf->surfaceType = SF_VBO_MDMMESH; vboSurf->mdmModel = mdm; vboSurf->mdmSurface = surf; vboSurf->shader = R_GetShaderByHandle( surf->shaderIndex ); vboSurf->skinIndex = skinIndex; vboSurf->numIndexes = indexesNum; vboSurf->numVerts = vertexesNum; dataSize = vertexesNum * ( sizeof( vec4_t ) * 7 ); data = ri.Hunk_AllocateTempMemory( dataSize ); dataOfs = 0; //ri.Printf(PRINT_ALL, "AddSurfaceToVBOSurfacesList( %i verts, %i tris )\n", surf->numVerts, vboTriangles->currentElements); vboSurf->numBoneRemap = 0; Com_Memset( vboSurf->boneRemap, 0, sizeof( vboSurf->boneRemap ) ); Com_Memset( vboSurf->boneRemapInverse, 0, sizeof( vboSurf->boneRemapInverse ) ); //ri.Printf(PRINT_ALL, "original referenced bones: [ "); //for(j = 0; j < surf->numBoneReferences; j++) //{ // ri.Printf(PRINT_ALL, "%i, ", surf->boneReferences[j]); //} //ri.Printf(PRINT_ALL, "]\n"); //ri.Printf(PRINT_ALL, "new referenced bones: "); for ( j = 0; j < MAX_BONES; j++ ) { if ( boneReferences[ j ] > 0 ) { vboSurf->boneRemap[ j ] = vboSurf->numBoneRemap; vboSurf->boneRemapInverse[ vboSurf->numBoneRemap ] = j; vboSurf->numBoneRemap++; //ri.Printf(PRINT_ALL, "(%i -> %i) ", j, vboSurf->boneRemap[j]); } } //ri.Printf(PRINT_ALL, "\n"); // feed vertex XYZ for ( j = 0; j < vertexesNum; j++ ) { for ( k = 0; k < 3; k++ ) { tmp[ k ] = surf->verts[ j ].position[ k ]; } tmp[ 3 ] = 1; Com_Memcpy( data + dataOfs, ( vec_t * ) tmp, sizeof( vec4_t ) ); dataOfs += sizeof( vec4_t ); } // feed vertex texcoords ofsTexCoords = dataOfs; for ( j = 0; j < vertexesNum; j++ ) { for ( k = 0; k < 2; k++ ) { tmp[ k ] = surf->verts[ j ].texCoords[ k ]; } tmp[ 2 ] = 0; tmp[ 3 ] = 1; Com_Memcpy( data + dataOfs, ( vec_t * ) tmp, sizeof( vec4_t ) ); dataOfs += sizeof( vec4_t ); } // feed vertex tangents ofsTangents = dataOfs; for ( j = 0; j < vertexesNum; j++ ) { for ( k = 0; k < 3; k++ ) { tmp[ k ] = surf->verts[ j ].tangent[ k ]; } tmp[ 3 ] = 1; Com_Memcpy( data + dataOfs, ( vec_t * ) tmp, sizeof( vec4_t ) ); dataOfs += sizeof( vec4_t ); } // feed vertex binormals ofsBinormals = dataOfs; for ( j = 0; j < vertexesNum; j++ ) { for ( k = 0; k < 3; k++ ) { tmp[ k ] = surf->verts[ j ].binormal[ k ]; } tmp[ 3 ] = 1; Com_Memcpy( data + dataOfs, ( vec_t * ) tmp, sizeof( vec4_t ) ); dataOfs += sizeof( vec4_t ); } // feed vertex normals ofsNormals = dataOfs; for ( j = 0; j < vertexesNum; j++ ) { for ( k = 0; k < 3; k++ ) { tmp[ k ] = surf->verts[ j ].normal[ k ]; } tmp[ 3 ] = 1; Com_Memcpy( data + dataOfs, ( vec_t * ) tmp, sizeof( vec4_t ) ); dataOfs += sizeof( vec4_t ); } // feed bone indices ofsBoneIndexes = dataOfs; for ( j = 0, v = surf->verts; j < surf->numVerts; j++, v++ ) { for ( k = 0; k < MAX_WEIGHTS; k++ ) { if ( k < v->numWeights ) { index = vboSurf->boneRemap[ v->weights[ k ]->boneIndex ]; } else { index = 0; } Com_Memcpy( data + dataOfs, &index, sizeof( int ) ); dataOfs += sizeof( int ); } } // feed bone weights ofsBoneWeights = dataOfs; for ( j = 0, v = surf->verts; j < surf->numVerts; j++, v++ ) { for ( k = 0; k < MAX_WEIGHTS; k++ ) { if ( k < v->numWeights ) { tmp[ k ] = v->weights[ k ]->boneWeight; } else { tmp[ k ] = 0; } } Com_Memcpy( data + dataOfs, ( vec_t * ) tmp, sizeof( vec4_t ) ); dataOfs += sizeof( vec4_t ); } vboSurf->vbo = R_CreateVBO( va( "staticMDMMesh_VBO %i", vboSurfaces->currentElements ), data, dataSize, VBO_USAGE_STATIC ); vboSurf->vbo->ofsXYZ = 0; vboSurf->vbo->ofsTexCoords = ofsTexCoords; vboSurf->vbo->ofsLightCoords = ofsTexCoords; vboSurf->vbo->ofsTangents = ofsTangents; vboSurf->vbo->ofsBinormals = ofsBinormals; vboSurf->vbo->ofsNormals = ofsNormals; vboSurf->vbo->ofsColors = ofsNormals; vboSurf->vbo->ofsLightCoords = 0; // not required anyway vboSurf->vbo->ofsLightDirections = 0; // not required anyway vboSurf->vbo->ofsBoneIndexes = ofsBoneIndexes; vboSurf->vbo->ofsBoneWeights = ofsBoneWeights; // calculate LOD IBOs lod = 0; do { float flod; int renderCount; flod = mdmLODResolutions[ lod ]; renderCount = MIN( ( int )( ( float ) surf->numVerts * flod ), surf->numVerts ); if ( renderCount < surf->minLod ) { renderCount = surf->minLod; flod = ( float ) renderCount / surf->numVerts; } if ( renderCount == surf->numVerts ) { indexesNum = vboTriangles->currentElements * 3; indexesSize = indexesNum * sizeof( int ); indexes = ri.Hunk_AllocateTempMemory( indexesSize ); indexesOfs = 0; for ( j = 0; j < vboTriangles->currentElements; j++ ) { tri = Com_GrowListElement( vboTriangles, j ); for ( k = 0; k < 3; k++ ) { index = tri->indexes[ k ]; Com_Memcpy( indexes + indexesOfs, &index, sizeof( int ) ); indexesOfs += sizeof( int ); } } } else { int ci[ 3 ]; int32_t *pCollapseMap; int32_t *pCollapse; pCollapse = collapse; for ( j = 0; j < renderCount; pCollapse++, j++ ) { *pCollapse = j; } pCollapseMap = &surf->collapseMap[ renderCount ]; for ( j = renderCount; j < surf->numVerts; j++, pCollapse++, pCollapseMap++ ) { int32_t collapseValue = *pCollapseMap; *pCollapse = collapse[ collapseValue ]; } indexesNum = 0; for ( j = 0; j < vboTriangles->currentElements; j++ ) { tri = Com_GrowListElement( vboTriangles, j ); ci[ 0 ] = collapse[ tri->indexes[ 0 ] ]; ci[ 1 ] = collapse[ tri->indexes[ 1 ] ]; ci[ 2 ] = collapse[ tri->indexes[ 2 ] ]; // FIXME // note: serious optimization opportunity here, // by sorting the triangles the following "continue" // could have been made into a "break" statement. if ( ci[ 0 ] == ci[ 1 ] || ci[ 1 ] == ci[ 2 ] || ci[ 2 ] == ci[ 0 ] ) { continue; } indexesNum += 3; } indexesSize = indexesNum * sizeof( int ); indexes = ri.Hunk_AllocateTempMemory( indexesSize ); indexesOfs = 0; for ( j = 0; j < vboTriangles->currentElements; j++ ) { tri = Com_GrowListElement( vboTriangles, j ); ci[ 0 ] = collapse[ tri->indexes[ 0 ] ]; ci[ 1 ] = collapse[ tri->indexes[ 1 ] ]; ci[ 2 ] = collapse[ tri->indexes[ 2 ] ]; // FIXME // note: serious optimization opportunity here, // by sorting the triangles the following "continue" // could have been made into a "break" statement. if ( ci[ 0 ] == ci[ 1 ] || ci[ 1 ] == ci[ 2 ] || ci[ 2 ] == ci[ 0 ] ) { continue; } for ( k = 0; k < 3; k++ ) { index = ci[ k ]; Com_Memcpy( indexes + indexesOfs, &index, sizeof( int ) ); indexesOfs += sizeof( int ); } } } vboSurf->ibo[ lod ] = R_CreateIBO( va( "staticMDMMesh_IBO_LOD_%f %i", flod, indexesNum / 3 ), indexes, indexesSize, VBO_USAGE_STATIC ); vboSurf->ibo[ lod ]->indexesNum = indexesNum; ri.Hunk_FreeTempMemory( indexes ); if ( vboTriangles->currentElements != surf->numTriangles ) { ri.Printf( PRINT_WARNING, "Can't calculate LOD IBOs\n" ); break; } lod++; } while ( lod < MD3_MAX_LODS ); ri.Hunk_FreeTempMemory( data ); // megs /* ri.Printf(PRINT_ALL, "md5 mesh data VBO size: %d.%02d MB\n", dataSize / (1024 * 1024), (dataSize % (1024 * 1024)) * 100 / (1024 * 1024)); ri.Printf(PRINT_ALL, "md5 mesh tris VBO size: %d.%02d MB\n", indexesSize / (1024 * 1024), (indexesSize % (1024 * 1024)) * 100 / (1024 * 1024)); */ }
void AddSurfaceToVBOSurfacesList(growList_t * vboSurfaces, growList_t * vboTriangles, md5Model_t * md5, md5Surface_t * surf, int skinIndex, int numBoneReferences, int boneReferences[MAX_BONES]) { int j, k; int vertexesNum; byte *data; int dataSize; int dataOfs; GLuint ofsTexCoords; GLuint ofsTangents; GLuint ofsBinormals; GLuint ofsNormals; GLuint ofsColors; GLuint ofsBoneIndexes; GLuint ofsBoneWeights; int indexesNum; byte *indexes; int indexesSize; int indexesOfs; skelTriangle_t *tri; vec4_t tmp; int index; srfVBOMD5Mesh_t *vboSurf; md5Vertex_t *v; vec4_t tmpColor = { 1, 1, 1, 1 }; vertexesNum = surf->numVerts; indexesNum = vboTriangles->currentElements * 3; // create surface vboSurf = ri.Hunk_Alloc(sizeof(*vboSurf), h_low); Com_AddToGrowList(vboSurfaces, vboSurf); vboSurf->surfaceType = SF_VBO_MD5MESH; vboSurf->md5Model = md5; vboSurf->shader = R_GetShaderByHandle(surf->shaderIndex); vboSurf->skinIndex = skinIndex; vboSurf->numIndexes = indexesNum; vboSurf->numVerts = vertexesNum; dataSize = vertexesNum * (sizeof(vec4_t) * 8); data = ri.Hunk_AllocateTempMemory(dataSize); dataOfs = 0; indexesSize = indexesNum * sizeof(int); indexes = ri.Hunk_AllocateTempMemory(indexesSize); indexesOfs = 0; //ri.Printf(PRINT_ALL, "AddSurfaceToVBOSurfacesList( %i verts, %i tris )\n", surf->numVerts, vboTriangles->currentElements); vboSurf->numBoneRemap = 0; Com_Memset(vboSurf->boneRemap, 0, sizeof(vboSurf->boneRemap)); Com_Memset(vboSurf->boneRemapInverse, 0, sizeof(vboSurf->boneRemapInverse)); //ri.Printf(PRINT_ALL, "referenced bones: "); for(j = 0; j < MAX_BONES; j++) { if(boneReferences[j] > 0) { vboSurf->boneRemap[j] = vboSurf->numBoneRemap; vboSurf->boneRemapInverse[vboSurf->numBoneRemap] = j; vboSurf->numBoneRemap++; //ri.Printf(PRINT_ALL, "(%i -> %i) ", j, vboSurf->boneRemap[j]); } } //ri.Printf(PRINT_ALL, "\n"); //for(j = 0, tri = surf->triangles; j < surf->numTriangles; j++, tri++) for(j = 0; j < vboTriangles->currentElements; j++) { tri = Com_GrowListElement(vboTriangles, j); for(k = 0; k < 3; k++) { index = tri->indexes[k]; Com_Memcpy(indexes + indexesOfs, &index, sizeof(int)); indexesOfs += sizeof(int); } } // feed vertex XYZ for(j = 0; j < vertexesNum; j++) { for(k = 0; k < 3; k++) { tmp[k] = surf->verts[j].position[k]; } tmp[3] = 1; Com_Memcpy(data + dataOfs, (vec_t *) tmp, sizeof(vec4_t)); dataOfs += sizeof(vec4_t); } // feed vertex texcoords ofsTexCoords = dataOfs; for(j = 0; j < vertexesNum; j++) { for(k = 0; k < 2; k++) { tmp[k] = surf->verts[j].texCoords[k]; } tmp[2] = 0; tmp[3] = 1; Com_Memcpy(data + dataOfs, (vec_t *) tmp, sizeof(vec4_t)); dataOfs += sizeof(vec4_t); } // feed vertex tangents ofsTangents = dataOfs; for(j = 0; j < vertexesNum; j++) { for(k = 0; k < 3; k++) { tmp[k] = surf->verts[j].tangent[k]; } tmp[3] = 1; Com_Memcpy(data + dataOfs, (vec_t *) tmp, sizeof(vec4_t)); dataOfs += sizeof(vec4_t); } // feed vertex binormals ofsBinormals = dataOfs; for(j = 0; j < vertexesNum; j++) { for(k = 0; k < 3; k++) { tmp[k] = surf->verts[j].binormal[k]; } tmp[3] = 1; Com_Memcpy(data + dataOfs, (vec_t *) tmp, sizeof(vec4_t)); dataOfs += sizeof(vec4_t); } // feed vertex normals ofsNormals = dataOfs; for(j = 0; j < vertexesNum; j++) { for(k = 0; k < 3; k++) { tmp[k] = surf->verts[j].normal[k]; } tmp[3] = 1; Com_Memcpy(data + dataOfs, (vec_t *) tmp, sizeof(vec4_t)); dataOfs += sizeof(vec4_t); } // feed vertex colors ofsColors = dataOfs; for(j = 0; j < vertexesNum; j++) { Com_Memcpy(data + dataOfs, tmpColor, sizeof(vec4_t)); dataOfs += sizeof(vec4_t); } // feed bone indices ofsBoneIndexes = dataOfs; for(j = 0, v = surf->verts; j < surf->numVerts; j++, v++) { for(k = 0; k < MAX_WEIGHTS; k++) { if(k < v->numWeights) index = vboSurf->boneRemap[v->weights[k]->boneIndex]; else index = 0; Com_Memcpy(data + dataOfs, &index, sizeof(int)); dataOfs += sizeof(int); } } // feed bone weights ofsBoneWeights = dataOfs; for(j = 0, v = surf->verts; j < surf->numVerts; j++, v++) { for(k = 0; k < MAX_WEIGHTS; k++) { if(k < v->numWeights) tmp[k] = v->weights[k]->boneWeight; else tmp[k] = 0; } Com_Memcpy(data + dataOfs, (vec_t *) tmp, sizeof(vec4_t)); dataOfs += sizeof(vec4_t); } vboSurf->vbo = R_CreateVBO(va("staticMD5Mesh_VBO %i", vboSurfaces->currentElements), data, dataSize, VBO_USAGE_STATIC); vboSurf->vbo->ofsXYZ = 0; vboSurf->vbo->ofsTexCoords = ofsTexCoords; vboSurf->vbo->ofsLightCoords = ofsTexCoords; vboSurf->vbo->ofsTangents = ofsTangents; vboSurf->vbo->ofsBinormals = ofsBinormals; vboSurf->vbo->ofsNormals = ofsNormals; vboSurf->vbo->ofsColors = ofsColors; vboSurf->vbo->ofsLightCoords = ofsColors; // not required anyway vboSurf->vbo->ofsLightDirections = ofsColors; // not required anyway vboSurf->vbo->ofsBoneIndexes = ofsBoneIndexes; vboSurf->vbo->ofsBoneWeights = ofsBoneWeights; vboSurf->ibo = R_CreateIBO(va("staticMD5Mesh_IBO %i", vboSurfaces->currentElements), indexes, indexesSize, VBO_USAGE_STATIC); ri.Hunk_FreeTempMemory(indexes); ri.Hunk_FreeTempMemory(data); // megs /* ri.Printf(PRINT_ALL, "md5 mesh data VBO size: %d.%02d MB\n", dataSize / (1024 * 1024), (dataSize % (1024 * 1024)) * 100 / (1024 * 1024)); ri.Printf(PRINT_ALL, "md5 mesh tris VBO size: %d.%02d MB\n", indexesSize / (1024 * 1024), (indexesSize % (1024 * 1024)) * 100 / (1024 * 1024)); */ }