Beispiel #1
0
/*
=============
RB_SurfacePolychain
=============
*/
static void RB_SurfacePolychain( srfPoly_t *p ) {
	int		i;
	int		numv;

	RB_CheckVao(tess.vao);

	RB_CHECKOVERFLOW( p->numVerts, 3*(p->numVerts - 2) );

	// fan triangles into the tess array
	numv = tess.numVertexes;
	for ( i = 0; i < p->numVerts; i++ ) {
		VectorCopy( p->verts[i].xyz, tess.xyz[numv] );
		tess.texCoords[numv][0] = p->verts[i].st[0];
		tess.texCoords[numv][1] = p->verts[i].st[1];
		tess.color[numv][0] = (int)p->verts[i].modulate[0] * 257;
		tess.color[numv][1] = (int)p->verts[i].modulate[1] * 257;
		tess.color[numv][2] = (int)p->verts[i].modulate[2] * 257;
		tess.color[numv][3] = (int)p->verts[i].modulate[3] * 257;

		numv++;
	}

	// generate fan indexes into the tess array
	for ( i = 0; i < p->numVerts-2; i++ ) {
		tess.indexes[tess.numIndexes + 0] = tess.numVertexes;
		tess.indexes[tess.numIndexes + 1] = tess.numVertexes + i + 1;
		tess.indexes[tess.numIndexes + 2] = tess.numVertexes + i + 2;
		tess.numIndexes += 3;
	}

	tess.numVertexes = numv;
}
Beispiel #2
0
static void DoRailCore( const vec3_t start, const vec3_t end, const vec3_t up, float len, float spanWidth )
{
	float		spanWidth2;
	int			vbase;
	float		t = len / 256.0f;

	RB_CheckVao(tess.vao);

	RB_CHECKOVERFLOW( 4, 6 );

	vbase = tess.numVertexes;

	spanWidth2 = -spanWidth;

	// FIXME: use quad stamp?
	VectorMA( start, spanWidth, up, tess.xyz[tess.numVertexes] );
	tess.texCoords[tess.numVertexes][0] = 0;
	tess.texCoords[tess.numVertexes][1] = 0;
	tess.color[tess.numVertexes][0] = backEnd.currentEntity->e.shaderRGBA[0] * 0.25f * 257.0f;
	tess.color[tess.numVertexes][1] = backEnd.currentEntity->e.shaderRGBA[1] * 0.25f * 257.0f;
	tess.color[tess.numVertexes][2] = backEnd.currentEntity->e.shaderRGBA[2] * 0.25f * 257.0f;
	tess.numVertexes++;

	VectorMA( start, spanWidth2, up, tess.xyz[tess.numVertexes] );
	tess.texCoords[tess.numVertexes][0] = 0;
	tess.texCoords[tess.numVertexes][1] = 1;
	tess.color[tess.numVertexes][0] = backEnd.currentEntity->e.shaderRGBA[0] * 257;
	tess.color[tess.numVertexes][1] = backEnd.currentEntity->e.shaderRGBA[1] * 257;
	tess.color[tess.numVertexes][2] = backEnd.currentEntity->e.shaderRGBA[2] * 257;
	tess.numVertexes++;

	VectorMA( end, spanWidth, up, tess.xyz[tess.numVertexes] );

	tess.texCoords[tess.numVertexes][0] = t;
	tess.texCoords[tess.numVertexes][1] = 0;
	tess.color[tess.numVertexes][0] = backEnd.currentEntity->e.shaderRGBA[0] * 257;
	tess.color[tess.numVertexes][1] = backEnd.currentEntity->e.shaderRGBA[1] * 257;
	tess.color[tess.numVertexes][2] = backEnd.currentEntity->e.shaderRGBA[2] * 257;
	tess.numVertexes++;

	VectorMA( end, spanWidth2, up, tess.xyz[tess.numVertexes] );
	tess.texCoords[tess.numVertexes][0] = t;
	tess.texCoords[tess.numVertexes][1] = 1;
	tess.color[tess.numVertexes][0] = backEnd.currentEntity->e.shaderRGBA[0] * 257;
	tess.color[tess.numVertexes][1] = backEnd.currentEntity->e.shaderRGBA[1] * 257;
	tess.color[tess.numVertexes][2] = backEnd.currentEntity->e.shaderRGBA[2] * 257;
	tess.numVertexes++;

	tess.indexes[tess.numIndexes++] = vbase;
	tess.indexes[tess.numIndexes++] = vbase + 1;
	tess.indexes[tess.numIndexes++] = vbase + 2;

	tess.indexes[tess.numIndexes++] = vbase + 2;
	tess.indexes[tess.numIndexes++] = vbase + 1;
	tess.indexes[tess.numIndexes++] = vbase + 3;
}
const void     *RB_Draw2dPolys( const void *data )
{
	const poly2dCommand_t *cmd;
	shader_t              *shader;
	int                   i;

	cmd = ( const poly2dCommand_t * ) data;

	if ( !backEnd.projection2D )
	{
		RB_SetGL2D();
	}

	shader = cmd->shader;

	if ( shader != tess.shader )
	{
		if ( tess.numIndexes )
		{
			RB_EndSurface();
		}

		backEnd.currentEntity = &backEnd.entity2D;
		RB_BeginSurface( shader, 0 );
	}

	RB_CHECKOVERFLOW( cmd->numverts, ( cmd->numverts - 2 ) * 3 );

	for ( i = 0; i < cmd->numverts - 2; i++ )
	{
		tess.indexes[ tess.numIndexes + 0 ] = tess.numVertexes;
		tess.indexes[ tess.numIndexes + 1 ] = tess.numVertexes + i + 1;
		tess.indexes[ tess.numIndexes + 2 ] = tess.numVertexes + i + 2;
		tess.numIndexes += 3;
	}

	for ( i = 0; i < cmd->numverts; i++ )
	{
		tess.xyz[ tess.numVertexes ].v[ 0 ] = cmd->verts[ i ].xyz[ 0 ];
		tess.xyz[ tess.numVertexes ].v[ 1 ] = cmd->verts[ i ].xyz[ 1 ];
		tess.xyz[ tess.numVertexes ].v[ 2 ] = 0;

		tess.texCoords0[ tess.numVertexes ].v[ 0 ] = cmd->verts[ i ].st[ 0 ];
		tess.texCoords0[ tess.numVertexes ].v[ 1 ] = cmd->verts[ i ].st[ 1 ];

		tess.vertexColors[ tess.numVertexes ].v[ 0 ] = cmd->verts[ i ].modulate[ 0 ];
		tess.vertexColors[ tess.numVertexes ].v[ 1 ] = cmd->verts[ i ].modulate[ 1 ];
		tess.vertexColors[ tess.numVertexes ].v[ 2 ] = cmd->verts[ i ].modulate[ 2 ];
		tess.vertexColors[ tess.numVertexes ].v[ 3 ] = cmd->verts[ i ].modulate[ 3 ];
		tess.numVertexes++;
	}

	return ( const void * )( cmd + 1 );
}
Beispiel #4
0
static void FillCloudySkySide( const int mins[2], const int maxs[2], qboolean addIndexes )
{
    int s, t;
    int vertexStart = tess.numVertexes;
    int tHeight, sWidth;

    tHeight = maxs[1] - mins[1] + 1;
    sWidth = maxs[0] - mins[0] + 1;

    RB_CHECKOVERFLOW( ( maxs[ 0 ] - mins[ 0 ] ) * ( maxs[ 1 ] - mins[ 1 ] ), ( sWidth - 1 ) * ( tHeight - 1 ) * 6 );

    for ( t = mins[1]+HALF_SKY_SUBDIVISIONS; t <= maxs[1]+HALF_SKY_SUBDIVISIONS; t++ )
    {
        for ( s = mins[0]+HALF_SKY_SUBDIVISIONS; s <= maxs[0]+HALF_SKY_SUBDIVISIONS; s++ )
        {
            VectorAdd( s_skyPoints[t][s], backEnd.viewParms.or.origin, tess.xyz[tess.numVertexes] );
            tess.texCoords[tess.numVertexes][0][0] = s_skyTexCoords[t][s][0];
            tess.texCoords[tess.numVertexes][0][1] = s_skyTexCoords[t][s][1];

            tess.numVertexes++;

            if ( tess.numVertexes >= SHADER_MAX_VERTEXES )
            {
                ri.Error( ERR_DROP, "SHADER_MAX_VERTEXES hit in FillCloudySkySide()" );
            }
        }
    }

    // only add indexes for one pass, otherwise it would draw multiple times for each pass
    if ( addIndexes ) {
        for ( t = 0; t < tHeight-1; t++ )
        {
            for ( s = 0; s < sWidth-1; s++ )
            {
                tess.indexes[tess.numIndexes] = vertexStart + s + t * ( sWidth );
                tess.numIndexes++;
                tess.indexes[tess.numIndexes] = vertexStart + s + ( t + 1 ) * ( sWidth );
                tess.numIndexes++;
                tess.indexes[tess.numIndexes] = vertexStart + s + 1 + t * ( sWidth );
                tess.numIndexes++;

                tess.indexes[tess.numIndexes] = vertexStart + s + ( t + 1 ) * ( sWidth );
                tess.numIndexes++;
                tess.indexes[tess.numIndexes] = vertexStart + s + 1 + ( t + 1 ) * ( sWidth );
                tess.numIndexes++;
                tess.indexes[tess.numIndexes] = vertexStart + s + 1 + t * ( sWidth );
                tess.numIndexes++;
            }
        }
    }
}
Beispiel #5
0
static void FillCloudySkySide(const int mins[2], const int maxs[2], qboolean addIndexes)
{
	int s, t;
	int vertexStart = tess.numVertexes;
	int tHeight     = maxs[1] - mins[1] + 1;
	int sWidth      = maxs[0] - mins[0] + 1;

	// overflow check
	RB_CHECKOVERFLOW((maxs[0] - mins[0]) * (maxs[1] - mins[1]), (sWidth - 1) * (tHeight - 1) * 6);

	for (t = mins[1] + HALF_SKY_SUBDIVISIONS; t <= maxs[1] + HALF_SKY_SUBDIVISIONS; t++)
	{
		for (s = mins[0] + HALF_SKY_SUBDIVISIONS; s <= maxs[0] + HALF_SKY_SUBDIVISIONS; s++)
		{
			VectorAdd(s_skyPoints[t][s], backEnd.viewParms.orientation.origin, tess.xyz[tess.numVertexes].v);
			tess.texCoords0[tess.numVertexes].v[0] = s_skyTexCoords[t][s][0];
			tess.texCoords0[tess.numVertexes].v[1] = s_skyTexCoords[t][s][1];

			tess.numVertexes++;

			if (tess.numVertexes >= tess.maxShaderVerts)
			{
				Ren_Drop("tess.maxShaderVerts(%i) hit in FillCloudySkySide()\n", tess.maxShaderVerts);
			}
		}
	}

	// only add indexes for one pass, otherwise it would draw multiple times for each pass
	if (addIndexes)
	{
		for (t = 0; t < tHeight - 1; t++)
		{
			for (s = 0; s < sWidth - 1; s++)
			{
				tess.indexes[tess.numIndexes] = vertexStart + s + t * (sWidth);
				tess.numIndexes++;
				tess.indexes[tess.numIndexes] = vertexStart + s + (t + 1) * (sWidth);
				tess.numIndexes++;
				tess.indexes[tess.numIndexes] = vertexStart + s + 1 + t * (sWidth);
				tess.numIndexes++;

				tess.indexes[tess.numIndexes] = vertexStart + s + (t + 1) * (sWidth);
				tess.numIndexes++;
				tess.indexes[tess.numIndexes] = vertexStart + s + 1 + (t + 1) * (sWidth);
				tess.numIndexes++;
				tess.indexes[tess.numIndexes] = vertexStart + s + 1 + t * (sWidth);
				tess.numIndexes++;
			}
		}
	}
}
Beispiel #6
0
/*
=============
RB_SurfaceMesh
=============
*/
static void RB_SurfaceMesh(mdvSurface_t *surface) {
	int				j;
	float			backlerp;
	mdvSt_t			*texCoords;
	int				Bob, Doug;
	int				numVerts;

	if (  backEnd.currentEntity->e.oldframe == backEnd.currentEntity->e.frame ) {
		backlerp = 0;
	} else  {
		backlerp = backEnd.currentEntity->e.backlerp;
	}

	RB_CheckVao(tess.vao);

	RB_CHECKOVERFLOW( surface->numVerts, surface->numIndexes );

	LerpMeshVertexes (surface, backlerp);

	Bob = tess.numIndexes;
	Doug = tess.numVertexes;
	for (j = 0 ; j < surface->numIndexes ; j++) {
		tess.indexes[Bob + j] = Doug + surface->indexes[j];
	}
	tess.numIndexes += surface->numIndexes;

	texCoords = surface->st;

	numVerts = surface->numVerts;
	for ( j = 0; j < numVerts; j++ ) {
		tess.texCoords[Doug + j][0] = texCoords[j].st[0];
		tess.texCoords[Doug + j][1] = texCoords[j].st[1];
		// FIXME: fill in lightmapST for completeness?
	}

	tess.numVertexes += surface->numVerts;

}
Beispiel #7
0
/*
 * RB_StretchPic
 */
