コード例 #1
0
/*
============
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();
}
コード例 #2
0
ファイル: tr_vbo.c プロジェクト: ZdrytchX/Unvanquished-KoRx
/*
============
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();
}
コード例 #3
0
ファイル: tr_vbo.c プロジェクト: SHOVELL/Unvanquished
/*
============
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();
}
コード例 #4
0
ファイル: tr_vbo.c プロジェクト: dustinduse/etlegacy
/*
============
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();
}
コード例 #5
0
ファイル: tr_model_skel.c プロジェクト: GenaSG/etlegacy
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);
}
コード例 #6
0
ファイル: tr_model_mdm.c プロジェクト: ghostmod/Unvanquished
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));
	 */
}
コード例 #7
0
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));
	 */
}