示例#1
0
/*
* Mod_AliasBuildStaticVBOForMesh
* 
* Builds a static vertex buffer object for given alias model mesh
*/
static void Mod_AliasBuildStaticVBOForMesh( maliasmesh_t *mesh )
{
	int i;
	mesh_t aliasmesh;
	vattribmask_t vattribs;
	
	vattribs = VATTRIB_TEXCOORDS_BIT | VATTRIB_NORMAL_BIT | VATTRIB_SVECTOR_BIT;
	for( i = 0; i < mesh->numskins; i++ ) {
		vattribs |= mesh->skins[i].shader->vattribs;
	}

	mesh->vbo = R_CreateMeshVBO( ( void * )mesh, 
		mesh->numverts, mesh->numtris * 3, 0, vattribs, VBO_TAG_MODEL );

	if( !mesh->vbo ) {
		return;
	}

	memset( &aliasmesh, 0, sizeof( aliasmesh ) );

	aliasmesh.elems = mesh->elems;
	aliasmesh.numElems = mesh->numtris * 3;
	aliasmesh.numVerts = mesh->numverts;

	aliasmesh.xyzArray = mesh->xyzArray;
	aliasmesh.stArray = mesh->stArray;
	aliasmesh.normalsArray = mesh->normalsArray;
	aliasmesh.sVectorsArray = mesh->sVectorsArray;

	R_UploadVBOVertexData( mesh->vbo, 0, vattribs, &aliasmesh, VBO_HINT_NONE );
	R_UploadVBOElemData( mesh->vbo, 0, 0, &aliasmesh, VBO_HINT_NONE );
}
示例#2
0
/*
* Mod_SkeletalBuildStaticVBOForMesh
* 
* Builds a static vertex buffer object for given skeletal model mesh
*/
static void Mod_SkeletalBuildStaticVBOForMesh( mskmesh_t *mesh )
{
	mesh_t skmmesh;
	vattribmask_t vattribs;
	
	vattribs = VATTRIB_POSITION_BIT | VATTRIB_TEXCOORDS_BIT | VATTRIB_NORMAL_BIT | VATTRIB_SVECTOR_BIT;
	vattribs |= VATTRIB_BONES_BITS;
	vattribs |= mesh->skin.shader->vattribs;

	mesh->vbo = R_CreateMeshVBO( ( void * )mesh, 
		mesh->numverts, mesh->numtris * 3, 0, vattribs, VBO_TAG_MODEL, vattribs );

	if( !mesh->vbo ) {
		return;
	}

	memset( &skmmesh, 0, sizeof( skmmesh ) );

	skmmesh.elems = mesh->elems;
	skmmesh.numElems = mesh->numtris * 3;
	skmmesh.numVerts = mesh->numverts;

	skmmesh.xyzArray = mesh->xyzArray;
	skmmesh.stArray = mesh->stArray;
	skmmesh.normalsArray = mesh->normalsArray;
	skmmesh.sVectorsArray = mesh->sVectorsArray;

	R_UploadVBOVertexData( mesh->vbo, 0, vattribs, &skmmesh, VBO_HINT_NONE ); 
	R_UploadVBOElemData( mesh->vbo, 0, 0, &skmmesh, VBO_HINT_NONE );
	if( glConfig.maxGLSLBones > 0 ) {
	    R_UploadVBOBonesData( mesh->vbo, 0, mesh->numverts, mesh->blendIndices, mesh->blendWeights );
	}
}
示例#3
0
/*
* Mod_AliasBuildStaticVBOForMesh
* 
* Builds a static vertex buffer object for given alias model mesh
*/
static void Mod_AliasBuildStaticVBOForMesh( maliasmesh_t *mesh )
{
	mesh_t aliasmesh;

	mesh->vbo = R_CreateStaticMeshVBO( ( void * )mesh, 
		mesh->numverts, mesh->numtris * 3, MF_STCOORDS | (mesh->sVectorsArray ? MF_SVECTORS : 0), VBO_TAG_MODEL );
	if( !mesh->vbo ) {
		return;
	}

	aliasmesh.elems = mesh->elems;
	aliasmesh.numElems = mesh->numtris * 3;
	aliasmesh.numVerts = mesh->numverts;

	aliasmesh.xyzArray = mesh->xyzArray;
	aliasmesh.stArray = mesh->stArray;
	aliasmesh.normalsArray = mesh->normalsArray;
	aliasmesh.sVectorsArray = mesh->sVectorsArray;

	R_UploadVBOVertexData( mesh->vbo, 0, &aliasmesh ); 
	R_UploadVBOElemData( mesh->vbo, 0, 0, &aliasmesh );
}
示例#4
0
/*
* RB_UploadMesh
*/
void RB_UploadMesh( const mesh_t *mesh )
{
	int stream;
	mesh_vbo_t *vbo;
	vboSlice_t *offset;
	vbo_hint_t vbo_hint = VBO_HINT_NONE;
	int numVerts = mesh->numVerts, numElems = mesh->numElems;

	assert( rb.currentVBOId < RB_VBO_NONE );
	if( rb.currentVBOId >= RB_VBO_NONE ) {
		return;
	}
	
	if( rb.currentVBOId == RB_VBO_STREAM_QUAD ) {
		numElems = numVerts/4*6;
	} else if( !numElems && rb.currentVBOId == RB_VBO_STREAM ) {
		numElems = (max(numVerts, 2) - 2) * 3;
	}

	if( !numVerts || !numElems ) {
		return;
	}

	vbo = rb.currentVBO;
	stream = -rb.currentVBOId - 1;
	offset = &rb.streamOffset[stream];

	if( offset->firstVert+offset->numVerts+numVerts > MAX_STREAM_VBO_VERTS || 
		offset->firstElem+offset->numVerts+numElems > MAX_STREAM_VBO_ELEMENTS ) {

		RB_DrawElements( offset->firstVert, offset->numVerts, 
			offset->firstElem, offset->numElems );

		R_DiscardVBOVertexData( vbo );
		if( rb.currentVBOId != RB_VBO_STREAM_QUAD ) {
			R_DiscardVBOElemData( vbo );
		}

		offset->firstVert = 0;
		offset->firstElem = 0;
		offset->numVerts = 0;
		offset->numElems = 0;
	}

	if( numVerts > MAX_STREAM_VBO_VERTS ||
		numElems > MAX_STREAM_VBO_ELEMENTS ) {
		// FIXME: do something about this?
		return;
	}

	if( rb.currentVBOId == RB_VBO_STREAM_QUAD ) {
		vbo_hint = VBO_HINT_ELEMS_QUAD;

		// quad indices are stored in a static vbo, don't call R_UploadVBOElemData
	} else {
		if( mesh->elems ) {
			vbo_hint = VBO_HINT_NONE;
		} else if( rb.currentVBOId == RB_VBO_STREAM ) {
			vbo_hint = VBO_HINT_ELEMS_TRIFAN;
		} else {
			assert( 0 );
		}
		R_UploadVBOElemData( vbo, offset->firstVert + offset->numVerts, 
			offset->firstElem + offset->numElems, mesh, vbo_hint );
	}

	R_UploadVBOVertexData( vbo, offset->firstVert + offset->numVerts, 
		rb.currentVAttribs, mesh, vbo_hint );

	offset->numElems += numElems;
	offset->numVerts += numVerts;
}
示例#5
0
文件: r_sky.c 项目: adem4ik/qfusion
/*
* Gen_BoxSide
*
* I don't know exactly what Q3A does for skybox texturing, but
* this is at least fairly close.  We tile the texture onto the
* inside of a large sphere, and put the camera near the top of
* the sphere. We place the box around the camera, and cast rays
* through the box verts to the sphere to find the texture coordinates.
*/
static void Gen_BoxSide( skydome_t *skydome, int side, vec3_t orig, vec3_t drow, vec3_t dcol ) {
	vec3_t pos, w, row, norm;
	float *v, *n, *st = NULL, *st2;
	int r, c;
	float t, d, d2, b, b2, q[2], s;
	elem_t *elem;
	mesh_t *mesh = &( skydome->meshes[side] );

	s = 1.0 / ( SIDE_SIZE - 1 );
	d = EYE_RAD; // sphere center to camera distance
	d2 = d * d;
	b = SPHERE_RAD; // sphere radius
	b2 = b * b;
	q[0] = 1.0 / ( 2.0 * SCALE_S );
	q[1] = 1.0 / ( 2.0 * SCALE_T );

	v = mesh->xyzArray[0];
	n = mesh->normalsArray[0];
	if( side != 5 ) {
		st = skydome->sphereStCoords[side][0];
	}
	st2 = skydome->linearStCoords[side][0];

	VectorCopy( orig, row );

//	CrossProduct( dcol, drow, norm );
//	VectorNormalize( norm );
	VectorClear( norm );

	for( r = 0; r < SIDE_SIZE; r++ ) {
		VectorCopy( row, pos );
		for( c = 0; c < SIDE_SIZE; c++ ) {
			// pos points from eye to vertex on box
			VectorCopy( pos, v );
			VectorCopy( pos, w );

			// Normalize pos -> w
			VectorNormalize( w );

			// Find distance along w to sphere
			t = sqrt( d2 * ( w[2] * w[2] - 1.0 ) + b2 ) - d * w[2];
			w[0] *= t;
			w[1] *= t;

			if( st ) {
				// use x and y on sphere as s and t
				// minus is here so skies scoll in correct (Q3A's) direction
				st[0] = -w[0] * q[0];
				st[1] = -w[1] * q[1];

				// avoid bilerp seam
				st[0] = ( bound( -1, st[0], 1 ) + 1.0 ) * 0.5;
				st[1] = ( bound( -1, st[1], 1 ) + 1.0 ) * 0.5;
			}

			st2[0] = c * s;
			st2[1] = 1.0 - r * s;

			VectorAdd( pos, dcol, pos );
			VectorCopy( norm, n );

			v[3] = 0; // set w-coordinate to 0 for infinite farclip
			n[3] = 0;

			v += 4;
			n += 4;
			if( st ) {
				st += 2;
			}
			st2 += 2;
		}

		VectorAdd( row, drow, row );
	}

	// elements in tristrip order
	elem = mesh->elems;
	for( r = 0; r < SIDE_SIZE - 1; r++ ) {
		for( c = 0; c < SIDE_SIZE - 1; c++ ) {
			elem[0] = r * SIDE_SIZE + c;
			elem[1] = elem[4] = elem[0] + SIDE_SIZE;
			elem[2] = elem[3] = elem[0] + 1;
			elem[5] = elem[1] + 1;
			elem += 6;
		}
	}

	// upload two static VBO's for each side except for the bottom one
	// which only has 1 side for skybox
	if( side != 5 ) {
		mesh->stArray = skydome->sphereStCoords[side];
		R_UploadVBOVertexData( skydome->sphereVbos[side], 0, SKYDOME_VATTRIBS, mesh );
		R_UploadVBOElemData( skydome->sphereVbos[side], 0, 0, mesh );
	}

	skydome->meshes[side].stArray = skydome->linearStCoords[side];
	R_UploadVBOVertexData( skydome->linearVbos[side], 0, SKYDOME_VATTRIBS, mesh );
	R_UploadVBOElemData( skydome->linearVbos[side], 0, 0, mesh );
}