const void *
RB_StretchPic(const void *data)
{
	const stretchPicCommand_t *cmd;
	material_t *shader;
	int numVerts, numIndexes;

	cmd = (const stretchPicCommand_t*)data;

	/* FIXME: HUGE hack */
	if(glRefConfig.framebufferObject && !glState.currentFBO){
		if(backEnd.framePostProcessed){
			FBO_Bind(tr.screenScratchFbo);
		}else{
			FBO_Bind(tr.renderFbo);
		}
	}

	RB_SetGL2D();

	shader = cmd->shader;
	if(shader != tess.shader){
		if(tess.numIndexes){
			RB_EndSurface();
		}
		backEnd.currentEntity = &backEnd.entity2D;
		RB_BeginSurface(shader, 0);
	}

	RB_CHECKOVERFLOW(4, 6);
	numVerts = tess.numVertexes;
	numIndexes = tess.numIndexes;

	tess.numVertexes += 4;
	tess.numIndexes += 6;

	tess.indexes[ numIndexes ] = numVerts + 3;
	tess.indexes[ numIndexes + 1 ]	= numVerts + 0;
	tess.indexes[ numIndexes + 2 ]	= numVerts + 2;
	tess.indexes[ numIndexes + 3 ]	= numVerts + 2;
	tess.indexes[ numIndexes + 4 ]	= numVerts + 0;
	tess.indexes[ numIndexes + 5 ]	= numVerts + 1;

	{
		Vec4 color;

		scalev34(backEnd.color2D, 1.0f / 255.0f, color);

		copyv34(color, tess.vertexColors[ numVerts ]);
		copyv34(color, tess.vertexColors[ numVerts + 1]);
		copyv34(color, tess.vertexColors[ numVerts + 2]);
		copyv34(color, tess.vertexColors[ numVerts + 3 ]);
	}

	tess.xyz[ numVerts ][0] = cmd->x;
	tess.xyz[ numVerts ][1] = cmd->y;
	tess.xyz[ numVerts ][2] = 0;

	tess.texCoords[ numVerts ][0][0] = cmd->s1;
	tess.texCoords[ numVerts ][0][1] = cmd->t1;

	tess.xyz[ numVerts + 1 ][0] = cmd->x + cmd->w;
	tess.xyz[ numVerts + 1 ][1] = cmd->y;
	tess.xyz[ numVerts + 1 ][2] = 0;

	tess.texCoords[ numVerts + 1 ][0][0] = cmd->s2;
	tess.texCoords[ numVerts + 1 ][0][1] = cmd->t1;

	tess.xyz[ numVerts + 2 ][0] = cmd->x + cmd->w;
	tess.xyz[ numVerts + 2 ][1] = cmd->y + cmd->h;
	tess.xyz[ numVerts + 2 ][2] = 0;

	tess.texCoords[ numVerts + 2 ][0][0] = cmd->s2;
	tess.texCoords[ numVerts + 2 ][0][1] = cmd->t2;

	tess.xyz[ numVerts + 3 ][0] = cmd->x;
	tess.xyz[ numVerts + 3 ][1] = cmd->y + cmd->h;
	tess.xyz[ numVerts + 3 ][2] = 0;

	tess.texCoords[ numVerts + 3 ][0][0] = cmd->s1;
	tess.texCoords[ numVerts + 3 ][0][1] = cmd->t2;

	return (const void*)(cmd + 1);
}
Beispiel #8
0
/*
==============
RB_AddQuadStampExt
==============
*/
void RB_AddQuadStampExt( vec3_t origin, vec3_t left, vec3_t up, float color[4], float s1, float t1, float s2, float t2 ) {
	vec3_t		normal;
	int16_t     iNormal[4];
	uint16_t    iColor[4];
	int			ndx;

	RB_CheckVao(tess.vao);

	RB_CHECKOVERFLOW( 4, 6 );

	ndx = tess.numVertexes;

	// triangle indexes for a simple quad
	tess.indexes[ tess.numIndexes ] = ndx;
	tess.indexes[ tess.numIndexes + 1 ] = ndx + 1;
	tess.indexes[ tess.numIndexes + 2 ] = ndx + 3;

	tess.indexes[ tess.numIndexes + 3 ] = ndx + 3;
	tess.indexes[ tess.numIndexes + 4 ] = ndx + 1;
	tess.indexes[ tess.numIndexes + 5 ] = ndx + 2;

	tess.xyz[ndx][0] = origin[0] + left[0] + up[0];
	tess.xyz[ndx][1] = origin[1] + left[1] + up[1];
	tess.xyz[ndx][2] = origin[2] + left[2] + up[2];

	tess.xyz[ndx+1][0] = origin[0] - left[0] + up[0];
	tess.xyz[ndx+1][1] = origin[1] - left[1] + up[1];
	tess.xyz[ndx+1][2] = origin[2] - left[2] + up[2];

	tess.xyz[ndx+2][0] = origin[0] - left[0] - up[0];
	tess.xyz[ndx+2][1] = origin[1] - left[1] - up[1];
	tess.xyz[ndx+2][2] = origin[2] - left[2] - up[2];

	tess.xyz[ndx+3][0] = origin[0] + left[0] - up[0];
	tess.xyz[ndx+3][1] = origin[1] + left[1] - up[1];
	tess.xyz[ndx+3][2] = origin[2] + left[2] - up[2];


	// constant normal all the way around
	VectorSubtract( vec3_origin, backEnd.viewParms.or.axis[0], normal );

	R_VaoPackNormal(iNormal, normal);

	VectorCopy4(iNormal, tess.normal[ndx]);
	VectorCopy4(iNormal, tess.normal[ndx + 1]);
	VectorCopy4(iNormal, tess.normal[ndx + 2]);
	VectorCopy4(iNormal, tess.normal[ndx + 3]);

	// standard square texture coordinates
	VectorSet2(tess.texCoords[ndx], s1, t1);
	VectorSet2(tess.lightCoords[ndx], s1, t1);

	VectorSet2(tess.texCoords[ndx+1], s2, t1);
	VectorSet2(tess.lightCoords[ndx+1], s2, t1);

	VectorSet2(tess.texCoords[ndx+2], s2, t2);
	VectorSet2(tess.lightCoords[ndx+2], s2, t2);

	VectorSet2(tess.texCoords[ndx+3], s1, t2);
	VectorSet2(tess.lightCoords[ndx+3], s1, t2);

	// constant color all the way around
	// should this be identity and let the shader specify from entity?

	R_VaoPackColor(iColor, color);

	VectorCopy4(iColor, tess.color[ndx]);
	VectorCopy4(iColor, tess.color[ndx + 1]);
	VectorCopy4(iColor, tess.color[ndx + 2]);
	VectorCopy4(iColor, tess.color[ndx + 3]);

	tess.numVertexes += 4;
	tess.numIndexes += 6;
}
Beispiel #9
0
//QTZTODO: Support Centered Pic or vice versa?
const void *RB_RotatedPic( const void *data ) {
	const stretchPicCommand_t   *cmd;
	shader_t *shader;
	int numVerts, numIndexes;
	float angle;
	float pi2 = M_PI * 2;

	cmd = (const stretchPicCommand_t *)data;

	if ( !backEnd.projection2D )
		RB_SetGL2D();

	shader = cmd->shader;
	if ( shader != tess.shader )
	{
		if ( tess.numIndexes )
			RB_EndSurface();

		backEnd.currentEntity = &backEnd.entity2D;
		RB_BeginSurface( shader, 0 );
	}

	RB_CHECKOVERFLOW( 4, 6 );
	numVerts = tess.numVertexes;
	numIndexes = tess.numIndexes;

	tess.numVertexes += 4;
	tess.numIndexes += 6;

	tess.indexes[ numIndexes ] = numVerts + 3;
	tess.indexes[ numIndexes + 1 ] = numVerts + 0;
	tess.indexes[ numIndexes + 2 ] = numVerts + 2;
	tess.indexes[ numIndexes + 3 ] = numVerts + 2;
	tess.indexes[ numIndexes + 4 ] = numVerts + 0;
	tess.indexes[ numIndexes + 5 ] = numVerts + 1;

	*(int *)tess.vertexColors[ numVerts ] =
		*(int *)tess.vertexColors[ numVerts + 1 ] =
		*(int *)tess.vertexColors[ numVerts + 2 ] =
		*(int *)tess.vertexColors[ numVerts + 3 ] = *(int *)backEnd.color2D;

	angle = cmd->angle * pi2;
	tess.xyz[ numVerts ].x = cmd->x + ( cosf( angle ) * cmd->w );
	tess.xyz[ numVerts ].y = cmd->y + ( sinf( angle ) * cmd->h );
	tess.xyz[ numVerts ].z = 0;

	tess.texCoords[ numVerts ][0].x = cmd->s1;
	tess.texCoords[ numVerts ][0].y = cmd->t1;

	angle = cmd->angle * pi2 + 0.25f * pi2;
	tess.xyz[ numVerts + 1 ].x = cmd->x + ( cosf( angle ) * cmd->w );
	tess.xyz[ numVerts + 1 ].y = cmd->y + ( sinf( angle ) * cmd->h );
	tess.xyz[ numVerts + 1 ].z = 0;

	tess.texCoords[ numVerts + 1 ][0].x = cmd->s2;
	tess.texCoords[ numVerts + 1 ][0].y = cmd->t1;

	angle = cmd->angle * pi2 + 0.50f * pi2;
	tess.xyz[ numVerts + 2 ].x = cmd->x + ( cosf( angle ) * cmd->w );
	tess.xyz[ numVerts + 2 ].y = cmd->y + ( sinf( angle ) * cmd->h );
	tess.xyz[ numVerts + 2 ].z = 0;

	tess.texCoords[ numVerts + 2 ][0].x = cmd->s2;
	tess.texCoords[ numVerts + 2 ][0].y = cmd->t2;

	angle = cmd->angle * pi2 + 0.75f * pi2;
	tess.xyz[ numVerts + 3 ].x = cmd->x + ( cosf( angle ) * cmd->w );
	tess.xyz[ numVerts + 3 ].y = cmd->y + ( sinf( angle ) * cmd->h );
	tess.xyz[ numVerts + 3 ].z = 0;

	tess.texCoords[ numVerts + 3 ][0].x = cmd->s1;
	tess.texCoords[ numVerts + 3 ][0].y = cmd->t2;

	return (const void *)( cmd + 1 );
}
Beispiel #10
0
/*
=================
RB_AddIQMSurfaces

Compute vertices for this model surface
=================
*/
void RB_IQMSurfaceAnim( surfaceType_t *surface ) {
	srfIQModel_t	*surf = (srfIQModel_t *)surface;
	iqmData_t	*data = surf->data;
	float		jointMats[IQM_MAX_JOINTS * 12];
	int		i;

	vec4_t		*outXYZ;
	uint32_t	*outNormal;
#ifdef USE_VERT_TANGENT_SPACE
	uint32_t	*outTangent;
#endif
	vec2_t		(*outTexCoord)[2];
	vec4_t	*outColor;

	iqmData_t	*skeleton = R_GetIQMModelDataByHandle( backEnd.currentEntity->e.frameModel, data );
	iqmData_t	*oldSkeleton = R_GetIQMModelDataByHandle( backEnd.currentEntity->e.oldframeModel, data );

	int	frame = skeleton->num_frames ? backEnd.currentEntity->e.frame % skeleton->num_frames : 0;
	int	oldframe = oldSkeleton->num_frames ? backEnd.currentEntity->e.oldframe % oldSkeleton->num_frames : 0;
	float	backlerp = backEnd.currentEntity->e.backlerp;

	int		*tri;
	glIndex_t	*ptr;
	glIndex_t	base;

	if ( data != skeleton && data->num_joints != skeleton->num_poses ) {
		ri.Printf( PRINT_WARNING, "WARNING: frameModel '%s' for model '%s' has different number of joints\n",
				R_GetModelByHandle( backEnd.currentEntity->e.frameModel )->name, R_GetModelByHandle( backEnd.currentEntity->e.hModel )->name );
		skeleton = data;
	}

	if ( data != oldSkeleton && data->num_joints != oldSkeleton->num_poses ) {
		ri.Printf( PRINT_WARNING, "WARNING: oldframeModel '%s' for model '%s' has different number of joints\n",
				R_GetModelByHandle( backEnd.currentEntity->e.oldframeModel )->name, R_GetModelByHandle( backEnd.currentEntity->e.hModel )->name );
		oldSkeleton = data;
	}

	RB_CHECKOVERFLOW( surf->num_vertexes, surf->num_triangles * 3 );

	outXYZ = &tess.xyz[tess.numVertexes];
	outNormal = &tess.normal[tess.numVertexes];
#ifdef USE_VERT_TANGENT_SPACE
	outTangent = &tess.tangent[tess.numVertexes];
#endif
	outTexCoord = &tess.texCoords[tess.numVertexes];
	outColor = &tess.vertexColors[tess.numVertexes];

	// compute interpolated joint matrices
	if ( skeleton->num_poses > 0 ) {
		ComputePoseMats( data, skeleton, oldSkeleton, frame, oldframe, backlerp, jointMats );
	}

	// transform vertexes and fill other data
	for( i = 0; i < surf->num_vertexes;
	     i++, outXYZ++, outNormal++, outTexCoord++, outColor++ ) {
		int	j, k;
		float	vtxMat[12];
		float	nrmMat[9];
		int	vtx = i + surf->first_vertex;
		float	blendWeights[4];
		int		numWeights;

		for ( numWeights = 0; numWeights < 4; numWeights++ ) {
			if ( data->blendWeightsType == IQM_FLOAT )
				blendWeights[numWeights] = data->blendWeights.f[4*vtx + numWeights];
			else
				blendWeights[numWeights] = (float)data->blendWeights.b[4*vtx + numWeights] / 255.0f;

			if ( blendWeights[numWeights] <= 0 )
				break;
		}

		if ( skeleton->num_poses == 0 || numWeights == 0 ) {
			// no blend joint, use identity matrix.
			Com_Memcpy( vtxMat, identityMatrix, 12 * sizeof (float) );
		} else {
			// compute the vertex matrix by blending the up to
			// four blend weights
			Com_Memset( vtxMat, 0, 12 * sizeof (float) );
			for( j = 0; j < numWeights; j++ ) {
				for( k = 0; k < 12; k++ ) {
					vtxMat[k] += blendWeights[j] * jointMats[12*data->blendIndexes[4*vtx + j] + k];
				}
			}
		}

		// compute the normal matrix as transpose of the adjoint
		// of the vertex matrix
		nrmMat[ 0] = vtxMat[ 5]*vtxMat[10] - vtxMat[ 6]*vtxMat[ 9];
		nrmMat[ 1] = vtxMat[ 6]*vtxMat[ 8] - vtxMat[ 4]*vtxMat[10];
		nrmMat[ 2] = vtxMat[ 4]*vtxMat[ 9] - vtxMat[ 5]*vtxMat[ 8];
		nrmMat[ 3] = vtxMat[ 2]*vtxMat[ 9] - vtxMat[ 1]*vtxMat[10];
		nrmMat[ 4] = vtxMat[ 0]*vtxMat[10] - vtxMat[ 2]*vtxMat[ 8];
		nrmMat[ 5] = vtxMat[ 1]*vtxMat[ 8] - vtxMat[ 0]*vtxMat[ 9];
		nrmMat[ 6] = vtxMat[ 1]*vtxMat[ 6] - vtxMat[ 2]*vtxMat[ 5];
		nrmMat[ 7] = vtxMat[ 2]*vtxMat[ 4] - vtxMat[ 0]*vtxMat[ 6];
		nrmMat[ 8] = vtxMat[ 0]*vtxMat[ 5] - vtxMat[ 1]*vtxMat[ 4];

		(*outTexCoord)[0][0] = data->texcoords[2*vtx + 0];
		(*outTexCoord)[0][1] = data->texcoords[2*vtx + 1];
		(*outTexCoord)[1][0] = (*outTexCoord)[0][0];
		(*outTexCoord)[1][1] = (*outTexCoord)[0][1];

		(*outXYZ)[0] =
			vtxMat[ 0] * data->positions[3*vtx+0] +
			vtxMat[ 1] * data->positions[3*vtx+1] +
			vtxMat[ 2] * data->positions[3*vtx+2] +
			vtxMat[ 3];
		(*outXYZ)[1] =
			vtxMat[ 4] * data->positions[3*vtx+0] +
			vtxMat[ 5] * data->positions[3*vtx+1] +
			vtxMat[ 6] * data->positions[3*vtx+2] +
			vtxMat[ 7];
		(*outXYZ)[2] =
			vtxMat[ 8] * data->positions[3*vtx+0] +
			vtxMat[ 9] * data->positions[3*vtx+1] +
			vtxMat[10] * data->positions[3*vtx+2] +
			vtxMat[11];
		(*outXYZ)[3] = 1.0f;

		{
			vec3_t normal;
			vec4_t tangent;

			normal[0] = DotProduct(&nrmMat[0], &data->normals[3*vtx]);
			normal[1] = DotProduct(&nrmMat[3], &data->normals[3*vtx]);
			normal[2] = DotProduct(&nrmMat[6], &data->normals[3*vtx]);

			*outNormal = R_VboPackNormal(normal);

#ifdef USE_VERT_TANGENT_SPACE
			tangent[0] = DotProduct(&nrmMat[0], &data->tangents[4*vtx]);
			tangent[1] = DotProduct(&nrmMat[3], &data->tangents[4*vtx]);
			tangent[2] = DotProduct(&nrmMat[6], &data->tangents[4*vtx]);
			tangent[3] = data->tangents[4*vtx+3];

			*outTangent++ = R_VboPackTangent(tangent);
#endif
		}

		(*outColor)[0] = data->colors[4*vtx+0] / 255.0f;
		(*outColor)[1] = data->colors[4*vtx+1] / 255.0f;
		(*outColor)[2] = data->colors[4*vtx+2] / 255.0f;
		(*outColor)[3] = data->colors[4*vtx+3] / 255.0f;
	}

	tri = data->triangles + 3 * surf->first_triangle;
	ptr = &tess.indexes[tess.numIndexes];
	base = tess.numVertexes;

	for( i = 0; i < surf->num_triangles; i++ ) {
		*ptr++ = base + (*tri++ - surf->first_vertex);
		*ptr++ = base + (*tri++ - surf->first_vertex);
		*ptr++ = base + (*tri++ - surf->first_vertex);
	}

	tess.numIndexes += 3 * surf->num_triangles;
	tess.numVertexes += surf->num_vertexes;
}
Beispiel #11
0
/*
==============
RB_MDRSurfaceAnim
==============
*/
void RB_MDRSurfaceAnim( mdrSurface_t *surface )
{
	int				i, j, k;
	float			frontlerp, backlerp;
	int				*triangles;
	int				indexes;
	int				baseIndex, baseVertex;
	int				numVerts;
	mdrVertex_t		*v;
	mdrHeader_t		*header;
	mdrFrame_t		*frame;
	mdrFrame_t		*oldFrame;
	mdrBone_t		bones[MDR_MAX_BONES], *bonePtr, *bone;

	int			frameSize;

	// don't lerp if lerping off, or this is the only frame, or the last frame...
	//
	if (backEnd.currentEntity->e.oldframe == backEnd.currentEntity->e.frame) 
	{
		backlerp	= 0;	// if backlerp is 0, lerping is off and frontlerp is never used
		frontlerp	= 1;
	} 
	else  
	{
		backlerp	= backEnd.currentEntity->e.backlerp;
		frontlerp	= 1.0f - backlerp;
	}

	header = (mdrHeader_t *)((byte *)surface + surface->ofsHeader);

	frameSize = (size_t)( &((mdrFrame_t *)0)->bones[ header->numBones ] );

	frame = (mdrFrame_t *)((byte *)header + header->ofsFrames +
		backEnd.currentEntity->e.frame * frameSize );
	oldFrame = (mdrFrame_t *)((byte *)header + header->ofsFrames +
		backEnd.currentEntity->e.oldframe * frameSize );

	RB_CHECKOVERFLOW( surface->numVerts, surface->numTriangles * 3 );

	triangles	= (int *) ((byte *)surface + surface->ofsTriangles);
	indexes		= surface->numTriangles * 3;
	baseIndex	= tess.numIndexes;
	baseVertex	= tess.numVertexes;
	
	// Set up all triangles.
	for (j = 0 ; j < indexes ; j++) 
	{
		tess.indexes[baseIndex + j] = baseVertex + triangles[j];
	}
	tess.numIndexes += indexes;

	//
	// lerp all the needed bones
	//
	if ( !backlerp ) 
	{
		// no lerping needed
		bonePtr = frame->bones;
	} 
	else 
	{
		bonePtr = bones;
		
		for ( i = 0 ; i < header->numBones*12 ; i++ ) 
		{
			((float *)bonePtr)[i] = frontlerp * ((float *)frame->bones)[i] + backlerp * ((float *)oldFrame->bones)[i];
		}
	}

	//
	// deform the vertexes by the lerped bones
	//
	numVerts = surface->numVerts;
	v = (mdrVertex_t *) ((byte *)surface + surface->ofsVerts);
	for ( j = 0; j < numVerts; j++ ) 
	{
		vec3_t	tempVert, tempNormal;
		mdrWeight_t	*w;

		VectorClear( tempVert );
		VectorClear( tempNormal );
		w = v->weights;
		for ( k = 0 ; k < v->numWeights ; k++, w++ ) 
		{
			bone = bonePtr + w->boneIndex;
			
			tempVert[0] += w->boneWeight * ( DotProduct( bone->matrix[0], w->offset ) + bone->matrix[0][3] );
			tempVert[1] += w->boneWeight * ( DotProduct( bone->matrix[1], w->offset ) + bone->matrix[1][3] );
			tempVert[2] += w->boneWeight * ( DotProduct( bone->matrix[2], w->offset ) + bone->matrix[2][3] );
			
			tempNormal[0] += w->boneWeight * DotProduct( bone->matrix[0], v->normal );
			tempNormal[1] += w->boneWeight * DotProduct( bone->matrix[1], v->normal );
			tempNormal[2] += w->boneWeight * DotProduct( bone->matrix[2], v->normal );
		}

		tess.xyz[baseVertex + j][0] = tempVert[0];
		tess.xyz[baseVertex + j][1] = tempVert[1];
		tess.xyz[baseVertex + j][2] = tempVert[2];

		R_VaoPackNormal(tess.normal[baseVertex + j], tempNormal);

		tess.texCoords[baseVertex + j][0] = v->texCoords[0];
		tess.texCoords[baseVertex + j][1] = v->texCoords[1];

		v = (mdrVertex_t *)&v->weights[v->numWeights];
	}

	tess.numVertexes += surface->numVerts;
}
Beispiel #12
0
/*
=================
RB_AddIQMSurfaces

Compute vertices for this model surface
=================
*/
void RB_IQMSurfaceAnim( surfaceType_t *surface ) {
	srfIQModel_t	*surf = (srfIQModel_t *)surface;
	iqmData_t	*data = surf->data;
	float		jointMats[IQM_MAX_JOINTS * 12];
	int		i;

	vec4_t		*outXYZ;
	vec4_t		*outNormal;
	vec2_t		(*outTexCoord)[2];
	color4ub_t	*outColor;

	int	frame = data->num_frames ? backEnd.currentEntity->e.frame % data->num_frames : 0;
	int	oldframe = data->num_frames ? backEnd.currentEntity->e.oldframe % data->num_frames : 0;
	float	backlerp = backEnd.currentEntity->e.backlerp;

	int		*tri;
	glIndex_t	*ptr;
	glIndex_t	base;

	RB_CHECKOVERFLOW( surf->num_vertexes, surf->num_triangles * 3 );

	outXYZ = &tess.xyz[tess.numVertexes];
	outNormal = &tess.normal[tess.numVertexes];
	outTexCoord = &tess.texCoords[tess.numVertexes];
	outColor = &tess.vertexColors[tess.numVertexes];

	// compute interpolated joint matrices
	if ( data->num_poses > 0 ) {
		ComputePoseMats( data, frame, oldframe, backlerp, jointMats );
	}

	// transform vertexes and fill other data
	for( i = 0; i < surf->num_vertexes;
	     i++, outXYZ++, outNormal++, outTexCoord++, outColor++ ) {
		int	j, k;
		float	vtxMat[12];
		float	nrmMat[9];
		int	vtx = i + surf->first_vertex;
		float	blendWeights[4];
		int		numWeights;

		for ( numWeights = 0; numWeights < 4; numWeights++ ) {
			if ( data->blendWeightsType == IQM_FLOAT )
				blendWeights[numWeights] = data->blendWeights.f[4*vtx + numWeights];
			else
				blendWeights[numWeights] = (float)data->blendWeights.b[4*vtx + numWeights] / 255.0f;

			if ( blendWeights[numWeights] <= 0 )
				break;
		}

		if ( data->num_poses == 0 || numWeights == 0 ) {
			// no blend joint, use identity matrix.
			Com_Memcpy( vtxMat, identityMatrix, 12 * sizeof (float) );
		} else {
			// compute the vertex matrix by blending the up to
			// four blend weights
			Com_Memset( vtxMat, 0, 12 * sizeof (float) );
			for( j = 0; j < numWeights; j++ ) {
				for( k = 0; k < 12; k++ ) {
					vtxMat[k] += blendWeights[j] * jointMats[12*data->blendIndexes[4*vtx + j] + k];
				}
			}
		}

		// compute the normal matrix as transpose of the adjoint
		// of the vertex matrix
		nrmMat[ 0] = vtxMat[ 5]*vtxMat[10] - vtxMat[ 6]*vtxMat[ 9];
		nrmMat[ 1] = vtxMat[ 6]*vtxMat[ 8] - vtxMat[ 4]*vtxMat[10];
		nrmMat[ 2] = vtxMat[ 4]*vtxMat[ 9] - vtxMat[ 5]*vtxMat[ 8];
		nrmMat[ 3] = vtxMat[ 2]*vtxMat[ 9] - vtxMat[ 1]*vtxMat[10];
		nrmMat[ 4] = vtxMat[ 0]*vtxMat[10] - vtxMat[ 2]*vtxMat[ 8];
		nrmMat[ 5] = vtxMat[ 1]*vtxMat[ 8] - vtxMat[ 0]*vtxMat[ 9];
		nrmMat[ 6] = vtxMat[ 1]*vtxMat[ 6] - vtxMat[ 2]*vtxMat[ 5];
		nrmMat[ 7] = vtxMat[ 2]*vtxMat[ 4] - vtxMat[ 0]*vtxMat[ 6];
		nrmMat[ 8] = vtxMat[ 0]*vtxMat[ 5] - vtxMat[ 1]*vtxMat[ 4];

		(*outTexCoord)[0][0] = data->texcoords[2*vtx + 0];
		(*outTexCoord)[0][1] = data->texcoords[2*vtx + 1];
		(*outTexCoord)[1][0] = (*outTexCoord)[0][0];
		(*outTexCoord)[1][1] = (*outTexCoord)[0][1];

		(*outXYZ)[0] =
			vtxMat[ 0] * data->positions[3*vtx+0] +
			vtxMat[ 1] * data->positions[3*vtx+1] +
			vtxMat[ 2] * data->positions[3*vtx+2] +
			vtxMat[ 3];
		(*outXYZ)[1] =
			vtxMat[ 4] * data->positions[3*vtx+0] +
			vtxMat[ 5] * data->positions[3*vtx+1] +
			vtxMat[ 6] * data->positions[3*vtx+2] +
			vtxMat[ 7];
		(*outXYZ)[2] =
			vtxMat[ 8] * data->positions[3*vtx+0] +
			vtxMat[ 9] * data->positions[3*vtx+1] +
			vtxMat[10] * data->positions[3*vtx+2] +
			vtxMat[11];
		(*outXYZ)[3] = 1.0f;

		(*outNormal)[0] =
			nrmMat[ 0] * data->normals[3*vtx+0] +
			nrmMat[ 1] * data->normals[3*vtx+1] +
			nrmMat[ 2] * data->normals[3*vtx+2];
		(*outNormal)[1] =
			nrmMat[ 3] * data->normals[3*vtx+0] +
			nrmMat[ 4] * data->normals[3*vtx+1] +
			nrmMat[ 5] * data->normals[3*vtx+2];
		(*outNormal)[2] =
			nrmMat[ 6] * data->normals[3*vtx+0] +
			nrmMat[ 7] * data->normals[3*vtx+1] +
			nrmMat[ 8] * data->normals[3*vtx+2];
		(*outNormal)[3] = 0.0f;

		(*outColor)[0] = data->colors[4*vtx+0];
		(*outColor)[1] = data->colors[4*vtx+1];
		(*outColor)[2] = data->colors[4*vtx+2];
		(*outColor)[3] = data->colors[4*vtx+3];
	}

	tri = data->triangles + 3 * surf->first_triangle;
	ptr = &tess.indexes[tess.numIndexes];
	base = tess.numVertexes;

	for( i = 0; i < surf->num_triangles; i++ ) {
		*ptr++ = base + (*tri++ - surf->first_vertex);
		*ptr++ = base + (*tri++ - surf->first_vertex);
		*ptr++ = base + (*tri++ - surf->first_vertex);
	}

	tess.numIndexes += 3 * surf->num_triangles;
	tess.numVertexes += surf->num_vertexes;
}
void RB_DrawPolys( const void *data )
{
	const drawPolysCmd_t *cmd = (drawPolysCmd_t*)data;

	uint i;
	uint numVerts, numIndices;

	float *xy, *st;
	uint *colors;
	glIndex_t *indices;
	uint baseVtx;

	if( !backEnd.projection2D )
		RB_SetGL2D();

	numVerts = cmd->numVertsPerPoly * cmd->numPolys;
	numIndices = cmd->numPolys * (cmd->numVertsPerPoly - 2) * 3;

	RB_CheckSurface( cmd->shader, 0, GL_TRIANGLES );

	RB_CHECKOVERFLOW( numVerts, numIndices );

	baseVtx = tess.numVertexes;
	xy = tess.xyz[baseVtx];
	st = tess.texCoords[baseVtx][0];
	colors = (uint*)tess.vertexColors + baseVtx;
	
	tess.numVertexes = baseVtx + numVerts;

	for( i = 0; i < numVerts; i++ )
	{
		xy[0] = cmd->verts[i].xy[0];
		xy[1] = cmd->verts[i].xy[1];
		xy[2] = 0;

		st[0] = cmd->verts[i].st[0];
		st[1] = cmd->verts[i].st[1];

		*colors = *(uint*)cmd->verts[i].modulate;

		xy++;
		st++;
		colors++;
	}

	indices = tess.indexes + tess.numIndexes;

	for( i = 0; i < cmd->numPolys; i++ )
	{
		uint j;

		//emit fan-order indices
		for( j = 2; j < cmd->numVertsPerPoly; j++ )
		{
			indices[0] = baseVtx;
			indices[1] = baseVtx + j - 1;
			indices[2] = baseVtx + j;

			indices += 3;
		}

		baseVtx += cmd->numVertsPerPoly;
	}

	tess.numIndexes += numIndices;
}
Beispiel #14
0
/*==============================================================
  RB_SurfaceMyGhoul
    Called when a MyGhoul surf is asked to render.
==============================================================*/
void RB_SurfaceMyGhoul( surfaceType_t *surface )
{
	glmSurface_t	*surf = (glmSurface_t *)surface;
//	int				i, j, k;
	int				j, k;
	int				*triangles;
	int				indexes;
	int				baseIndex, baseVertex;
	int				numVerts;
	glmVertex_t		*v;
	glmVertexTexCoord_t *t;
	glmHeader_t		*header;
	model_t			*model_anims = NULL;
//	mdxaHeader_t	*anims;
	vec3_t	tempVert, tempNormal;
	int				animated = 0;
//	int				numWeights;
//	int				boneIndices[4];
//	float			boneWeights[4];
//	float			totalWeight = 0.0;
	//mgMatrix34_t		final;
	//mg_animstate_t	*as = NULL;
	//mgMatrix34_t	*pose = NULL;
	float	*outXyz, *outNormal;
//	vec3_t newXyz, newNormal;
	
	float zrots[3][4];
	int do_zrot = 1;
	
	zrots[0][0] = 0.0;
	zrots[0][1] = -1.0;
	zrots[0][2] = 0.0;
	zrots[0][3] = 0.0;
	zrots[1][0] = 1.0;
	zrots[1][1] = 0.0;
	zrots[1][2] = 0.0;
	zrots[1][3] = 0.0;
	zrots[2][0] = 0.0;
	zrots[2][1] = 0.0;
	zrots[2][2] = 1.0;
	zrots[2][3] = 0.0;
	
	header = (glmHeader_t *)((byte *)surf + surf->ofsHeader);
	RB_CHECKOVERFLOW( surf->numVerts, surf->numTriangles * 3 );
	
	triangles = (int *) ((byte *)surf + surf->ofsTriangles);
	indexes = surf->numTriangles * 3;
	baseIndex = tess.numIndexes;
	baseVertex = tess.numVertexes;
	
	outXyz = tess.xyz[baseVertex];
	outNormal = tess.normal[baseVertex];
	
	for (j = 0 ; j < indexes ; j++)
	{
		tess.indexes[baseIndex + j] = baseVertex + triangles[j];
	}
	tess.numIndexes += indexes;
#if 0
	if( header->animIndex != 0 )
	{
		model_anims = R_GetModelByHandle( header->animIndex );
		if( model_anims->type == MOD_GLA )
		{
			anims = model_anims->gla;
			as = RE_AS_Fetch( backEnd.currentEntity->e.frame );
		}

		if( as->index == 0 )
		{
			anims = 0;
			animated = 0;
		}
		else
		{
			animated = 1;
			pose = as->pose;
		}
	}
	else
#endif
	{
		animated = 0;
	}
	
	//animated = 0;
	
	numVerts = surf->numVerts;
	v = (glmVertex_t *)((byte *)surf + surf->ofsVerts);
	triangles = (int *)((byte *)surf + surf->ofsBoneReferences );
	
	for( k=0; k<numVerts; k++, outXyz+=4, outNormal+=4 )
	{
		tempVert[0] = v->vertCoords[0];
		tempVert[1] = v->vertCoords[1];
		tempVert[2] = v->vertCoords[2];
		tempNormal[0] = v->normal[0];
		tempNormal[1] = v->normal[1];
		tempNormal[2] = v->normal[2];

#if 0
		if( animated )
		{
			numWeights = GLM_GetVertNumWeights( v );
			final.matrix[0][0] = final.matrix[0][1] = final.matrix[0][2] = final.matrix[0][3] = final.matrix[1][0] = final.matrix[1][1] = final.matrix[1][2] = final.matrix[1][3] = final.matrix[2][0] = final.matrix[2][1] = final.matrix[2][2] = final.matrix[2][3] = 0.0;
			totalWeight = 0.0;
			for( i = 0; i < numWeights; i++ )
			{
				boneIndices[i] = triangles[( v->uiNmWeightsAndBoneIndexes >> ( 5 * i ) ) & ( ( 1 << 5 ) - 1 )];
				if( i == numWeights-1 )
				{
					boneWeights[i] = 1.0f-totalWeight;
				}
				else
				{
					boneWeights[i] = GLM_GetVertBoneWeight( v, i, v->BoneWeightings[i], v->uiNmWeightsAndBoneIndexes, totalWeight );
				}
				totalWeight += boneWeights[i];
				Matrix34AddScale( final.matrix, pose[boneIndices[i]].matrix, boneWeights[i] );
			}

			Matrix34VectorRotateAdd( final.matrix, tempVert, newXyz );
			Matrix34VectorRotate( final.matrix, tempNormal, newNormal );

			outXyz[0] = newXyz[0];
			outXyz[1] = newXyz[1];
			outXyz[2] = newXyz[2];

			outNormal[0] = newNormal[0];
			outNormal[1] = newNormal[1];
			outNormal[2] = newNormal[2];
		}
		else
#endif
		{
			if( do_zrot )
Beispiel #15
0
/*
=============
RB_RotatedPic
=============
*/
const void     *RB_RotatedPic( const void *data )
{
	const stretchPicCommand_t *cmd;
	shader_t                  *shader;
	int                       numVerts, numIndexes;
	float                     mx, my, cosA, sinA, cw, ch, sw, sh;

	cmd = ( const stretchPicCommand_t * ) data;

	if ( !backEnd.projection2D )
	{
		RB_SetGL2D();
	}

	shader = cmd->shader;

	if ( shader != tess.shader )
	{
		if ( tess.numIndexes )
		{
			RB_EndSurface();
		}

		backEnd.currentEntity = &backEnd.entity2D;
		RB_BeginSurface( shader, 0 );
	}

	RB_CHECKOVERFLOW( 4, 6 );
	numVerts = tess.numVertexes;
	numIndexes = tess.numIndexes;

	tess.numVertexes += 4;
	tess.numIndexes += 6;

	tess.indexes[ numIndexes ] = numVerts + 3;
	tess.indexes[ numIndexes + 1 ] = numVerts + 0;
	tess.indexes[ numIndexes + 2 ] = numVerts + 2;
	tess.indexes[ numIndexes + 3 ] = numVerts + 2;
	tess.indexes[ numIndexes + 4 ] = numVerts + 0;
	tess.indexes[ numIndexes + 5 ] = numVerts + 1;

	* ( int * ) tess.vertexColors[ numVerts ].v =
	  * ( int * ) tess.vertexColors[ numVerts + 1 ].v =
	    * ( int * ) tess.vertexColors[ numVerts + 2 ].v = * ( int * ) tess.vertexColors[ numVerts + 3 ].v = * ( int * ) backEnd.color2D;

	mx = cmd->x + ( cmd->w / 2 );
	my = cmd->y + ( cmd->h / 2 );
	cosA = cos( DEG2RAD( cmd->angle ) );
	sinA = sin( DEG2RAD( cmd->angle ) );
	cw = cosA * ( cmd->w / 2 );
	ch = cosA * ( cmd->h / 2 );
	sw = sinA * ( cmd->w / 2 );
	sh = sinA * ( cmd->h / 2 );

	tess.xyz[ numVerts ].v[ 0 ] = mx - cw - sh;
	tess.xyz[ numVerts ].v[ 1 ] = my + sw - ch;
	tess.xyz[ numVerts ].v[ 2 ] = 0;

	tess.texCoords0[ numVerts ].v[ 0 ] = cmd->s1;
	tess.texCoords0[ numVerts ].v[ 1 ] = cmd->t1;

	tess.xyz[ numVerts + 1 ].v[ 0 ] = mx + cw - sh;
	tess.xyz[ numVerts + 1 ].v[ 1 ] = my - sw - ch;
	tess.xyz[ numVerts + 1 ].v[ 2 ] = 0;

	tess.texCoords0[ numVerts + 1 ].v[ 0 ] = cmd->s2;
	tess.texCoords0[ numVerts + 1 ].v[ 1 ] = cmd->t1;

	tess.xyz[ numVerts + 2 ].v[ 0 ] = mx + cw + sh;
	tess.xyz[ numVerts + 2 ].v[ 1 ] = my - sw + ch;
	tess.xyz[ numVerts + 2 ].v[ 2 ] = 0;

	tess.texCoords0[ numVerts + 2 ].v[ 0 ] = cmd->s2;
	tess.texCoords0[ numVerts + 2 ].v[ 1 ] = cmd->t2;

	tess.xyz[ numVerts + 3 ].v[ 0 ] = mx - cw + sh;
	tess.xyz[ numVerts + 3 ].v[ 1 ] = my + sw + ch;
	tess.xyz[ numVerts + 3 ].v[ 2 ] = 0;

	tess.texCoords0[ numVerts + 3 ].v[ 0 ] = cmd->s1;
	tess.texCoords0[ numVerts + 3 ].v[ 1 ] = cmd->t2;

	return ( const void * )( cmd + 1 );
}
Beispiel #16
0
static void DoRailDiscs( int numSegs, const vec3_t start, const vec3_t dir, const vec3_t right, const vec3_t up )
{
	int i;
	vec3_t	pos[4];
	vec3_t	v;
	int		spanWidth = r_railWidth->integer;
	float c, s;
	float		scale;

	if ( numSegs > 1 )
		numSegs--;
	if ( !numSegs )
		return;

	scale = 0.25;

	for ( i = 0; i < 4; i++ )
	{
		c = cos( DEG2RAD( 45 + i * 90 ) );
		s = sin( DEG2RAD( 45 + i * 90 ) );
		v[0] = ( right[0] * c + up[0] * s ) * scale * spanWidth;
		v[1] = ( right[1] * c + up[1] * s ) * scale * spanWidth;
		v[2] = ( right[2] * c + up[2] * s ) * scale * spanWidth;
		VectorAdd( start, v, pos[i] );

		if ( numSegs > 1 )
		{
			// offset by 1 segment if we're doing a long distance shot
			VectorAdd( pos[i], dir, pos[i] );
		}
	}

	RB_CheckVao(tess.vao);

	for ( i = 0; i < numSegs; i++ )
	{
		int j;

		RB_CHECKOVERFLOW( 4, 6 );

		for ( j = 0; j < 4; j++ )
		{
			VectorCopy( pos[j], tess.xyz[tess.numVertexes] );
			tess.texCoords[tess.numVertexes][0] = (j < 2);
			tess.texCoords[tess.numVertexes][1] = (j && j != 3);
			tess.color[tess.numVertexes][0] = backEnd.currentEntity->e.shaderRGBA[0] * 257;
			tess.color[tess.numVertexes][1] = backEnd.currentEntity->e.shaderRGBA[1] * 257;
			tess.color[tess.numVertexes][2] = backEnd.currentEntity->e.shaderRGBA[2] * 257;
			tess.numVertexes++;

			VectorAdd( pos[j], dir, pos[j] );
		}

		tess.indexes[tess.numIndexes++] = tess.numVertexes - 4 + 0;
		tess.indexes[tess.numIndexes++] = tess.numVertexes - 4 + 1;
		tess.indexes[tess.numIndexes++] = tess.numVertexes - 4 + 3;
		tess.indexes[tess.numIndexes++] = tess.numVertexes - 4 + 3;
		tess.indexes[tess.numIndexes++] = tess.numVertexes - 4 + 1;
		tess.indexes[tess.numIndexes++] = tess.numVertexes - 4 + 2;
	}
}
Beispiel #17
0
static void RB_SurfaceVertsAndIndexes( int numVerts, srfVert_t *verts, int numIndexes, glIndex_t *indexes, int dlightBits, int pshadowBits)
{
	int             i;
	glIndex_t      *inIndex;
	srfVert_t      *dv;
	float          *xyz, *texCoords, *lightCoords;
	int16_t        *lightdir;
	int16_t        *normal;
	int16_t        *tangent;
	glIndex_t      *outIndex;
	uint16_t       *color;

	RB_CheckVao(tess.vao);

	RB_CHECKOVERFLOW( numVerts, numIndexes );

	inIndex = indexes;
	outIndex = &tess.indexes[ tess.numIndexes ];
	for ( i = 0 ; i < numIndexes ; i++ ) {
		*outIndex++ = tess.numVertexes + *inIndex++;
	}
	tess.numIndexes += numIndexes;

	if ( tess.shader->vertexAttribs & ATTR_POSITION )
	{
		dv = verts;
		xyz = tess.xyz[ tess.numVertexes ];
		for ( i = 0 ; i < numVerts ; i++, dv++, xyz+=4 )
			VectorCopy(dv->xyz, xyz);
	}

	if ( tess.shader->vertexAttribs & ATTR_NORMAL )
	{
		dv = verts;
		normal = tess.normal[ tess.numVertexes ];
		for ( i = 0 ; i < numVerts ; i++, dv++, normal+=4 )
			VectorCopy4(dv->normal, normal);
	}

	if ( tess.shader->vertexAttribs & ATTR_TANGENT )
	{
		dv = verts;
		tangent = tess.tangent[ tess.numVertexes ];
		for ( i = 0 ; i < numVerts ; i++, dv++, tangent+=4 )
			VectorCopy4(dv->tangent, tangent);
	}

	if ( tess.shader->vertexAttribs & ATTR_TEXCOORD )
	{
		dv = verts;
		texCoords = tess.texCoords[tess.numVertexes];
		for ( i = 0 ; i < numVerts ; i++, dv++, texCoords+=2 )
			VectorCopy2(dv->st, texCoords);
	}

	if ( tess.shader->vertexAttribs & ATTR_LIGHTCOORD )
	{
		dv = verts;
		lightCoords = tess.lightCoords[ tess.numVertexes ];
		for ( i = 0 ; i < numVerts ; i++, dv++, lightCoords+=2 )
			VectorCopy2(dv->lightmap, lightCoords);
	}

	if ( tess.shader->vertexAttribs & ATTR_COLOR )
	{
		dv = verts;
		color = tess.color[ tess.numVertexes ];
		for ( i = 0 ; i < numVerts ; i++, dv++, color+=4 )
			VectorCopy4(dv->color, color);
	}

	if ( tess.shader->vertexAttribs & ATTR_LIGHTDIRECTION )
	{
		dv = verts;
		lightdir = tess.lightdir[ tess.numVertexes ];
		for ( i = 0 ; i < numVerts ; i++, dv++, lightdir+=4 )
			VectorCopy4(dv->lightdir, lightdir);
	}

#if 0  // nothing even uses vertex dlightbits
	for ( i = 0 ; i < numVerts ; i++ ) {
		tess.vertexDlightBits[ tess.numVertexes + i ] = dlightBits;
	}
#endif

	tess.dlightBits |= dlightBits;
	tess.pshadowBits |= pshadowBits;

	tess.numVertexes += numVerts;
}
Beispiel #18
0
/*
=================
RB_AddIQMSurfaces

Compute vertices for this model surface
=================
*/
void RB_IQMSurfaceAnim(surfaceType_t* surface) {
    srfIQModel_t*    surf = (srfIQModel_t*)surface;
    iqmData_t*   data = surf->data;
    float       jointMats[IQM_MAX_JOINTS * 12];
    int     i;

    vec4_t*      outXYZ = &tess.xyz[tess.numVertexes];
    vec4_t*      outNormal = &tess.normal[tess.numVertexes];
    vec2_t (*outTexCoord)[2] = &tess.texCoords[tess.numVertexes];
    color4ub_t*  outColor = &tess.vertexColors[tess.numVertexes];

    int frame = backEnd.currentEntity->e.frame % data->num_frames;
    int oldframe = backEnd.currentEntity->e.oldframe % data->num_frames;
    float   backlerp = backEnd.currentEntity->e.backlerp;

    int*     tri;
    glIndex_t*   ptr;
    glIndex_t   base;

    RB_CHECKOVERFLOW(surf->num_vertexes, surf->num_triangles * 3);

    // compute interpolated joint matrices
    ComputeJointMats(data, frame, oldframe, backlerp, jointMats);

    // transform vertexes and fill other data
    for (i = 0; i < surf->num_vertexes;
            i++, outXYZ++, outNormal++, outTexCoord++, outColor++) {
        int j, k;
        float   vtxMat[12];
        float   nrmMat[9];
        int vtx = i + surf->first_vertex;

        // compute the vertex matrix by blending the up to
        // four blend weights
        for (k = 0; k < 12; k++)
            vtxMat[k] = data->blendWeights[4 * vtx]
                        * jointMats[12 * data->blendIndexes[4 * vtx] + k];
        for (j = 1; j < 4; j++) {
            if (data->blendWeights[4 * vtx + j] <= 0)
                break;
            for (k = 0; k < 12; k++)
                vtxMat[k] += data->blendWeights[4 * vtx + j]
                             * jointMats[12 * data->blendIndexes[4 * vtx + j] + k];
        }
        for (k = 0; k < 12; k++)
            vtxMat[k] *= 1.0f / 255.0f;

        // compute the normal matrix as transpose of the adjoint
        // of the vertex matrix
        nrmMat[ 0] = vtxMat[ 5] * vtxMat[10] - vtxMat[ 6] * vtxMat[ 9];
        nrmMat[ 1] = vtxMat[ 6] * vtxMat[ 8] - vtxMat[ 4] * vtxMat[10];
        nrmMat[ 2] = vtxMat[ 4] * vtxMat[ 9] - vtxMat[ 5] * vtxMat[ 8];
        nrmMat[ 3] = vtxMat[ 2] * vtxMat[ 9] - vtxMat[ 1] * vtxMat[10];
        nrmMat[ 4] = vtxMat[ 0] * vtxMat[10] - vtxMat[ 2] * vtxMat[ 8];
        nrmMat[ 5] = vtxMat[ 1] * vtxMat[ 8] - vtxMat[ 0] * vtxMat[ 9];
        nrmMat[ 6] = vtxMat[ 1] * vtxMat[ 6] - vtxMat[ 2] * vtxMat[ 5];
        nrmMat[ 7] = vtxMat[ 2] * vtxMat[ 4] - vtxMat[ 0] * vtxMat[ 6];
        nrmMat[ 8] = vtxMat[ 0] * vtxMat[ 5] - vtxMat[ 1] * vtxMat[ 4];

        (*outTexCoord)[0][0] = data->texcoords[2 * vtx + 0];
        (*outTexCoord)[0][1] = data->texcoords[2 * vtx + 1];
        (*outTexCoord)[1][0] = (*outTexCoord)[0][0];
        (*outTexCoord)[1][1] = (*outTexCoord)[0][1];

        (*outXYZ)[0] =
            vtxMat[ 0] * data->positions[3 * vtx + 0] +
            vtxMat[ 1] * data->positions[3 * vtx + 1] +
            vtxMat[ 2] * data->positions[3 * vtx + 2] +
            vtxMat[ 3];
        (*outXYZ)[1] =
            vtxMat[ 4] * data->positions[3 * vtx + 0] +
            vtxMat[ 5] * data->positions[3 * vtx + 1] +
            vtxMat[ 6] * data->positions[3 * vtx + 2] +
            vtxMat[ 7];
        (*outXYZ)[2] =
            vtxMat[ 8] * data->positions[3 * vtx + 0] +
            vtxMat[ 9] * data->positions[3 * vtx + 1] +
            vtxMat[10] * data->positions[3 * vtx + 2] +
            vtxMat[11];
        (*outXYZ)[3] = 1.0f;

        (*outNormal)[0] =
            nrmMat[ 0] * data->normals[3 * vtx + 0] +
            nrmMat[ 1] * data->normals[3 * vtx + 1] +
            nrmMat[ 2] * data->normals[3 * vtx + 2];
        (*outNormal)[1] =
            nrmMat[ 3] * data->normals[3 * vtx + 0] +
            nrmMat[ 4] * data->normals[3 * vtx + 1] +
            nrmMat[ 5] * data->normals[3 * vtx + 2];
        (*outNormal)[2] =
            nrmMat[ 6] * data->normals[3 * vtx + 0] +
            nrmMat[ 7] * data->normals[3 * vtx + 1] +
            nrmMat[ 8] * data->normals[3 * vtx + 2];
        (*outNormal)[3] = 0.0f;

        (*outColor)[0] = data->colors[4 * vtx + 0];
        (*outColor)[1] = data->colors[4 * vtx + 1];
        (*outColor)[2] = data->colors[4 * vtx + 2];
        (*outColor)[3] = data->colors[4 * vtx + 3];
    }

    tri = data->triangles + 3 * surf->first_triangle;
    ptr = &tess.indexes[tess.numIndexes];
    base = tess.numVertexes;

    for (i = 0; i < surf->num_triangles; i++) {
        *ptr++ = base + (*tri++ - surf->first_vertex);
        *ptr++ = base + (*tri++ - surf->first_vertex);
        *ptr++ = base + (*tri++ - surf->first_vertex);
    }

    tess.numIndexes += 3 * surf->num_triangles;
    tess.numVertexes += surf->num_vertexes;
}
Beispiel #19
0
/*
=============
RB_StretchPic
=============
*/
const void *RB_StretchPic ( const void *data ) {
	const stretchPicCommand_t	*cmd;
	shader_t *shader;
	int		numVerts, numIndexes;

	cmd = (const stretchPicCommand_t *)data;

	// FIXME: HUGE hack
	if (glRefConfig.framebufferObject)
		FBO_Bind(backEnd.framePostProcessed ? NULL : tr.renderFbo);

	RB_SetGL2D();

	shader = cmd->shader;
	if ( shader != tess.shader ) {
		if ( tess.numIndexes ) {
			RB_EndSurface();
		}
		backEnd.currentEntity = &backEnd.entity2D;
		RB_BeginSurface( shader, 0, 0 );
	}

	RB_CHECKOVERFLOW( 4, 6 );
	numVerts = tess.numVertexes;
	numIndexes = tess.numIndexes;

	tess.numVertexes += 4;
	tess.numIndexes += 6;

	tess.indexes[ numIndexes ] = numVerts + 3;
	tess.indexes[ numIndexes + 1 ] = numVerts + 0;
	tess.indexes[ numIndexes + 2 ] = numVerts + 2;
	tess.indexes[ numIndexes + 3 ] = numVerts + 2;
	tess.indexes[ numIndexes + 4 ] = numVerts + 0;
	tess.indexes[ numIndexes + 5 ] = numVerts + 1;

	{
		uint16_t color[4];

		VectorScale4(backEnd.color2D, 257, color);

		VectorCopy4(color, tess.color[ numVerts ]);
		VectorCopy4(color, tess.color[ numVerts + 1]);
		VectorCopy4(color, tess.color[ numVerts + 2]);
		VectorCopy4(color, tess.color[ numVerts + 3 ]);
	}

	tess.xyz[ numVerts ][0] = cmd->x;
	tess.xyz[ numVerts ][1] = cmd->y;
	tess.xyz[ numVerts ][2] = 0;

	tess.texCoords[ numVerts ][0] = cmd->s1;
	tess.texCoords[ numVerts ][1] = cmd->t1;

	tess.xyz[ numVerts + 1 ][0] = cmd->x + cmd->w;
	tess.xyz[ numVerts + 1 ][1] = cmd->y;
	tess.xyz[ numVerts + 1 ][2] = 0;

	tess.texCoords[ numVerts + 1 ][0] = cmd->s2;
	tess.texCoords[ numVerts + 1 ][1] = cmd->t1;

	tess.xyz[ numVerts + 2 ][0] = cmd->x + cmd->w;
	tess.xyz[ numVerts + 2 ][1] = cmd->y + cmd->h;
	tess.xyz[ numVerts + 2 ][2] = 0;

	tess.texCoords[ numVerts + 2 ][0] = cmd->s2;
	tess.texCoords[ numVerts + 2 ][1] = cmd->t2;

	tess.xyz[ numVerts + 3 ][0] = cmd->x;
	tess.xyz[ numVerts + 3 ][1] = cmd->y + cmd->h;
	tess.xyz[ numVerts + 3 ][2] = 0;

	tess.texCoords[ numVerts + 3 ][0] = cmd->s1;
	tess.texCoords[ numVerts + 3 ][1] = cmd->t2;

	return (const void *)(cmd + 1);
}
Beispiel #20
0
/*
=============
RB_StretchPic
=============
*/
const void *RB_StretchPic ( const void *data ) {
	const stretchPicCommand_t	*cmd;
	shader_t *shader;
	int		numVerts, numIndexes;

	cmd = (const stretchPicCommand_t *)data;

	if ( !backEnd.projection2D ) {
		RB_SetGL2D();
	}

	shader = cmd->shader;
	if ( shader != tess.shader ) {
		if ( tess.numIndexes ) {
			RB_EndSurface();
		}
		backEnd.currentEntity = &backEnd.entity2D;
		RB_BeginSurface( shader, 0 );
	}

	RB_CHECKOVERFLOW( 4, 6 );
	numVerts = tess.numVertexes;
	numIndexes = tess.numIndexes;

	tess.numVertexes += 4;
	tess.numIndexes += 6;

	tess.indexes[ numIndexes ] = numVerts + 3;
	tess.indexes[ numIndexes + 1 ] = numVerts + 0;
	tess.indexes[ numIndexes + 2 ] = numVerts + 2;
	tess.indexes[ numIndexes + 3 ] = numVerts + 2;
	tess.indexes[ numIndexes + 4 ] = numVerts + 0;
	tess.indexes[ numIndexes + 5 ] = numVerts + 1;

	*(int *)tess.vertexColors[ numVerts ] =
		*(int *)tess.vertexColors[ numVerts + 1 ] =
		*(int *)tess.vertexColors[ numVerts + 2 ] =
		*(int *)tess.vertexColors[ numVerts + 3 ] = *(int *)backEnd.color2D;

	tess.xyz[ numVerts ][0] = cmd->x;
	tess.xyz[ numVerts ][1] = cmd->y;
	tess.xyz[ numVerts ][2] = 0;

	tess.texCoords[ numVerts ][0][0] = cmd->s1;
	tess.texCoords[ numVerts ][0][1] = cmd->t1;

	tess.xyz[ numVerts + 1 ][0] = cmd->x + cmd->w;
	tess.xyz[ numVerts + 1 ][1] = cmd->y;
	tess.xyz[ numVerts + 1 ][2] = 0;

	tess.texCoords[ numVerts + 1 ][0][0] = cmd->s2;
	tess.texCoords[ numVerts + 1 ][0][1] = cmd->t1;

	tess.xyz[ numVerts + 2 ][0] = cmd->x + cmd->w;
	tess.xyz[ numVerts + 2 ][1] = cmd->y + cmd->h;
	tess.xyz[ numVerts + 2 ][2] = 0;

	tess.texCoords[ numVerts + 2 ][0][0] = cmd->s2;
	tess.texCoords[ numVerts + 2 ][0][1] = cmd->t2;

	tess.xyz[ numVerts + 3 ][0] = cmd->x;
	tess.xyz[ numVerts + 3 ][1] = cmd->y + cmd->h;
	tess.xyz[ numVerts + 3 ][2] = 0;

	tess.texCoords[ numVerts + 3 ][0][0] = cmd->s1;
	tess.texCoords[ numVerts + 3 ][0][1] = cmd->t2;

	return (const void *)(cmd + 1);
}
static void RB_StretchPic ( const void *data )
{
	const stretchPicCommand_t *cmd = (const stretchPicCommand_t *)data;

	int i;

	shader_t *shader;
	int numVerts, numIndexes;

	if( !backEnd.projection2D )
		RB_SetGL2D();

	shader = cmd->shader;
	RB_CheckSurface( shader, 0, GL_TRIANGLES );

	RB_CHECKOVERFLOW( 4, 6 );
	numVerts = tess.numVertexes;
	numIndexes = tess.numIndexes;

	tess.numVertexes += 4;
	tess.numIndexes += 6;

	tess.indexes[ numIndexes ] = numVerts + 3;
	tess.indexes[ numIndexes + 1 ] = numVerts + 0;
	tess.indexes[ numIndexes + 2 ] = numVerts + 2;
	tess.indexes[ numIndexes + 3 ] = numVerts + 2;
	tess.indexes[ numIndexes + 4 ] = numVerts + 0;
	tess.indexes[ numIndexes + 5 ] = numVerts + 1;

	*(int *)tess.vertexColors[ numVerts ] =
		*(int *)tess.vertexColors[ numVerts + 1 ] =
		*(int *)tess.vertexColors[ numVerts + 2 ] =
		*(int *)tess.vertexColors[ numVerts + 3 ] = *(int *)backEnd.color2D;

	tess.xyz[ numVerts ][0] = cmd->x;
	tess.xyz[ numVerts ][1] = cmd->y;
	tess.xyz[ numVerts ][2] = 0;

	tess.texCoords[ numVerts ][0][0] = cmd->s1;
	tess.texCoords[ numVerts ][0][1] = cmd->t1;

	tess.xyz[ numVerts + 1 ][0] = cmd->x + cmd->w;
	tess.xyz[ numVerts + 1 ][1] = cmd->y;
	tess.xyz[ numVerts + 1 ][2] = 0;

	tess.texCoords[ numVerts + 1 ][0][0] = cmd->s2;
	tess.texCoords[ numVerts + 1 ][0][1] = cmd->t1;

	tess.xyz[ numVerts + 2 ][0] = cmd->x + cmd->w;
	tess.xyz[ numVerts + 2 ][1] = cmd->y + cmd->h;
	tess.xyz[ numVerts + 2 ][2] = 0;

	tess.texCoords[ numVerts + 2 ][0][0] = cmd->s2;
	tess.texCoords[ numVerts + 2 ][0][1] = cmd->t2;

	tess.xyz[ numVerts + 3 ][0] = cmd->x;
	tess.xyz[ numVerts + 3 ][1] = cmd->y + cmd->h;
	tess.xyz[ numVerts + 3 ][2] = 0;

	tess.texCoords[ numVerts + 3 ][0][0] = cmd->s1;
	tess.texCoords[ numVerts + 3 ][0][1] = cmd->t2;

	for( i = 0; i < 4; i++ )
	{
		vec2_t v;

		Vec2_Cpy( v, tess.xyz[numVerts + i] );

		tess.xyz[numVerts + i][0] = v[0] * cmd->mat[0][0] + v[1] * cmd->mat[0][1] + cmd->mat[0][2];
		tess.xyz[numVerts + i][1] = v[0] * cmd->mat[1][0] + v[1] * cmd->mat[1][1] + cmd->mat[1][2];
	}
}