Exemple #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();
}
Exemple #2
0
/*
============
R_ShutdownVBOs
============
*/
void R_ShutdownVBOs(void)
{
	int             i, j;
	VBO_t          *vbo;
	IBO_t          *ibo;

	ri.Printf(PRINT_ALL, "------- R_ShutdownVBOs -------\n");

	R_BindNullVBO();
	R_BindNullIBO();


	for(i = 0; i < tr.vbos.currentElements; i++)
	{
		vbo = (VBO_t *) Com_GrowListElement(&tr.vbos, i);

		if(vbo->vertexesVBO)
		{
			glDeleteBuffersARB(1, &vbo->vertexesVBO);
		}
	}

	for(i = 0; i < tr.ibos.currentElements; i++)
	{
		ibo = (IBO_t *) Com_GrowListElement(&tr.ibos, i);

		if(ibo->indexesVBO)
		{
			glDeleteBuffersARB(1, &ibo->indexesVBO);
		}
	}

#if defined(USE_BSP_CLUSTERSURFACE_MERGING)
	if(tr.world)
	{
		for(j = 0; j < MAX_VISCOUNTS; j++)
		{
			// FIXME: clean up this code
			for(i = 0; i < tr.world->clusterVBOSurfaces[j].currentElements; i++)
			{
				srfVBOMesh_t   *vboSurf;

				vboSurf = (srfVBOMesh_t *) Com_GrowListElement(&tr.world->clusterVBOSurfaces[j], i);
				ibo = vboSurf->ibo;

				if(ibo->indexesVBO)
				{
					glDeleteBuffersARB(1, &ibo->indexesVBO);
				}
			}

			Com_DestroyGrowList(&tr.world->clusterVBOSurfaces[j]);
		}
	}
#endif // #if defined(USE_BSP_CLUSTERSURFACE_MERGING)

	Com_DestroyGrowList(&tr.vbos);
	Com_DestroyGrowList(&tr.ibos);
}
Exemple #3
0
/*
============
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();
}
Exemple #4
0
/*
============
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();
}
Exemple #5
0
/*
============
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();
}
Exemple #6
0
/*
============
R_CreateIBO2
============
*/
IBO_t *R_CreateStaticIBO( const char *name, glIndex_t *indexes, int numIndexes )
{
	IBO_t         *ibo;

	if ( !numIndexes )
	{
		return nullptr;
	}

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

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

	ibo = ( IBO_t * ) ri.Hunk_Alloc( sizeof( *ibo ), h_low );
	Com_AddToGrowList( &tr.ibos, ibo );

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

	ibo->indexesSize = numIndexes * sizeof( glIndex_t );
	ibo->indexesNum = numIndexes;

	glGenBuffers( 1, &ibo->indexesVBO );

	R_BindIBO( ibo );

#ifdef GLEW_ARB_buffer_storage
	if( glConfig2.bufferStorageAvailable ) {
		glBufferStorage( GL_ELEMENT_ARRAY_BUFFER, ibo->indexesSize, indexes, 0 );
	} else
#endif
	{
		glBufferData( GL_ELEMENT_ARRAY_BUFFER, ibo->indexesSize, indexes, GL_STATIC_DRAW );
	}
	R_BindNullIBO();

	GL_CheckErrors();

	return ibo;
}
Exemple #7
0
/*
============
R_ShutdownVBOs
============
*/
void R_ShutdownVBOs(void)
{
	int             i;
	VBO_t          *vbo;
	IBO_t          *ibo;

	ri.Printf(PRINT_ALL, "------- R_ShutdownVBOs -------\n");

	R_BindNullVBO();
	R_BindNullIBO();


	for(i = 0; i < tr.numVBOs; i++)
	{
		vbo = tr.vbos[i];

		if(vbo->vertexesVBO)
		{
			qglDeleteBuffersARB(1, &vbo->vertexesVBO);
		}

		//ri.Free(vbo);
	}

	for(i = 0; i < tr.numIBOs; i++)
	{
		ibo = tr.ibos[i];

		if(ibo->indexesVBO)
		{
			qglDeleteBuffersARB(1, &ibo->indexesVBO);
		}

		//ri.Free(ibo);
	}

	tr.numVBOs = 0;
	tr.numIBOs = 0;
}
Exemple #8
0
/**
 * @brief Returns the number of msec spent in the back end
 * @param[out] frontEndMsec
 * @param[out] backEndMsec
 */
