示例#1
0
void Gui_Init()
{
    Gui_InitBars();
    Gui_InitNotifier();

    qglGenBuffersARB(1, &crosshairBuffer);
    qglGenBuffersARB(1, &backgroundBuffer);
    qglGenBuffersARB(1, &rectBuffer);
    qglGenTextures(1, &load_screen_tex);
    Gui_FillCrosshairBuffer();
    Gui_FillBackgroundBuffer();

    main_inventory_manager = new gui_InventoryManager();
}
示例#2
0
/*
========================
idJointBuffer::AllocBufferObject
========================
*/
bool idJointBuffer::AllocBufferObject( const float * joints, int numAllocJoints ) {
	assert( apiObject == NULL );
	assert_16_byte_aligned( joints );

	if ( numAllocJoints <= 0 ) {
		idLib::Error( "idJointBuffer::AllocBufferObject: joints = %i", numAllocJoints );
	}

	numJoints = numAllocJoints;

	bool allocationFailed = false;

	const int numBytes = GetAllocedSize();

	GLuint buffer = 0;
	qglGenBuffersARB( 1, &buffer );
	qglBindBufferARB( GL_UNIFORM_BUFFER, buffer );
	qglBufferDataARB( GL_UNIFORM_BUFFER, numBytes, NULL, GL_STREAM_DRAW_ARB );
	qglBindBufferARB( GL_UNIFORM_BUFFER, 0);
	apiObject = reinterpret_cast< void * >( buffer );

	if ( r_showBuffers.GetBool() ) {
		idLib::Printf( "joint buffer alloc %p, api %p (%i joints)\n", this, GetAPIObject(), GetNumJoints() );
	}

	// copy the data
	if ( joints != NULL ) {
		Update( joints, numAllocJoints );
	}

	return !allocationFailed;
}
示例#3
0
void CDynamicBSP::Reset(struct anim_seq_s *seq)
{
    if(m_vbo == 0)
    {
        qglGenBuffersARB(1, &m_vbo);
    }

    switch(m_realloc_state)
    {
        case NEED_REALLOC_TREE_BUFF:
            {
                uint32_t new_buffer_size = m_tree_buffer_size * 1.5;
                uint8_t *new_buffer = (uint8_t*)malloc(new_buffer_size * sizeof(uint8_t));
                if(new_buffer != NULL)
                {
                    free(m_tree_buffer);
                    m_tree_buffer = new_buffer;
                    m_tree_buffer_size = new_buffer_size;
                }
            }
            break;

        case NEED_REALLOC_TEMP_BUFF:
            {
                uint32_t new_buffer_size = m_temp_buffer_size * 1.5;
                uint8_t *new_buffer = (uint8_t*)malloc(new_buffer_size * sizeof(uint8_t));
                if(new_buffer != NULL)
                {
                    free(m_temp_buffer);
                    m_temp_buffer = new_buffer;
                    m_temp_buffer_size = new_buffer_size;
                }
            }
            break;

        case NEED_REALLOC_VERTEX_BUFF:
            {
                uint32_t new_buffer_size = m_vertex_buffer_size * 1.5;
                vertex_p new_buffer = (vertex_p)malloc(new_buffer_size * sizeof(vertex_t));
                if(new_buffer != NULL)
                {
                    free(m_vertex_buffer);
                    m_vertex_buffer = new_buffer;
                    m_vertex_buffer_size = new_buffer_size;
                }
            }
            break;
    };

    m_anim_seq = seq;
    m_temp_allocated = 0;
    m_tree_allocated = 0;
    m_vertex_allocated = 0;
    m_realloc_state = 0;
    m_input_polygons = 0;
    m_added_polygons = 0;
    m_root = this->CreateBSPNode();
}
示例#4
0
/*
============
R_CreateVBO
============
*/
VBO_t          *R_CreateVBO(const char *name, byte * vertexes, int vertexesSize, vboUsage_t usage)
{
	VBO_t          *vbo;
	int				glUsage;

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

		case VBO_USAGE_DYNAMIC:
			glUsage = GL_DYNAMIC_DRAW_ARB;
			break;

		default:
			Com_Error(ERR_FATAL, "bad vboUsage_t given: %i", usage);
			return NULL;
	}

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

	if ( tr.numVBOs == MAX_VBOS ) {
		ri.Error( ERR_DROP, "R_CreateVBO: MAX_VBOS hit\n");
	}

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

	vbo = tr.vbos[tr.numVBOs] = ri.Hunk_Alloc(sizeof(*vbo), h_low);
	tr.numVBOs++;

	memset(vbo, 0, sizeof(*vbo));

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

	vbo->vertexesSize = vertexesSize;

	qglGenBuffersARB(1, &vbo->vertexesVBO);

	qglBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo->vertexesVBO);
	qglBufferDataARB(GL_ARRAY_BUFFER_ARB, vertexesSize, vertexes, glUsage);

	qglBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);

	glState.currentVBO = NULL;

	GL_CheckErrors();

	return vbo;
}
示例#5
0
文件: tr_vbo.c 项目: SonnyJim/ioq3
/*
============
R_CreateIBO
============
*/
IBO_t          *R_CreateIBO(const char *name, byte * indexes, int indexesSize, vboUsage_t usage)
{
	IBO_t          *ibo;
	int				glUsage;

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

		case VBO_USAGE_DYNAMIC:
			glUsage = GL_DYNAMIC_DRAW_ARB;
			break;

		default:
			Com_Error(ERR_FATAL, "bad vboUsage_t given: %i", usage);
			return NULL;
	}

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

	if ( tr.numIBOs == MAX_IBOS ) {
		ri.Error( ERR_DROP, "R_CreateIBO: MAX_IBOS hit");
	}

	R_IssuePendingRenderCommands();

	ibo = tr.ibos[tr.numIBOs] = ri.Hunk_Alloc(sizeof(*ibo), h_low);
	tr.numIBOs++;

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

	ibo->indexesSize = indexesSize;

	qglGenBuffersARB(1, &ibo->indexesVBO);

	qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, ibo->indexesVBO);
	qglBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, indexesSize, indexes, glUsage);

	qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);

	glState.currentIBO = NULL;

	GL_CheckErrors();

	return ibo;
}
示例#6
0
/*
========================
idIndexBuffer::AllocBufferObject
========================
*/
bool idIndexBuffer::AllocBufferObject( const void * data, int allocSize ) {
	assert( apiObject == NULL );
	assert_16_byte_aligned( data );

	if ( allocSize <= 0 ) {
		idLib::Error( "idIndexBuffer::AllocBufferObject: allocSize = %i", allocSize );
	}

	size = allocSize;

	bool allocationFailed = false;

	int numBytes = GetAllocedSize();


	// clear out any previous error
	qglGetError();

	GLuint bufferObject = 0xFFFF;
	qglGenBuffersARB( 1, & bufferObject );
	if ( bufferObject == 0xFFFF ) {
		GLenum error = qglGetError();
		idLib::FatalError( "idIndexBuffer::AllocBufferObject: failed - GL_Error %d", error );
	}
	qglBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, bufferObject );

	// these are rewritten every frame
	qglBufferDataARB( GL_ELEMENT_ARRAY_BUFFER_ARB, numBytes, NULL, bufferUsage );
	apiObject = reinterpret_cast< void * >( bufferObject );

	GLenum err = qglGetError();
	if ( err == GL_OUT_OF_MEMORY ) {
		idLib::Warning( "idIndexBuffer:AllocBufferObject: allocation failed" );
		allocationFailed = true;
	}


	if ( r_showBuffers.GetBool() ) {
		idLib::Printf( "index buffer alloc %p, api %p (%i bytes)\n", this, GetAPIObject(), GetSize() );
	}

	// copy the data
	if ( data != NULL ) {
		Update( data, allocSize );
	}

	return !allocationFailed;
}
示例#7
0
文件: tr_vbo.c 项目: SonnyJim/ioq3
/*
============
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;

	byte           *data;
	int             dataSize;
	int             dataOfs;

	int				glUsage;

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

		case VBO_USAGE_DYNAMIC:
			glUsage = GL_DYNAMIC_DRAW_ARB;
			break;

		default:
			Com_Error(ERR_FATAL, "bad vboUsage_t given: %i", usage);
			return NULL;
	}

	if(!numVertexes)
		return NULL;

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

	if ( tr.numVBOs == MAX_VBOS ) {
		ri.Error( ERR_DROP, "R_CreateVBO2: MAX_VBOS hit");
	}

	R_IssuePendingRenderCommands();

	vbo = tr.vbos[tr.numVBOs] = ri.Hunk_Alloc(sizeof(*vbo), h_low);
	tr.numVBOs++;

	memset(vbo, 0, sizeof(*vbo));

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

	if (usage == VBO_USAGE_STATIC)
	{
		// since these vertex attributes are never altered, interleave them
		vbo->ofs_xyz = 0;
		dataSize = sizeof(verts[0].xyz);

		if(stateBits & ATTR_NORMAL)
		{
			vbo->ofs_normal = dataSize;
			dataSize += sizeof(uint8_t) * 4;
		}

#ifdef USE_VERT_TANGENT_SPACE
		if(stateBits & ATTR_TANGENT)
		{
			vbo->ofs_tangent = dataSize;
			dataSize += sizeof(uint8_t) * 4;
		}
#endif

		if(stateBits & ATTR_TEXCOORD)
		{
			vbo->ofs_st = dataSize;
			dataSize += sizeof(verts[0].st);
		}

		if(stateBits & ATTR_LIGHTCOORD)
		{
			vbo->ofs_lightmap = dataSize;
			dataSize += sizeof(verts[0].lightmap);
		}

		if(stateBits & ATTR_COLOR)
		{
			vbo->ofs_vertexcolor = dataSize;
			dataSize += sizeof(verts[0].vertexColors);
		}

		if(stateBits & ATTR_LIGHTDIRECTION)
		{
			vbo->ofs_lightdir = dataSize;
			dataSize += sizeof(verts[0].lightdir);
		}

		vbo->stride_xyz         = dataSize;
		vbo->stride_normal      = dataSize;
#ifdef USE_VERT_TANGENT_SPACE
		vbo->stride_tangent     = dataSize;
#endif
		vbo->stride_st          = dataSize;
		vbo->stride_lightmap    = dataSize;
		vbo->stride_vertexcolor = dataSize;
		vbo->stride_lightdir    = dataSize;

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

		//ri.Printf(PRINT_ALL, "CreateVBO: %d, %d %d %d %d %d, %d %d %d %d %d\n", dataSize, vbo->ofs_xyz, vbo->ofs_normal, vbo->ofs_st, vbo->ofs_lightmap, vbo->ofs_vertexcolor,
			//vbo->stride_xyz, vbo->stride_normal, vbo->stride_st, vbo->stride_lightmap, vbo->stride_vertexcolor);

		for (i = 0; i < numVertexes; i++)
		{
			// xyz
			memcpy(data + dataOfs, &verts[i].xyz, sizeof(verts[i].xyz));
			dataOfs += sizeof(verts[i].xyz);

			// normal
			if(stateBits & ATTR_NORMAL)
			{
				uint8_t *p = data + dataOfs;

				p[0] = (uint8_t)(verts[i].normal[0] * 127.5f + 128.0f);
				p[1] = (uint8_t)(verts[i].normal[1] * 127.5f + 128.0f);
				p[2] = (uint8_t)(verts[i].normal[2] * 127.5f + 128.0f);
				p[3] = 0;

				dataOfs += sizeof(uint8_t) * 4;
			}

#ifdef USE_VERT_TANGENT_SPACE
			// tangent
			if(stateBits & ATTR_TANGENT)
			{
				vec3_t nxt;
				uint8_t *p = data + dataOfs;

				CrossProduct(verts[i].normal, verts[i].tangent, nxt);

				p[0] = (uint8_t)(verts[i].tangent[0] * 127.5f + 128.0f);
				p[1] = (uint8_t)(verts[i].tangent[1] * 127.5f + 128.0f);
				p[2] = (uint8_t)(verts[i].tangent[2] * 127.5f + 128.0f);				
				p[3] = (uint8_t)(verts[i].tangent[3] * 127.5f + 128.0f);

				dataOfs += sizeof(uint8_t) * 4;
			}
#endif

			// vertex texcoords
			if(stateBits & ATTR_TEXCOORD)
			{
				memcpy(data + dataOfs, &verts[i].st, sizeof(verts[i].st));
				dataOfs += sizeof(verts[i].st);
			}

			// feed vertex lightmap texcoords
			if(stateBits & ATTR_LIGHTCOORD)
			{
				memcpy(data + dataOfs, &verts[i].lightmap, sizeof(verts[i].lightmap));
				dataOfs += sizeof(verts[i].lightmap);
			}

			// feed vertex colors
			if(stateBits & ATTR_COLOR)
			{
				memcpy(data + dataOfs, &verts[i].vertexColors, sizeof(verts[i].vertexColors));
				dataOfs += sizeof(verts[i].vertexColors);
			}

			// feed vertex light directions
			if(stateBits & ATTR_LIGHTDIRECTION)
			{
				memcpy(data + dataOfs, &verts[i].lightdir, sizeof(verts[i].lightdir));
				dataOfs += sizeof(verts[i].lightdir);
			}
		}
	}
	else
	{
		// since these vertex attributes may be changed, put them in flat arrays
		dataSize = sizeof(verts[0].xyz);

		if(stateBits & ATTR_NORMAL)
		{
			dataSize += sizeof(uint8_t) * 4;
		}

#ifdef USE_VERT_TANGENT_SPACE
		if(stateBits & ATTR_TANGENT)
		{
			dataSize += sizeof(uint8_t) * 4;
		}
#endif

		if(stateBits & ATTR_TEXCOORD)
		{
			dataSize += sizeof(verts[0].st);
		}

		if(stateBits & ATTR_LIGHTCOORD)
		{
			dataSize += sizeof(verts[0].lightmap);
		}

		if(stateBits & ATTR_COLOR)
		{
			dataSize += sizeof(verts[0].vertexColors);
		}

		if(stateBits & ATTR_LIGHTDIRECTION)
		{
			dataSize += sizeof(verts[0].lightdir);
		}

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

		vbo->ofs_xyz            = 0;
		vbo->ofs_normal         = 0;
#ifdef USE_VERT_TANGENT_SPACE
		vbo->ofs_tangent        = 0;
#endif
		vbo->ofs_st             = 0;
		vbo->ofs_lightmap       = 0;
		vbo->ofs_vertexcolor    = 0;
		vbo->ofs_lightdir       = 0;

		vbo->stride_xyz         = sizeof(verts[0].xyz);
		vbo->stride_normal      = sizeof(uint8_t) * 4;
#ifdef USE_VERT_TANGENT_SPACE
		vbo->stride_tangent     = sizeof(uint8_t) * 4;
#endif
		vbo->stride_vertexcolor = sizeof(verts[0].vertexColors);
		vbo->stride_st          = sizeof(verts[0].st);
		vbo->stride_lightmap    = sizeof(verts[0].lightmap);
		vbo->stride_lightdir    = sizeof(verts[0].lightdir);

		//ri.Printf(PRINT_ALL, "2CreateVBO: %d, %d %d %d %d %d, %d %d %d %d %d\n", dataSize, vbo->ofs_xyz, vbo->ofs_normal, vbo->ofs_st, vbo->ofs_lightmap, vbo->ofs_vertexcolor,
			//vbo->stride_xyz, vbo->stride_normal, vbo->stride_st, vbo->stride_lightmap, vbo->stride_vertexcolor);

		// xyz
		for (i = 0; i < numVertexes; i++)
		{
			memcpy(data + dataOfs, &verts[i].xyz, sizeof(verts[i].xyz));
			dataOfs += sizeof(verts[i].xyz);
		}

		// normal
		if(stateBits & ATTR_NORMAL)
		{
			vbo->ofs_normal = dataOfs;
			for (i = 0; i < numVertexes; i++)
			{
				uint8_t *p = data + dataOfs;

				p[0] = (uint8_t)(verts[i].normal[0] * 127.5f + 128.0f);
				p[1] = (uint8_t)(verts[i].normal[1] * 127.5f + 128.0f);
				p[2] = (uint8_t)(verts[i].normal[2] * 127.5f + 128.0f);
				p[3] = 0;

				dataOfs += sizeof(uint8_t) * 4;
			}
		}

#ifdef USE_VERT_TANGENT_SPACE
		// tangent
		if(stateBits & ATTR_TANGENT)
		{
			vbo->ofs_tangent = dataOfs;
			for (i = 0; i < numVertexes; i++)
			{
				vec3_t nxt;
				uint8_t *p = data + dataOfs;

				CrossProduct(verts[i].normal, verts[i].tangent, nxt);

				p[0] = (uint8_t)(verts[i].tangent[0] * 127.5f + 128.0f);
				p[1] = (uint8_t)(verts[i].tangent[1] * 127.5f + 128.0f);
				p[2] = (uint8_t)(verts[i].tangent[2] * 127.5f + 128.0f);
				p[3] = (uint8_t)(verts[i].tangent[3] * 127.5f + 128.0f);

				dataOfs += sizeof(uint8_t) * 4;
			}
		}
#endif

		// vertex texcoords
		if(stateBits & ATTR_TEXCOORD)
		{
			vbo->ofs_st = dataOfs;
			for (i = 0; i < numVertexes; i++)
			{
				memcpy(data + dataOfs, &verts[i].st, sizeof(verts[i].st));
				dataOfs += sizeof(verts[i].st);
			}
		}

		// feed vertex lightmap texcoords
		if(stateBits & ATTR_LIGHTCOORD)
		{
			vbo->ofs_lightmap = dataOfs;
			for (i = 0; i < numVertexes; i++)
			{
				memcpy(data + dataOfs, &verts[i].lightmap, sizeof(verts[i].lightmap));
				dataOfs += sizeof(verts[i].lightmap);
			}
		}

		// feed vertex colors
		if(stateBits & ATTR_COLOR)
		{
			vbo->ofs_vertexcolor = dataOfs;
			for (i = 0; i < numVertexes; i++)
			{
				memcpy(data + dataOfs, &verts[i].vertexColors, sizeof(verts[i].vertexColors));
				dataOfs += sizeof(verts[i].vertexColors);
			}
		}

		// feed vertex lightdirs
		if(stateBits & ATTR_LIGHTDIRECTION)
		{
			vbo->ofs_lightdir = dataOfs;
			for (i = 0; i < numVertexes; i++)
			{
				memcpy(data + dataOfs, &verts[i].lightdir, sizeof(verts[i].lightdir));
				dataOfs += sizeof(verts[i].lightdir);
			}
		}
	}


	vbo->vertexesSize = dataSize;

	qglGenBuffersARB(1, &vbo->vertexesVBO);

	qglBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo->vertexesVBO);
	qglBufferDataARB(GL_ARRAY_BUFFER_ARB, dataSize, data, glUsage);

	qglBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);

	glState.currentVBO = NULL;

	GL_CheckErrors();

	ri.Hunk_FreeTempMemory(data);

	return vbo;
}
示例#8
0
文件: r_vbo.c 项目: ewirch/qfusion
/*
* R_CreateMeshVBO
*
* Create two static buffer objects: vertex buffer and elements buffer, the real
* data is uploaded by calling R_UploadVBOVertexData and R_UploadVBOElemData.
*
* Tag allows vertex buffer objects to be grouped and released simultaneously.
*/
mesh_vbo_t *R_CreateMeshVBO( void *owner, int numVerts, int numElems, int numInstances,
	vattribmask_t vattribs, vbo_tag_t tag, vattribmask_t halfFloatVattribs )
{
	int i;
	size_t size;
	GLuint vbo_id;
	vbohandle_t *vboh = NULL;
	mesh_vbo_t *vbo = NULL;
	GLenum array_usage = VBO_ARRAY_USAGE_FOR_TAG(tag);
	GLenum elem_usage = VBO_ELEM_USAGE_FOR_TAG(tag);
	size_t vertexSize;
	vattribbit_t lmattrbit;

	if( !glConfig.ext.vertex_buffer_object )
		return NULL;

	if( !r_free_vbohandles )
		return NULL;

	if( !glConfig.ext.half_float_vertex ) {
		halfFloatVattribs = 0;
	}
	else {
		if( !(halfFloatVattribs & VATTRIB_POSITION_BIT) ) {
			halfFloatVattribs &= ~(VATTRIB_AUTOSPRITE_BIT);
		}

		halfFloatVattribs &= ~VATTRIB_COLORS_BITS;
		halfFloatVattribs &= ~VATTRIB_BONES_BITS;

		// TODO: convert quaternion component of instance_t to half-float
		// when uploading instances data
		halfFloatVattribs &= ~VATTRIB_INSTANCES_BITS;
	}

	vboh = r_free_vbohandles;
	vbo = &r_mesh_vbo[vboh->index];
	memset( vbo, 0, sizeof( *vbo ) );

	// vertex data
	vertexSize = 0;

	vertexSize += FLOAT_VATTRIB_SIZE(VATTRIB_POSITION_BIT, halfFloatVattribs) * 4;

	// normals data
	if( vattribs & VATTRIB_NORMAL_BIT )
	{
		assert( !(vertexSize & 3) );
		vbo->normalsOffset = vertexSize;
		vertexSize += FLOAT_VATTRIB_SIZE(VATTRIB_NORMAL_BIT, halfFloatVattribs) * 4;
	}

	// s-vectors (tangent vectors)
	if( vattribs & VATTRIB_SVECTOR_BIT )
	{
		assert( !(vertexSize & 3) );
		vbo->sVectorsOffset = vertexSize;
		vertexSize += FLOAT_VATTRIB_SIZE(VATTRIB_SVECTOR_BIT, halfFloatVattribs) * 4;
	}

	// texture coordinates
	if( vattribs & VATTRIB_TEXCOORDS_BIT )
	{
		assert( !(vertexSize & 3) );
		vbo->stOffset = vertexSize;
		vertexSize += FLOAT_VATTRIB_SIZE(VATTRIB_TEXCOORDS_BIT, halfFloatVattribs) * 2;
	}

	// lightmap texture coordinates
	lmattrbit = VATTRIB_LMCOORDS0_BIT;
	for( i = 0; i < MAX_LIGHTMAPS/2; i++ ) {
		if( !(vattribs & lmattrbit) ) {
			break;
		}
		assert( !(vertexSize & 3) );
		vbo->lmstOffset[i] = vertexSize;
		vbo->lmstSize[i] = vattribs & VATTRIB_LMCOORDS0_BIT<<1 ? 4 : 2;
		vertexSize += FLOAT_VATTRIB_SIZE(VATTRIB_LMCOORDS0_BIT, halfFloatVattribs) * vbo->lmstSize[i];
		lmattrbit = ( vattribbit_t )( ( vattribmask_t )lmattrbit << 2 );
	}

	// vertex colors
	if( vattribs & VATTRIB_COLOR0_BIT )
	{
		assert( !(vertexSize & 3) );
		vbo->colorsOffset[0] = vertexSize;
		vertexSize += sizeof( int );
	}

	// bones data for skeletal animation
	if( (vattribs & VATTRIB_BONES_BITS) == VATTRIB_BONES_BITS ) {
		assert( SKM_MAX_WEIGHTS == 4 );

		assert( !(vertexSize & 3) );
		vbo->bonesIndicesOffset = vertexSize;
		vertexSize += sizeof( int );

		assert( !(vertexSize & 3) );
		vbo->bonesWeightsOffset = vertexSize;
		vertexSize += sizeof( int );
	}

	// autosprites
	// FIXME: autosprite2 requires waaaay too much data for such a trivial
	// transformation..
	if( (vattribs & VATTRIB_AUTOSPRITE_BIT) == VATTRIB_AUTOSPRITE_BIT ) {
		assert( !(vertexSize & 3) );
		vbo->spritePointsOffset = vertexSize;
		vertexSize += FLOAT_VATTRIB_SIZE(VATTRIB_AUTOSPRITE_BIT, halfFloatVattribs) * 4;
	}

	size = vertexSize * numVerts;


	// instances data
	if( ( (vattribs & VATTRIB_INSTANCES_BITS) == VATTRIB_INSTANCES_BITS ) && 
		numInstances && glConfig.ext.instanced_arrays ) {
		assert( !(vertexSize & 3) );
		vbo->instancesOffset = size;
		size += numInstances * sizeof( GLfloat ) * 8;
	}

	// pre-allocate vertex buffer
	vbo_id = 0;
	qglGenBuffersARB( 1, &vbo_id );
	if( !vbo_id )
		goto error;
	vbo->vertexId = vbo_id;

	RB_BindArrayBuffer( vbo->vertexId );
	qglBufferDataARB( GL_ARRAY_BUFFER_ARB, size, NULL, array_usage );
	if( qglGetError () == GL_OUT_OF_MEMORY )
		goto error;

	vbo->arrayBufferSize = size;

	// pre-allocate elements buffer
	vbo_id = 0;
	qglGenBuffersARB( 1, &vbo_id );
	if( !vbo_id )
		goto error;
	vbo->elemId = vbo_id;

	size = numElems * sizeof( elem_t );
	RB_BindElementArrayBuffer( vbo->elemId );
	qglBufferDataARB( GL_ELEMENT_ARRAY_BUFFER_ARB, size, NULL, elem_usage );
	if( qglGetError () == GL_OUT_OF_MEMORY )
		goto error;

	vbo->elemBufferSize = size;

	r_free_vbohandles = vboh->next;

	// link to the list of active vbo handles
	vboh->prev = &r_vbohandles_headnode;
	vboh->next = r_vbohandles_headnode.next;
	vboh->next->prev = vboh;
	vboh->prev->next = vboh;

	r_num_active_vbos++;

	vbo->registrationSequence = rsh.registrationSequence;
	vbo->vertexSize = vertexSize;
	vbo->numVerts = numVerts;
	vbo->numElems = numElems;
	vbo->owner = owner;
	vbo->index = vboh->index + 1;
	vbo->tag = tag;
	vbo->halfFloatAttribs = halfFloatVattribs;

	return vbo;

error:
	if( vbo )
		R_ReleaseMeshVBO( vbo );

	RB_BindArrayBuffer( 0 );
	RB_BindElementArrayBuffer( 0 );

	return NULL;
}
/*
===========
idVertexCache::Alloc
===========
*/
void idVertexCache::Alloc(void *data, int size, vertCache_t **buffer, bool indexBuffer)
{
	vertCache_t	*block;

	if (size <= 0) {
		common->Error("idVertexCache::Alloc: size = %i\n", size);
	}

	// if we can't find anything, it will be NULL
	*buffer = NULL;

	// if we don't have any remaining unused headers, allocate some more
	if (freeStaticHeaders.next == &freeStaticHeaders) {

		for (int i = 0; i < EXPAND_HEADERS; i++) {
			block = headerAllocator.Alloc();
			block->next = freeStaticHeaders.next;
			block->prev = &freeStaticHeaders;
			block->next->prev = block;
			block->prev->next = block;

			if (!virtualMemory) {
				qglGenBuffersARB(1, & block->vbo);
			}
		}
	}

	// move it from the freeStaticHeaders list to the staticHeaders list
	block = freeStaticHeaders.next;
	block->next->prev = block->prev;
	block->prev->next = block->next;
	block->next = staticHeaders.next;
	block->prev = &staticHeaders;
	block->next->prev = block;
	block->prev->next = block;

	block->size = size;
	block->offset = 0;
	block->tag = TAG_USED;

	// save data for debugging
	staticAllocThisFrame += block->size;
	staticCountThisFrame++;
	staticCountTotal++;
	staticAllocTotal += block->size;

	// this will be set to zero when it is purged
	block->user = buffer;
	*buffer = block;

	// allocation doesn't imply used-for-drawing, because at level
	// load time lots of things may be created, but they aren't
	// referenced by the GPU yet, and can be purged if needed.
	block->frameUsed = currentFrame - NUM_VERTEX_FRAMES;

	block->indexBuffer = indexBuffer;

	// copy the data
	if (block->vbo) {
		if (indexBuffer) {
			qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, block->vbo);
			qglBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, (GLsizeiptrARB)size, data, GL_STATIC_DRAW_ARB);
		} else {
			qglBindBufferARB(GL_ARRAY_BUFFER_ARB, block->vbo);

			if (allocatingTempBuffer) {
				qglBufferDataARB(GL_ARRAY_BUFFER_ARB, (GLsizeiptrARB)size, data, GL_STREAM_DRAW_ARB);
			} else {
				qglBufferDataARB(GL_ARRAY_BUFFER_ARB, (GLsizeiptrARB)size, data, GL_STATIC_DRAW_ARB);
			}
		}
	} else {
		block->virtMem = Mem_Alloc(size);
		SIMDProcessor->Memcpy(block->virtMem, data, size);
	}
}
示例#10
0
/*
============
R_CreateIBO2
============
*/
IBO_t          *R_CreateIBO2(const char *name, int numTriangles, srfTriangle_t * triangles, vboUsage_t usage)
{
	IBO_t          *ibo;
	int             i, j;

	byte           *indexes;
	int             indexesSize;
	int             indexesOfs;

	srfTriangle_t  *tri;
	glIndex_t       index;
	int				glUsage;

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

		case VBO_USAGE_DYNAMIC:
			glUsage = GL_DYNAMIC_DRAW_ARB;
			break;

		default:
			Com_Error(ERR_FATAL, "bad vboUsage_t given: %i", usage);
			return NULL;
	}

	if(!numTriangles)
		return NULL;

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

	if ( tr.numIBOs == MAX_IBOS ) {
		ri.Error( ERR_DROP, "R_CreateIBO2: MAX_IBOS hit\n");
	}

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

	ibo = tr.ibos[tr.numIBOs] = ri.Hunk_Alloc(sizeof(*ibo), h_low);
	tr.numIBOs++;

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

	indexesSize = numTriangles * 3 * sizeof(int);
	indexes = ri.Hunk_AllocateTempMemory(indexesSize);
	indexesOfs = 0;

	for(i = 0, tri = triangles; i < numTriangles; i++, tri++)
	{
		for(j = 0; j < 3; j++)
		{
			index = tri->indexes[j];
			memcpy(indexes + indexesOfs, &index, sizeof(glIndex_t));
			indexesOfs += sizeof(glIndex_t);
		}
	}

	ibo->indexesSize = indexesSize;

	qglGenBuffersARB(1, &ibo->indexesVBO);

	qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, ibo->indexesVBO);
	qglBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, indexesSize, indexes, glUsage);

	qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);

	glState.currentIBO = NULL;

	GL_CheckErrors();

	ri.Hunk_FreeTempMemory(indexes);

	return ibo;
}