Example #1
0
/*
============
R_CreateVBO2
============
*/
VBO_t          *R_CreateVBO2( const char *name, int numVertexes, srfVert_t *verts, unsigned int stateBits, vboUsage_t usage )
{
	VBO_t  *vbo;
	int    i, j;

	byte   *data;
	int    dataSize;
	int    dataOfs;

	int    glUsage;

	switch ( usage )
	{
		case VBO_USAGE_STATIC:
			glUsage = GL_STATIC_DRAW;
			break;

		case VBO_USAGE_DYNAMIC:
			glUsage = GL_DYNAMIC_DRAW;
			break;

		default:
			glUsage = 0;
			Com_Error( ERR_FATAL, "bad vboUsage_t given: %i", usage );
	}

	if ( !numVertexes )
	{
		return NULL;
	}

	if ( strlen( name ) >= MAX_QPATH )
	{
		ri.Error( ERR_DROP, "R_CreateVBO2: \"%s\" is too long", name );
	}

	// make sure the render thread is stopped
	R_SyncRenderThread();

	vbo = ri.Hunk_Alloc( sizeof( *vbo ), h_low );
	Com_AddToGrowList( &tr.vbos, vbo );

	Q_strncpyz( vbo->name, name, sizeof( vbo->name ) );

	vbo->ofsXYZ = 0;
	vbo->ofsTexCoords = 0;
	vbo->ofsLightCoords = 0;
	vbo->ofsBinormals = 0;
	vbo->ofsTangents = 0;
	vbo->ofsNormals = 0;
	vbo->ofsColors = 0;
	vbo->ofsPaintColors = 0;
	vbo->ofsLightDirections = 0;
	vbo->ofsBoneIndexes = 0;
	vbo->ofsBoneWeights = 0;

	vbo->sizeXYZ = 0;
	vbo->sizeTangents = 0;
	vbo->sizeBinormals = 0;
	vbo->sizeNormals = 0;

	// create VBO
	dataSize = numVertexes * ( sizeof( vec4_t ) * 9 );
	data = ri.Hunk_AllocateTempMemory( dataSize );
	dataOfs = 0;

	// since this is all float, point tmp directly into data
	// 2-entry -> { memb[0], memb[1], 0, 1 }
	// 3-entry -> { memb[0], memb[1], memb[2], 1 }
#define VERTEXCOPY(memb) \
	do { \
		vec_t *tmp = (vec_t *) ( data + dataOfs ); \
		for ( i = 0; i < numVertexes; i++ ) \
		{ \
			for ( j = 0; j < ARRAY_LEN( verts->memb ); j++ ) { *tmp++ = verts[ i ].memb[ j ]; } \
			if ( ARRAY_LEN( verts->memb ) < 3 ) { *tmp++ = 0; } \
			if ( ARRAY_LEN( verts->memb ) < 4 ) { *tmp++ = 1; } \
		} \
		dataOfs += i * sizeof( vec4_t ); \
	} while ( 0 )

	// set up xyz array
	VERTEXCOPY( xyz );

	// feed vertex texcoords
	if ( stateBits & ATTR_TEXCOORD )
	{
		vbo->ofsTexCoords = dataOfs;
		VERTEXCOPY( st );
	}

	// feed vertex lightmap texcoords
	if ( stateBits & ATTR_LIGHTCOORD )
	{
		vbo->ofsLightCoords = dataOfs;
		VERTEXCOPY( lightmap );
	}

	// feed vertex tangents
	if ( stateBits & ATTR_TANGENT )
	{
		vbo->ofsTangents = dataOfs;
		VERTEXCOPY( tangent );
	}

	// feed vertex binormals
	if ( stateBits & ATTR_BINORMAL )
	{
		vbo->ofsBinormals = dataOfs;
		VERTEXCOPY( binormal );
	}

	// feed vertex normals
	if ( stateBits & ATTR_NORMAL )
	{
		vbo->ofsNormals = dataOfs;
		VERTEXCOPY( normal );
	}

	// feed vertex colors
	if ( stateBits & ATTR_COLOR )
	{
		vbo->ofsColors = dataOfs;
		VERTEXCOPY( lightColor );
	}

#if !defined( COMPAT_Q3A ) && !defined( COMPAT_ET )

	// feed vertex paint colors
	if ( stateBits & ATTR_PAINTCOLOR )
	{
		vbo->ofsPaintColors = dataOfs;
		VERTEXCOPY( paintColor );
	}

	// feed vertex light directions
	if ( stateBits & ATTR_LIGHTDIRECTION )
	{
		vbo->ofsLightDirections = dataOfs;
		VERTEXCOPY( lightDirection );
	}

#endif

	vbo->vertexesSize = dataSize;
	vbo->vertexesNum = numVertexes;

	glGenBuffers( 1, &vbo->vertexesVBO );

	glBindBuffer( GL_ARRAY_BUFFER, vbo->vertexesVBO );
	glBufferData( GL_ARRAY_BUFFER, dataSize, data, glUsage );

	glBindBuffer( GL_ARRAY_BUFFER, 0 );

	GL_CheckErrors();

	ri.Hunk_FreeTempMemory( data );

	return vbo;
}
Example #2
0
/*
============
R_CreateVBO2
============
*/
VBO_t *R_CreateVBO2(const char *name, int numVertexes, srfVert_t *verts, unsigned int stateBits, vboUsage_t usage)
{
	VBO_t        *vbo;
	int          i, j;
	byte         *data;
	int          dataSize;
	int          dataOfs;
	int          glUsage;
	unsigned int bits;

	switch (usage)
	{
	case VBO_USAGE_STATIC:
		glUsage = GL_STATIC_DRAW;
		break;
	case VBO_USAGE_DYNAMIC:
		glUsage = GL_DYNAMIC_DRAW;
		break;
	default:
		glUsage = 0;
		Ren_Fatal("bad vboUsage_t given: %i", usage);
		break;
	}

	if (!numVertexes)
	{
		return NULL;
	}

	if (strlen(name) >= MAX_QPATH)
	{
		Ren_Drop("R_CreateVBO2: \"%s\" is too long\n", name);
	}

	// make sure the render thread is stopped
	R_IssuePendingRenderCommands();

	vbo = (VBO_t *)ri.Hunk_Alloc(sizeof(*vbo), h_low);
	Com_AddToGrowList(&tr.vbos, vbo);

	Q_strncpyz(vbo->name, name, sizeof(vbo->name));

	vbo->ofsXYZ             = 0;
	vbo->ofsTexCoords       = 0;
	vbo->ofsLightCoords     = 0;
	vbo->ofsBinormals       = 0;
	vbo->ofsTangents        = 0;
	vbo->ofsNormals         = 0;
	vbo->ofsColors          = 0;
	vbo->ofsPaintColors     = 0;
	vbo->ofsLightDirections = 0;
	vbo->ofsBoneIndexes     = 0;
	vbo->ofsBoneWeights     = 0;

	vbo->sizeXYZ       = 0;
	vbo->sizeTangents  = 0;
	vbo->sizeBinormals = 0;
	vbo->sizeNormals   = 0;

	// size VBO
	dataSize = 0;
	bits     = stateBits;
	while (bits)
	{
		if (bits & 1)
		{
			dataSize += sizeof(vec4_t);
		}
		bits >>= 1;
	}
	dataSize *= numVertexes;
	data      = (byte *)ri.Hunk_AllocateTempMemory(dataSize);
	dataOfs   = 0;

	// since this is all float, point tmp directly into data
	// 2-entry -> { memb[0], memb[1], 0, 1 }
	// 3-entry -> { memb[0], memb[1], memb[2], 1 }
#define VERTEXSIZE(memb) (sizeof(verts->memb) / sizeof(verts->memb[0]))
#define VERTEXCOPY(memb) \
	do { \
		vec_t *tmp = (vec_t *) (data + dataOfs); \
		for (i = 0; i < numVertexes; i++) \
		{ \
			for (j = 0; j < VERTEXSIZE(memb); j++) { *tmp++ = verts[i].memb[j]; } \
			if (VERTEXSIZE(memb) < 3) { *tmp++ = 0; } \
			if (VERTEXSIZE(memb) < 4) { *tmp++ = 1; } \
		} \
		dataOfs += i * sizeof(vec4_t); \
	} while (0)

	if (stateBits & ATTR_POSITION)
	{
		vbo->ofsXYZ = dataOfs;
		VERTEXCOPY(xyz);
	}

	// feed vertex texcoords
	if (stateBits & ATTR_TEXCOORD)
	{
		vbo->ofsTexCoords = dataOfs;
		VERTEXCOPY(st);
	}

	// feed vertex lightmap texcoords
	if (stateBits & ATTR_LIGHTCOORD)
	{
		vbo->ofsLightCoords = dataOfs;
		VERTEXCOPY(lightmap);
	}

	// feed vertex tangents
	if (stateBits & ATTR_TANGENT)
	{
		vbo->ofsTangents = dataOfs;
		VERTEXCOPY(tangent);
	}

	// feed vertex binormals
	if (stateBits & ATTR_BINORMAL)
	{
		vbo->ofsBinormals = dataOfs;
		VERTEXCOPY(binormal);
	}

	// feed vertex normals
	if (stateBits & ATTR_NORMAL)
	{
		vbo->ofsNormals = dataOfs;
		VERTEXCOPY(normal);
	}

	// feed vertex colors
	if (stateBits & ATTR_COLOR)
	{
		vbo->ofsColors = dataOfs;
		VERTEXCOPY(lightColor);
	}

	vbo->vertexesSize = dataSize;
	vbo->vertexesNum  = numVertexes;

	glGenBuffers(1, &vbo->vertexesVBO);

	glBindBuffer(GL_ARRAY_BUFFER, vbo->vertexesVBO);
	glBufferData(GL_ARRAY_BUFFER, dataSize, data, glUsage);

	glBindBuffer(GL_ARRAY_BUFFER, 0);

	GL_CheckErrors();

	ri.Hunk_FreeTempMemory(data);

	return vbo;
}