示例#1
0
/*
================
DrawNormals

Draws vertex normals for debugging
================
*/
static void DrawNormals( shaderCommands_t *input ) {
	int i;
	vec3_t temp;

	GL_Bind( tr.whiteImage );
	qglColor3f( 1,1,1 );
	qglDepthRange( 0, 0 );  // never occluded
	GL_State( GLS_POLYMODE_LINE | GLS_DEPTHMASK_TRUE );

	// ydnar: light direction
	if ( r_shownormals->integer == 2 ) {
		trRefEntity_t   *ent = backEnd.currentEntity;
		vec3_t temp2;

		if ( ent->e.renderfx & RF_LIGHTING_ORIGIN ) {
			VectorSubtract( ent->e.lightingOrigin, backEnd.orientation.origin, temp2 );
		} else {
			VectorClear( temp2 );
		}
		temp[ 0 ] = DotProduct( temp2, backEnd.orientation.axis[ 0 ] );
		temp[ 1 ] = DotProduct( temp2, backEnd.orientation.axis[ 1 ] );
		temp[ 2 ] = DotProduct( temp2, backEnd.orientation.axis[ 2 ] );

		qglColor3f( ent->ambientLight[ 0 ] / 255, ent->ambientLight[ 1 ] / 255, ent->ambientLight[ 2 ] / 255 );
		qglPointSize( 5 );
		qglBegin( GL_POINTS );
		qglVertex3fv( temp );
		qglEnd();
		qglPointSize( 1 );

		if ( fabs( VectorLengthSquared( ent->lightDir ) - 1.0f ) > 0.2f ) {
			qglColor3f( 1, 0, 0 );
		} else {
			qglColor3f( ent->directedLight[ 0 ] / 255, ent->directedLight[ 1 ] / 255, ent->directedLight[ 2 ] / 255 );
		}
		qglLineWidth( 3 );
		qglBegin( GL_LINES );
		qglVertex3fv( temp );
		VectorMA( temp, 32, ent->lightDir, temp );
		qglVertex3fv( temp );
		qglEnd();
		qglLineWidth( 1 );
	}
	// ydnar: normals drawing
	else
	{
		qglBegin( GL_LINES );
		for ( i = 0 ; i < input->numVertexes ; i++ ) {
			qglVertex3fv( input->xyz[i].v );
			VectorMA( input->xyz[i].v, r_normallength->value, input->normal[i].v, temp );
			qglVertex3fv( temp );
		}
		qglEnd();
	}

	qglDepthRange( 0, 1 );
}
示例#2
0
void Terrain_DrawCam( terrainMesh_t *pm ) {
	qglColor3f( 1,1,1 );
	qglPushAttrib( GL_ALL_ATTRIB_BITS );

	if ( g_bPatchWireFrame ) {
		if( pm->bSelected ) {
			qglLineWidth( 2 );
		} else {
			qglLineWidth( 1 );
		}

		qglDisable( GL_CULL_FACE );
		qglPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
		qglDisable( GL_TEXTURE_2D );

		if ( g_PrefsDlg.m_bGLLighting ) {
			qglDisable( GL_LIGHTING );
		}

		DrawTerrain( pm, pm->bSelected, true );

		if ( g_PrefsDlg.m_bGLLighting ) {
			qglEnable( GL_LIGHTING );
		}

		qglEnable( GL_CULL_FACE );
		qglLineWidth( 1 );
	} else {
		qglEnable( GL_CULL_FACE );
		qglCullFace( GL_FRONT );

		// draw the textured polys
		DrawTerrain( pm, pm->bSelected, true );

		// if selected, draw the red tint on the polys
		if( pm->bSelected ) { // && ( g_qeglobals.d_savedinfo.include & INCLUDE_CAMERATINT ) ) {
			qglColor4f( 1.0, 0.0, 0.0, 0.3 );
			qglEnable( GL_BLEND );
			qglPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
			qglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );

			DrawTerrain( pm, pm->bSelected );

			qglColor3f( 1, 1, 1 );
		}

		// draw the backside poly outlines
		qglCullFace( GL_BACK );
		qglPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
		qglDisable( GL_BLEND );
		DrawTerrain( pm, pm->bSelected, true );
	}

	qglPopAttrib();
}
示例#3
0
void Pointfile_Draw( void )
{
	int i;

	qglColor3f( 1.0F, 0.0F, 0.0F );
	qglDisable(GL_TEXTURE_2D);
	qglDisable(GL_TEXTURE_1D);
	qglLineWidth (2);
	qglBegin(GL_LINE_STRIP);
	for ( i = 0; i < s_num_points; i++ )
	{
		qglVertex3fv( s_pointvecs[i].ToFloatPtr() );
	}
	qglEnd();
	qglLineWidth( 0.5 );
}
// Draws from modelview space
void GLRB_SurfaceAxis( void ) {
	GL_Bind( tr.whiteImage );
	qglLineWidth( 3 );
	qglBegin( GL_LINES );
	qglColor3f( 1,0,0 );
	qglVertex3f( 0,0,0 );
	qglVertex3f( 16,0,0 );
	qglColor3f( 0,1,0 );
	qglVertex3f( 0,0,0 );
	qglVertex3f( 0,16,0 );
	qglColor3f( 0,0,1 );
	qglVertex3f( 0,0,0 );
	qglVertex3f( 0,0,16 );
	qglEnd();
	qglLineWidth( 1 );
}
示例#5
0
void WINAPI Pointfile_Check (void)
{
    char	name[1024];
    FILE	*f;
    idVec3	v;

    strcpy (name, currentmap);
    StripExtension (name);
    strcat (name, ".lin");

    f = fopen (name, "r");
    if (!f)
        return;

    common->Printf ("Reading pointfile %s\n", name);

    if (!g_qeglobals.d_pointfile_display_list)
        g_qeglobals.d_pointfile_display_list = qglGenLists(1);

    s_num_points = 0;
    qglNewList (g_qeglobals.d_pointfile_display_list,  GL_COMPILE);
    qglColor3f (1, 0, 0);
    qglDisable(GL_TEXTURE_2D);
    qglDisable(GL_TEXTURE_1D);
    qglLineWidth (2);
    qglBegin(GL_LINE_STRIP);
    do
    {
        if (fscanf (f, "%f %f %f\n", &v[0], &v[1], &v[2]) != 3)
            break;
        if (s_num_points < MAX_POINTFILE)
        {
            VectorCopy (v, s_pointvecs[s_num_points]);
            s_num_points++;
        }
        qglVertex3fv( v.ToFloatPtr() );
    }
    while (1);
    qglEnd();
    qglLineWidth (0.5);
    qglEndList ();

    s_check_point = 0;
    fclose (f);
    //Pointfile_Next ();
}
示例#6
0
/*
===================
RB_OutlinesPass

Draws outlines on surfaces with shader.hasOutlines set
===================
*/
static void RB_OutlinesPass( void ) {	

	int		outlines;
	float	outlinesAlpha;

	outlines		= r_outlines->value;
	outlinesAlpha	= r_outlinesAlpha->value;

	if ( !tess.shader->hasOutlines )
		return;	

	if ( !r_outlines->integer )
		return;

	GL_Bind( tr.whiteImage );
	qglColor4f( 0, 0, 0, outlinesAlpha );
		
	GL_State( GLS_POLYMODE_LINE | GLS_DEPTHMASK_TRUE | GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA );
	qglPolygonMode( GL_BACK, GL_LINE );
	qglLineWidth( outlines + 1 );
			
	qglCullFace( GL_BACK );
		
	qglDisableClientState( GL_COLOR_ARRAY );
	qglDisableClientState( GL_TEXTURE_COORD_ARRAY );

	qglVertexPointer (3, GL_FLOAT, 16, tess.xyz);	// padded for SIMD
			
	if (qglLockArraysEXT) {
		qglLockArraysEXT(0, tess.numVertexes);
		GLimp_LogComment( "glLockArraysEXT\n" );
	}
	
	R_DrawElements( tess.numIndexes, tess.indexes );
		
	if (qglUnlockArraysEXT) {
		qglUnlockArraysEXT();
		GLimp_LogComment( "glUnlockArraysEXT\n" );
	}

	// FIX: Must reset these manually or renderer will b0rk!
	qglCullFace( GL_FRONT ); 
	qglLineWidth( 1 );
}
示例#7
0
/*
===================
RB_SurfaceAxis

Draws x/y/z lines from the origin for orientation debugging
===================
*/
static void RB_SurfaceAxis( void ) {
	// FIXME: implement this
#if 0
	GL_BindToTMU( tr.whiteImage, TB_COLORMAP );
	GL_State( GLS_DEFAULT );
	qglLineWidth( 3 );
	qglBegin( GL_LINES );
	qglColor3f( 1,0,0 );
	qglVertex3f( 0,0,0 );
	qglVertex3f( 16,0,0 );
	qglColor3f( 0,1,0 );
	qglVertex3f( 0,0,0 );
	qglVertex3f( 0,16,0 );
	qglColor3f( 0,0,1 );
	qglVertex3f( 0,0,0 );
	qglVertex3f( 0,0,16 );
	qglEnd();
	qglLineWidth( 1 );
#endif
}
示例#8
0
void Terrain_DrawXY( terrainMesh_t *pm, entity_t *owner ) {
	qglPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
   
	if ( pm->bSelected ) {
		qglColor3fv( g_qeglobals.d_savedinfo.colors[ COLOR_SELBRUSHES ] );
	} else if ( owner != world_entity && _stricmp( owner->eclass->name, "func_group" ) ) {
		qglColor3fv( owner->eclass->color );
	} else {
		//FIXME
		qglColor3fv( g_qeglobals.d_savedinfo.colors[ COLOR_BRUSHES ] );
	}
	
	qglLineWidth( 1 );

	DrawTerrain( pm, pm->bSelected );

	qglPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
}
示例#9
0
void idGLDrawable::draw(int x, int y, int w, int h) {
    GL_State( GLS_DEFAULT );
    qglViewport(x, y, w, h);
    qglScissor(x, y, w, h);
    qglMatrixMode(GL_PROJECTION);
    qglClearColor( 0.1f, 0.1f, 0.1f, 0.0f );
    qglClear(GL_COLOR_BUFFER_BIT);
    qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    qglLineWidth(0.5);
    qglColor3f(1, 1, 1);
    globalImages->BindNull();
    qglBegin(GL_LINE_LOOP);
    qglColor3f(1, 0, 0);
    qglVertex2f(x + 3, y + 3);
    qglColor3f(0, 1, 0);
    qglVertex2f(x + 3, h - 3);
    qglColor3f(0, 0, 1);
    qglVertex2f(w - 3, h - 3);
    qglColor3f(1, 1, 1);
    qglVertex2f(w - 3, y + 3);
    qglEnd();

}
示例#10
0
/*
================
DrawTris

Draws triangle outlines for debugging
================
*/
static void DrawTris( shaderCommands_t *input ) {
	char            *s = r_trisColor->string;
	vec4_t trisColor = { 1, 1, 1, 1 };
	unsigned int stateBits = 0;

	GL_Bind( tr.whiteImage );

	if ( *s == '0' && ( *( s + 1 ) == 'x' || *( s + 1 ) == 'X' ) ) {
		s += 2;
		if ( Q_IsHexColorString( s ) ) {
			trisColor[0] = ( (float)( gethex( *( s ) ) * 16 + gethex( *( s + 1 ) ) ) ) / 255.00;
			trisColor[1] = ( (float)( gethex( *( s + 2 ) ) * 16 + gethex( *( s + 3 ) ) ) ) / 255.00;
			trisColor[2] = ( (float)( gethex( *( s + 4 ) ) * 16 + gethex( *( s + 5 ) ) ) ) / 255.00;

			if ( Q_HexColorStringHasAlpha( s ) ) {
				trisColor[3] = ( (float)( gethex( *( s + 6 ) ) * 16 + gethex( *( s + 7 ) ) ) ) / 255.00;
			}
		}
	} else {
		int i;
		char    *token;

		for ( i = 0 ; i < 4 ; i++ ) {
			token = COM_Parse( &s );
			if ( token ) {
				trisColor[i] = atof( token );
			} else {
				trisColor[i] = 1.f;
			}
		}

		if ( !trisColor[3] ) {
			trisColor[3] = 1.f;
		}
	}

	if ( trisColor[3] < 1.f ) {
		stateBits |= ( GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA );
	}

	qglColor4fv( trisColor );

	// ydnar r_showtris 2
	if ( r_showtris->integer == 2 ) {
		stateBits |= ( GLS_POLYMODE_LINE | GLS_DEPTHMASK_TRUE );
		GL_State( stateBits );
		qglDepthRange( 0, 0 );
	}
	#ifdef CELSHADING_HACK
	else if ( r_showtris->integer == 3 ) {
		stateBits |= ( GLS_POLYMODE_LINE | GLS_DEPTHMASK_TRUE );
		GL_State( stateBits );
		qglEnable( GL_POLYGON_OFFSET_LINE );
		qglPolygonOffset( 4.0, 0.5 );
		qglLineWidth( 5.0 );
	}
	#endif
	else
	{
		stateBits |= ( GLS_POLYMODE_LINE );
		GL_State( stateBits );
		qglEnable( GL_POLYGON_OFFSET_LINE );
		qglPolygonOffset( r_offsetFactor->value, r_offsetUnits->value );
	}

	qglDisableClientState( GL_COLOR_ARRAY );
	qglDisableClientState( GL_TEXTURE_COORD_ARRAY );

	qglVertexPointer( 3, GL_FLOAT, 16, input->xyz ); // padded for SIMD

	if ( qglLockArraysEXT ) {
		qglLockArraysEXT( 0, input->numVertexes );
		GLimp_LogComment( "glLockArraysEXT\n" );
	}

	R_DrawElements( input->numIndexes, input->indexes );

	if ( qglUnlockArraysEXT ) {
		qglUnlockArraysEXT();
		GLimp_LogComment( "glUnlockArraysEXT\n" );
	}
	qglDepthRange( 0, 1 );
	qglDisable( GL_POLYGON_OFFSET_LINE );
}
示例#11
0
/*
==============
R_CalcBones

    The list of bones[] should only be built and modified from within here
==============
*/
void R_CalcBones(mdsHeader_t *header, const refEntity_t *refent, int *boneList, int numBones)
{
	int   i;
	int   *boneRefs;
	float torsoWeight;

	// if the entity has changed since the last time the bones were built, reset them
	if (memcmp(&lastBoneEntity, refent, sizeof(refEntity_t)))
	{
		// different, cached bones are not valid
		memset(validBones, 0, header->numBones);
		lastBoneEntity = *refent;

		// (SA) also reset these counter statics
		//----(SA)	print stats for the complete model (not per-surface)
		if (r_bonesDebug->integer == 4 && totalrt)
		{
			Ren_Print("Lod %.2f  verts %4d/%4d  tris %4d/%4d  (%.2f%%)\n",
			          lodScale,
			          totalrv,
			          totalv,
			          totalrt,
			          totalt,
			          ( float )(100.0 * totalrt) / (float) totalt);
		}
		totalrv = totalrt = totalv = totalt = 0;
	}

	memset(newBones, 0, header->numBones);

	if (refent->oldframe == refent->frame)
	{
		backlerp  = 0;
		frontlerp = 1;
	}
	else
	{
		backlerp  = refent->backlerp;
		frontlerp = 1.0f - backlerp;
	}

	if (refent->oldTorsoFrame == refent->torsoFrame)
	{
		torsoBacklerp  = 0;
		torsoFrontlerp = 1;
	}
	else
	{
		torsoBacklerp  = refent->torsoBacklerp;
		torsoFrontlerp = 1.0f - torsoBacklerp;
	}

	frameSize = (int) (sizeof(mdsFrame_t) + (header->numBones - 1) * sizeof(mdsBoneFrameCompressed_t));

	frame = ( mdsFrame_t * )((byte *)header + header->ofsFrames +
	                         refent->frame * frameSize);
	torsoFrame = ( mdsFrame_t * )((byte *)header + header->ofsFrames +
	                              refent->torsoFrame * frameSize);
	oldFrame = ( mdsFrame_t * )((byte *)header + header->ofsFrames +
	                            refent->oldframe * frameSize);
	oldTorsoFrame = ( mdsFrame_t * )((byte *)header + header->ofsFrames +
	                                 refent->oldTorsoFrame * frameSize);

	// lerp all the needed bones (torsoParent is always the first bone in the list)
	cBoneList      = frame->bones;
	cBoneListTorso = torsoFrame->bones;

	boneInfo = ( mdsBoneInfo_t * )((byte *)header + header->ofsBones);
	boneRefs = boneList;
	//
	Matrix3Transpose(refent->torsoAxis, torsoAxis);

#ifdef HIGH_PRECISION_BONES
	if (qtrue)
	{
#else
	if (!backlerp && !torsoBacklerp)
	{
#endif
		for (i = 0; i < numBones; i++, boneRefs++)
		{
			if (validBones[*boneRefs])
			{
				// this bone is still in the cache
				bones[*boneRefs] = rawBones[*boneRefs];
				continue;
			}

			// find our parent, and make sure it has been calculated
			if ((boneInfo[*boneRefs].parent >= 0) && (!validBones[boneInfo[*boneRefs].parent] && !newBones[boneInfo[*boneRefs].parent]))
			{
				R_CalcBone(header, refent, boneInfo[*boneRefs].parent);
			}

			R_CalcBone(header, refent, *boneRefs);
		}
	}
	else        // interpolated
	{
		cOldBoneList      = oldFrame->bones;
		cOldBoneListTorso = oldTorsoFrame->bones;

		for (i = 0; i < numBones; i++, boneRefs++)
		{
			if (validBones[*boneRefs])
			{
				// this bone is still in the cache
				bones[*boneRefs] = rawBones[*boneRefs];
				continue;
			}

			// find our parent, and make sure it has been calculated
			if ((boneInfo[*boneRefs].parent >= 0) && (!validBones[boneInfo[*boneRefs].parent] && !newBones[boneInfo[*boneRefs].parent]))
			{
				R_CalcBoneLerp(header, refent, boneInfo[*boneRefs].parent);
			}

			R_CalcBoneLerp(header, refent, *boneRefs);
		}
	}

	// adjust for torso rotations
	torsoWeight = 0;
	boneRefs    = boneList;
	for (i = 0; i < numBones; i++, boneRefs++)
	{
		thisBoneInfo = &boneInfo[*boneRefs];
		bonePtr      = &bones[*boneRefs];
		// add torso rotation
		if (thisBoneInfo->torsoWeight > 0)
		{
			if (!newBones[*boneRefs])
			{
				// just copy it back from the previous calc
				bones[*boneRefs] = oldBones[*boneRefs];
				continue;
			}

			if (!(thisBoneInfo->flags & BONEFLAG_TAG))
			{
				// 1st multiply with the bone->matrix
				// 2nd translation for rotation relative to bone around torso parent offset
				VectorSubtract(bonePtr->translation, torsoParentOffset, t);
				Matrix4FromAxisPlusTranslation(bonePtr->matrix, t, m1);
				// 3rd scaled rotation
				// 4th translate back to torso parent offset
				// use previously created matrix if available for the same weight
				if (torsoWeight != thisBoneInfo->torsoWeight)
				{
					Matrix4FromScaledAxisPlusTranslation(torsoAxis, thisBoneInfo->torsoWeight, torsoParentOffset, m2);
					torsoWeight = thisBoneInfo->torsoWeight;
				}
				// multiply matrices to create one matrix to do all calculations
				Matrix4MultiplyInto3x3AndTranslation(m2, m1, bonePtr->matrix, bonePtr->translation);

			}
			else        // tag's require special handling
			{   // rotate each of the axis by the torsoAngles
				LocalScaledMatrixTransformVector(bonePtr->matrix[0], thisBoneInfo->torsoWeight, torsoAxis, tmpAxis[0]);
				LocalScaledMatrixTransformVector(bonePtr->matrix[1], thisBoneInfo->torsoWeight, torsoAxis, tmpAxis[1]);
				LocalScaledMatrixTransformVector(bonePtr->matrix[2], thisBoneInfo->torsoWeight, torsoAxis, tmpAxis[2]);
				memcpy(bonePtr->matrix, tmpAxis, sizeof(tmpAxis));

				// rotate the translation around the torsoParent
				VectorSubtract(bonePtr->translation, torsoParentOffset, t);
				LocalScaledMatrixTransformVector(t, thisBoneInfo->torsoWeight, torsoAxis, bonePtr->translation);
				VectorAdd(bonePtr->translation, torsoParentOffset, bonePtr->translation);
			}
		}
	}

	// backup the final bones
	memcpy(oldBones, bones, sizeof(bones[0]) * header->numBones);
}

#ifdef DBG_PROFILE_BONES
#define DBG_SHOWTIME    Ren_Print("%i: %i, ", di++, (dt = ri.Milliseconds()) - ldt); ldt = dt;
#else
#define DBG_SHOWTIME    ;
#endif

/*
==============
RB_SurfaceAnim
==============
*/
void RB_SurfaceAnim(mdsSurface_t *surface)
{
	int         j, k;
	refEntity_t *refent;
	int         *boneList;
	mdsHeader_t *header;

#ifdef DBG_PROFILE_BONES
	int di = 0, dt, ldt;

	dt  = ri.Milliseconds();
	ldt = dt;
#endif

	refent   = &backEnd.currentEntity->e;
	boneList = ( int * )((byte *)surface + surface->ofsBoneReferences);
	header   = ( mdsHeader_t * )((byte *)surface + surface->ofsHeader);

	R_CalcBones(header, (const refEntity_t *)refent, boneList, surface->numBoneReferences);

	DBG_SHOWTIME

	// calculate LOD
	// TODO: lerp the radius and origin
	VectorAdd(refent->origin, frame->localOrigin, vec);
	lodRadius = frame->radius;
	lodScale  = RB_CalcMDSLod(refent, vec, lodRadius, header->lodBias, header->lodScale);


//DBG_SHOWTIME

	// modification to allow dead skeletal bodies to go below minlod (experiment)
	if (refent->reFlags & REFLAG_DEAD_LOD)
	{
		if (lodScale < 0.35)       // allow dead to lod down to 35% (even if below surf->minLod) (%35 is arbitrary and probably not good generally.  worked for the blackguard/infantry as a test though)
		{
			lodScale = 0.35;
		}
		render_count = ROUND_INT(surface->numVerts * lodScale);

	}
	else
	{
		render_count = ROUND_INT(surface->numVerts * lodScale);
		if (render_count < surface->minLod)
		{
			if (!(refent->reFlags & REFLAG_DEAD_LOD))
			{
				render_count = surface->minLod;
			}
		}
	}

	if (render_count > surface->numVerts)
	{
		render_count = surface->numVerts;
	}

	RB_CheckOverflow(render_count, surface->numTriangles);

//DBG_SHOWTIME

	// setup triangle list
	RB_CheckOverflow(surface->numVerts, surface->numTriangles * 3);

//DBG_SHOWTIME

	collapse_map = ( int * )(( byte * )surface + surface->ofsCollapseMap);
	triangles    = ( int * )((byte *)surface + surface->ofsTriangles);
	indexes      = surface->numTriangles * 3;
	baseIndex    = tess.numIndexes;
	baseVertex   = tess.numVertexes;
	oldIndexes   = baseIndex;

	tess.numVertexes += render_count;

	pIndexes = &tess.indexes[baseIndex];

//DBG_SHOWTIME

	if (render_count == surface->numVerts)
	{
		memcpy(pIndexes, triangles, sizeof(triangles[0]) * indexes);
		if (baseVertex)
		{
			glIndex_t *indexesEnd;
			for (indexesEnd = pIndexes + indexes ; pIndexes < indexesEnd ; pIndexes++)
			{
				*pIndexes += baseVertex;
			}
		}
		tess.numIndexes += indexes;
	}
	else
	{
		int *collapseEnd;

		pCollapse = collapse;
		for (j = 0; j < render_count; pCollapse++, j++)
		{
			*pCollapse = j;
		}

		pCollapseMap = &collapse_map[render_count];
		for (collapseEnd = collapse + surface->numVerts ; pCollapse < collapseEnd; pCollapse++, pCollapseMap++)
		{
			*pCollapse = collapse[*pCollapseMap];
		}

		for (j = 0 ; j < indexes ; j += 3)
		{
			p0 = collapse[*(triangles++)];
			p1 = collapse[*(triangles++)];
			p2 = collapse[*(triangles++)];

			// FIXME
			// note:  serious optimization opportunity here,
			//  by sorting the triangles the following "continue"
			//  could have been made into a "break" statement.
			if (p0 == p1 || p1 == p2 || p2 == p0)
			{
				continue;
			}

			*(pIndexes++)    = baseVertex + p0;
			*(pIndexes++)    = baseVertex + p1;
			*(pIndexes++)    = baseVertex + p2;
			tess.numIndexes += 3;
		}

		baseIndex = tess.numIndexes;
	}

//DBG_SHOWTIME

	// deform the vertexes by the lerped bones

	numVerts   = surface->numVerts;
	v          = ( mdsVertex_t * )((byte *)surface + surface->ofsVerts);
	tempVert   = ( float * )(tess.xyz + baseVertex);
	tempNormal = ( float * )(tess.normal + baseVertex);
	for (j = 0; j < render_count; j++, tempVert += 4, tempNormal += 4)
	{
		mdsWeight_t *w;

		VectorClear(tempVert);

		w = v->weights;
		for (k = 0 ; k < v->numWeights ; k++, w++)
		{
			bone = &bones[w->boneIndex];
			LocalAddScaledMatrixTransformVectorTranslate(w->offset, w->boneWeight, bone->matrix, bone->translation, tempVert);
		}

		LocalMatrixTransformVector(v->normal, bones[v->weights[0].boneIndex].matrix, tempNormal);

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

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

	DBG_SHOWTIME

	if (r_bonesDebug->integer)
	{
		if (r_bonesDebug->integer < 3)
		{
			int i;

			// DEBUG: show the bones as a stick figure with axis at each bone
			boneRefs = ( int * )((byte *)surface + surface->ofsBoneReferences);
			for (i = 0; i < surface->numBoneReferences; i++, boneRefs++)
			{
				bonePtr = &bones[*boneRefs];

				GL_Bind(tr.whiteImage);
				qglLineWidth(1);
				qglBegin(GL_LINES);
				for (j = 0; j < 3; j++)
				{
					VectorClear(vec);
					vec[j] = 1;
					qglColor3fv(vec);
					qglVertex3fv(bonePtr->translation);
					VectorMA(bonePtr->translation, 5, bonePtr->matrix[j], vec);
					qglVertex3fv(vec);
				}
				qglEnd();

				// connect to our parent if it's valid
				if (validBones[boneInfo[*boneRefs].parent])
				{
					qglLineWidth(2);
					qglBegin(GL_LINES);
					qglColor3f(.6, .6, .6);
					qglVertex3fv(bonePtr->translation);
					qglVertex3fv(bones[boneInfo[*boneRefs].parent].translation);
					qglEnd();
				}

				qglLineWidth(1);
			}
		}

		if (r_bonesDebug->integer == 3 || r_bonesDebug->integer == 4)
		{
			int render_indexes = (tess.numIndexes - oldIndexes);

			// show mesh edges
			tempVert   = ( float * )(tess.xyz + baseVertex);
			tempNormal = ( float * )(tess.normal + baseVertex);

			GL_Bind(tr.whiteImage);
			qglLineWidth(1);
			qglBegin(GL_LINES);
			qglColor3f(.0, .0, .8);

			pIndexes = &tess.indexes[oldIndexes];
			for (j = 0; j < render_indexes / 3; j++, pIndexes += 3)
			{
				qglVertex3fv(tempVert + 4 * pIndexes[0]);
				qglVertex3fv(tempVert + 4 * pIndexes[1]);

				qglVertex3fv(tempVert + 4 * pIndexes[1]);
				qglVertex3fv(tempVert + 4 * pIndexes[2]);

				qglVertex3fv(tempVert + 4 * pIndexes[2]);
				qglVertex3fv(tempVert + 4 * pIndexes[0]);
			}

			qglEnd();

			// track debug stats
			if (r_bonesDebug->integer == 4)
			{
				totalrv += render_count;
				totalrt += render_indexes / 3;
				totalv  += surface->numVerts;
				totalt  += surface->numTriangles;
			}

			if (r_bonesDebug->integer == 3)
			{
				Ren_Print("Lod %.2f  verts %4d/%4d  tris %4d/%4d  (%.2f%%)\n", lodScale, render_count, surface->numVerts, render_indexes / 3, surface->numTriangles,
				          ( float )(100.0 * render_indexes / 3) / (float) surface->numTriangles);
			}
		}
	}

	if (r_bonesDebug->integer > 1)
	{
		// dont draw the actual surface
		tess.numIndexes  = oldIndexes;
		tess.numVertexes = baseVertex;
		return;
	}

#ifdef DBG_PROFILE_BONES
	Ren_Print("\n");
#endif
}
示例#12
0
//R_DRAWCEL
static void R_DrawCel( int numIndexes, const glIndex_t *indexes ) {
	int		primitives;
	
	if(
		//. ignore the 2d projection. do i smell the HUD?
		(backEnd.projection2D == qtrue) ||
		//. ignore general entitites that are sprites. SEE NOTE #3.
		(backEnd.currentEntity->e.reType == RT_SPRITE) ||
		//. ignore these liquids. why? ever see liquid with tris on the surface? exactly. SEE NOTE #4.
		(tess.shader->contentFlags & (CONTENTS_WATER | CONTENTS_LAVA | CONTENTS_SLIME | CONTENTS_FOG)) ||
		//. ignore things that are two sided, meaning mostly things that have transparency. SEE NOTE #1.		
		(tess.shader->cullType == CT_TWO_SIDED)
		
		) {
		return;
	}

	primitives = r_primitives->integer;

	// default is to use triangles if compiled vertex arrays are present
	if ( primitives == 0 ) {
		if ( qglLockArraysEXT ) {
			primitives = 2;
		} else {
			primitives = 1;
		}
	}

	//. correction for mirrors. SEE NOTE #2.
	if(backEnd.viewParms.isMirror == qtrue) { qglCullFace (GL_FRONT); }
	else { qglCullFace (GL_BACK); }	

	qglEnable (GL_BLEND);
	qglBlendFunc (GL_SRC_ALPHA ,GL_ONE_MINUS_SRC_ALPHA);
	qglColor3f (0.0f,0.0f,0.0f);
	qglLineWidth( (float) r_celoutline->integer );	

	if(primitives == 2) {
		qglDrawElements( GL_TRIANGLES, numIndexes, GL_INDEX_TYPE, indexes );
	} else if(primitives == 1) {
		R_DrawStripElements( numIndexes,  indexes, qglArrayElement );
	} else if(primitives == 3) {
		R_DrawStripElements( numIndexes,  indexes, R_ArrayElementDiscrete );
	}

	//. correction for mirrors. SEE NOTE #2.
	if(backEnd.viewParms.isMirror == qtrue) { qglCullFace (GL_BACK); }
	else { qglCullFace (GL_FRONT); }
	
	qglDisable (GL_BLEND);
	
	return;

/* Notes

1. this is going to be a pain in the arse. it fixes things like light `beams` from being cel'd but it
also will ignore any other shader set with no culling. this usually is everything that is translucent.
but this is a good hack to clean up the screen untill something more selective comes along. or who knows
group desision might actually be that this is liked. if so i take back calling it a `hack`, lol.
	= bob.

2. mirrors display correctly because the normals of the displayed are inverted of normal space. so to
continue to have them display correctly, we must invert them inversely from a normal inversion.
	= bob.
	
3. this turns off a lot of space hogging sprite cel outlines. picture if you will five people in a small
room all shooting rockets. each smoke puff gets a big black square around it, each explosion gets a big
black square around it, and now nobody can see eachother because everyones screen is solid black.
	= bob.

4. ignoring liquids means you will not get black tris lines all over the top of your liquid. i put this in
after seeing the lava on q3dm7 and water on q3ctf2 that had black lines all over the top, making the
liquids look solid instead of... liquid.
	= bob.

*/
}
示例#13
0
/*
 =======================================================================================================================
 =======================================================================================================================
 */
void CNewTexWnd::OnPaint() {

	CPaintDC	dc(this);	// device context for painting

	int nOld = g_qeglobals.d_texturewin.m_nTotalHeight;

	//hdcTexture = GetDC();
	if (!qwglMakeCurrent(dc.GetSafeHdc(), win32.hGLRC)) {
		common->Printf("ERROR: wglMakeCurrent failed..\n ");
	}
	else {
		const char	*name;
		qglClearColor
		(
			g_qeglobals.d_savedinfo.colors[COLOR_TEXTUREBACK][0],
			g_qeglobals.d_savedinfo.colors[COLOR_TEXTUREBACK][1],
			g_qeglobals.d_savedinfo.colors[COLOR_TEXTUREBACK][2],
			0
		);
		qglViewport(0, 0, rectClient.Width(), rectClient.Height());
		qglScissor(0, 0, rectClient.Width(), rectClient.Height());
		qglMatrixMode(GL_PROJECTION);
		qglLoadIdentity();
		qglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		qglDisable(GL_DEPTH_TEST);
		qglDisable(GL_BLEND);
		qglOrtho(0, rectClient.Width(), origin.y - rectClient.Height(), origin.y, -100, 100);
		qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

		// init stuff
		current.x = 8;
		current.y = -8;
		currentRow = 0;
		currentIndex = 0;
		while (1) {
			const idMaterial *mat = NextPos();
			if (mat == NULL) {
				break;
			}

			int width = mat->GetEditorImage()->uploadWidth * ((float)g_PrefsDlg.m_nTextureScale / 100);
			int height = mat->GetEditorImage()->uploadHeight * ((float)g_PrefsDlg.m_nTextureScale / 100);

			// Is this texture visible?
			if ((draw.y - height - FONT_HEIGHT < origin.y) && (draw.y > origin.y - rectClient.Height())) {
				// if in use, draw a background
				qglLineWidth(1);
				qglColor3f(1, 1, 1);
				globalImages->BindNull();
				qglBegin(GL_LINE_LOOP);
				qglVertex2f(draw.x - 1, draw.y + 1 - FONT_HEIGHT);
				qglVertex2f(draw.x - 1, draw.y - height - 1 - FONT_HEIGHT);
				qglVertex2f(draw.x + 1 + width, draw.y - height - 1 - FONT_HEIGHT);
				qglVertex2f(draw.x + 1 + width, draw.y + 1 - FONT_HEIGHT);
				qglEnd();

				// Draw the texture
				float	fScale = (g_PrefsDlg.m_bHiColorTextures == TRUE) ? ((float)g_PrefsDlg.m_nTextureScale / 100) : 1.0;

				mat->GetEditorImage()->Bind();
				QE_CheckOpenGLForErrors();
				qglColor3f(1, 1, 1);
				qglBegin(GL_QUADS);
				qglTexCoord2f(0, 0);
				qglVertex2f(draw.x, draw.y - FONT_HEIGHT);
				qglTexCoord2f(1, 0);
				qglVertex2f(draw.x + width, draw.y - FONT_HEIGHT);
				qglTexCoord2f(1, 1);
				qglVertex2f(draw.x + width, draw.y - FONT_HEIGHT - height);
				qglTexCoord2f(0, 1);
				qglVertex2f(draw.x, draw.y - FONT_HEIGHT - height);
				qglEnd();

				// draw the selection border
				if ( !idStr::Icmp(g_qeglobals.d_texturewin.texdef.name, mat->GetName()) ) {
					qglLineWidth(3);
					qglColor3f(1, 0, 0);
					globalImages->BindNull();

					qglBegin(GL_LINE_LOOP);
					qglVertex2f(draw.x - 4, draw.y - FONT_HEIGHT + 4);
					qglVertex2f(draw.x - 4, draw.y - FONT_HEIGHT - height - 4);
					qglVertex2f(draw.x + 4 + width, draw.y - FONT_HEIGHT - height - 4);
					qglVertex2f(draw.x + 4 + width, draw.y - FONT_HEIGHT + 4);
					qglEnd();

					qglLineWidth(1);
				}

				// draw the texture name
				globalImages->BindNull();
				qglColor3f(1, 1, 1);
				qglRasterPos2f(draw.x, draw.y - FONT_HEIGHT + 2);

				// don't draw the directory name
				for (name = mat->GetName(); *name && *name != '/' && *name != '\\'; name++) {
					;
				}

				if (!*name) {
					name = mat->GetName();
				}
				else {
					name++;
				}
				qglCallLists(strlen(name), GL_UNSIGNED_BYTE, name);
				//qglCallLists(va("%s -- %d, %d" strlen(name), GL_UNSIGNED_BYTE, name);
			} 
		}

		g_qeglobals.d_texturewin.m_nTotalHeight = abs(draw.y) + 100;

		// reset the current texture
		globalImages->BindNull();
		qglFinish();
		qwglSwapBuffers(dc.GetSafeHdc());
		TRACE("Texture Paint\n");
	}

	if (g_PrefsDlg.m_bTextureScrollbar && (m_bNeedRange || g_qeglobals.d_texturewin.m_nTotalHeight != nOld)) {
		m_bNeedRange = false;
		SetScrollRange(SB_VERT, 0, g_qeglobals.d_texturewin.m_nTotalHeight, TRUE);
	}

	//ReleaseDC(hdcTexture);
}