void RE_EndFrame(int *frontEndMsec, int *backEndMsec)
{
	swapBuffersCommand_t *cmd;

	if (!tr.registered)
	{
		return;
	}

	cmd = (swapBuffersCommand_t *)R_GetCommandBuffer(sizeof(*cmd));
	if (!cmd)
	{
		return;
	}

	cmd->commandId = RC_SWAP_BUFFERS;

	R_BindNullVBO();
	R_BindNullIBO();

	R_IssueRenderCommands(qtrue);

	// use the other buffers next frame, because another CPU
	// may still be rendering into the current ones
	R_InitNextFrame();

	if (frontEndMsec)
	{
		*frontEndMsec = tr.frontEndMsec;
	}
	tr.frontEndMsec = 0;
	if (backEndMsec)
	{
		*backEndMsec = backEnd.pc.msec;
	}
	backEnd.pc.msec = 0;
}
Exemple #9
0
/*
====================
RE_RegisterModel

Loads in a model for the given name

Zero will be returned if the model fails to load.
An entry will be retained for failed models as an
optimization to prevent disk rescanning if they are
asked for again.
====================
*/
qhandle_t RE_RegisterModel( const char *name )
{
	model_t   *mod;
	unsigned  *buffer;
	int       bufferLen = 0;
	int       lod;
	int       ident;
	qboolean  loaded;
	qhandle_t hModel;
	int       numLoaded;

	if ( !name || !name[ 0 ] )
	{
		ri.Printf( PRINT_ALL, "RE_RegisterModel: NULL name\n" );
		return 0;
	}

	if ( strlen( name ) >= MAX_QPATH )
	{
		Com_Printf( "Model name exceeds MAX_QPATH\n" );
		return 0;
	}

	// search the currently loaded models
	for ( hModel = 1; hModel < tr.numModels; hModel++ )
	{
		mod = tr.models[ hModel ];

		if ( !strcmp( mod->name, name ) )
		{
			if ( mod->type == MOD_BAD )
			{
				return 0;
			}

			return hModel;
		}
	}

	// allocate a new model_t
	if ( ( mod = R_AllocModel() ) == NULL )
	{
		ri.Printf( PRINT_WARNING, "RE_RegisterModel: R_AllocModel() failed for '%s'\n", name );
		return 0;
	}

	// only set the name after the model has been successfully loaded
	Q_strncpyz( mod->name, name, sizeof( mod->name ) );

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

	mod->numLods = 0;

	// load the files
	numLoaded = 0;

#if defined( COMPAT_ET )

	if ( strstr( name, ".mds" ) || strstr( name, ".mdm" ) || strstr( name, ".mdx" ) || strstr( name, ".md5mesh" ) || strstr( name, ".psk" ) )
#else
	if ( strstr( name, ".md5mesh" ) || strstr( name, ".psk" ) )
#endif
	{
		// try loading skeletal file

		loaded = qfalse;
		bufferLen = ri.FS_ReadFile( name, ( void ** ) &buffer );

		if ( buffer )
		{
			loadmodel = mod;

			ident = LittleLong( * ( unsigned * ) buffer );
#if defined( COMPAT_ET )
#if 0

			if ( ident == MDS_IDENT )
			{
				loaded = R_LoadMDS( mod, buffer, name );
			}
			else
#endif
				if ( ident == MDM_IDENT )
				{
					loaded = R_LoadMDM( mod, buffer, name );
				}
				else if ( ident == MDX_IDENT )
				{
					loaded = R_LoadMDX( mod, buffer, name );
				}

#endif

#if defined( USE_REFENTITY_ANIMATIONSYSTEM )

			if ( !Q_strnicmp( ( const char * ) buffer, "MD5Version", 10 ) )
			{
				loaded = R_LoadMD5( mod, buffer, bufferLen, name );
			}
			else if ( !Q_strnicmp( ( const char * ) buffer, PSK_IDENTSTRING, PSK_IDENTLEN ) )
			{
				loaded = R_LoadPSK( mod, buffer, bufferLen, name );
			}

#endif
			ri.FS_FreeFile( buffer );
		}

		if ( loaded )
		{
			// make sure the VBO glState entries are save
			R_BindNullVBO();
			R_BindNullIBO();

			return mod->index;
		}
	}

	for ( lod = MD3_MAX_LODS - 1; lod >= 0; lod-- )
	{
		char filename[ 1024 ];

		strcpy( filename, name );

		if ( lod != 0 )
		{
			char namebuf[ 80 ];

			if ( strrchr( filename, '.' ) )
			{
				*strrchr( filename, '.' ) = 0;
			}

			sprintf( namebuf, "_%d.md3", lod );
			strcat( filename, namebuf );
		}

		filename[ strlen( filename ) - 1 ] = '3';  // try MD3 first
		ri.FS_ReadFile( filename, ( void ** ) &buffer );

		if ( !buffer )
		{
			filename[ strlen( filename ) - 1 ] = 'c';  // try MDC second
			ri.FS_ReadFile( filename, ( void ** ) &buffer );

			if ( !buffer )
			{
				continue;
			}
		}

		loadmodel = mod;

		ident = LittleLong( * ( unsigned * ) buffer );

		if ( ident == MD3_IDENT )
		{
			loaded = R_LoadMD3( mod, lod, buffer, bufferLen, name );
			ri.FS_FreeFile( buffer );
		}

#if defined( COMPAT_ET )
		else if ( ident == MDC_IDENT )
		{
			loaded = R_LoadMDC( mod, lod, buffer, bufferLen, name );
			ri.FS_FreeFile( buffer );
		}

#endif
		else
		{
			ri.FS_FreeFile( buffer );

			ri.Printf( PRINT_WARNING, "RE_RegisterModel: unknown fileid for %s\n", name );
			goto fail;
		}

		if ( !loaded )
		{
			if ( lod == 0 )
			{
				goto fail;
			}
			else
			{
				break;
			}
		}
		else
		{
			// make sure the VBO glState entries are save
			R_BindNullVBO();
			R_BindNullIBO();

			mod->numLods++;
			numLoaded++;
			// if we have a valid model and are biased
			// so that we won't see any higher detail ones,
			// stop loading them
//          if ( lod <= r_lodbias->integer ) {
//              break;
//          }
		}
	}

	// make sure the VBO glState entries are save
	R_BindNullVBO();
	R_BindNullIBO();

	if ( numLoaded )
	{
		// duplicate into higher lod spots that weren't
		// loaded, in case the user changes r_lodbias on the fly
		for ( lod--; lod >= 0; lod-- )
		{
			mod->numLods++;
			mod->mdv[ lod ] = mod->mdv[ lod + 1 ];
		}

		return mod->index;
	}

#ifndef NDEBUG
	else
	{
		ri.Printf( PRINT_WARNING, "couldn't load '%s'\n", name );
	}

#endif

fail:
	// we still keep the model_t around, so if the model name is asked for
	// again, we won't bother scanning the filesystem
	mod->type = MOD_BAD;

	// make sure the VBO glState entries are save
	R_BindNullVBO();
	R_BindNullIBO();

	return 0;
}
Exemple #10
0
/*
============
R_ShutdownVBOs
============
*/
void R_ShutdownVBOs()
{
	int   i;
	VBO_t *vbo;
	IBO_t *ibo;

	ri.Printf( PRINT_DEVELOPER, "------- R_ShutdownVBOs -------\n" );

	if( !glConfig2.mapBufferRangeAvailable ) {
		// nothing
	}
#if defined( GLEW_ARB_buffer_storage ) && defined( GLEW_ARB_sync )
	else if( glConfig2.bufferStorageAvailable &&
		 glConfig2.syncAvailable ) {
		R_BindVBO( tess.vbo );
		R_ShutdownRingbuffer( GL_ARRAY_BUFFER, &tess.vertexRB );
		R_BindIBO( tess.ibo );
		R_ShutdownRingbuffer( GL_ELEMENT_ARRAY_BUFFER, &tess.indexRB );
	}
#endif
	else {
		if( tess.verts != nullptr && tess.verts != tess.vertsBuffer ) {
			R_BindVBO( tess.vbo );
			glUnmapBuffer( GL_ARRAY_BUFFER );
		}

		if( tess.indexes != nullptr && tess.indexes != tess.indexesBuffer ) {
			R_BindIBO( tess.ibo );
			glUnmapBuffer( GL_ELEMENT_ARRAY_BUFFER );
		}
	}

	R_BindNullVBO();
	R_BindNullIBO();

	glDeleteBuffers( 1, &tr.colorGradePBO );

	for ( i = 0; i < tr.vbos.currentElements; i++ )
	{
		vbo = ( VBO_t * ) Com_GrowListElement( &tr.vbos, i );

		if ( vbo->vertexesVBO )
		{
			glDeleteBuffers( 1, &vbo->vertexesVBO );
		}
	}

	for ( i = 0; i < tr.ibos.currentElements; i++ )
	{
		ibo = ( IBO_t * ) Com_GrowListElement( &tr.ibos, i );

		if ( ibo->indexesVBO )
		{
			glDeleteBuffers( 1, &ibo->indexesVBO );
		}
	}

	Com_DestroyGrowList( &tr.vbos );
	Com_DestroyGrowList( &tr.ibos );

	Com_Free_Aligned( tess.vertsBuffer );
	Com_Free_Aligned( tess.indexesBuffer );

	tess.verts = tess.vertsBuffer = nullptr;
	tess.indexes = tess.indexesBuffer = nullptr;
}