PDGL_API void pdglEnd(void) { if(pglEnd) { pglEnd(); return; } pglEnd=pdglGetProcAddress("glEnd"); pglEnd(); }
/* ================ CL_DrawTracer draws a single tracer ================ */ void CL_DrawTracer( vec3_t start, vec3_t delta, float width, rgb_t color, int alpha, float startV, float endV ) { // Clip the tracer vec3_t verts[4]; if ( !CL_TracerComputeVerts( start, delta, width, verts )) return; // NOTE: Gotta get the winding right so it's not backface culled // (we need to turn of backface culling for these bad boys) GL_SetRenderMode( kRenderTransTexture ); pglColor4ub( color[0], color[1], color[2], alpha ); GL_Bind( GL_TEXTURE0, cls.particleImage ); pglBegin( GL_QUADS ); pglTexCoord2f( 0.0f, endV ); pglVertex3fv( verts[2] ); pglTexCoord2f( 1.0f, endV ); pglVertex3fv( verts[3] ); pglTexCoord2f( 1.0f, startV ); pglVertex3fv( verts[1] ); pglTexCoord2f( 0.0f, startV ); pglVertex3fv( verts[0] ); pglEnd(); }
/* ================= R_Bloom_Quad ================= */ inline static void R_Bloom_Quad( int x, int y, int w, int h, float texwidth, float texheight ) { pglBegin( GL_QUADS ); pglTexCoord2f( 0, texheight ); pglVertex2f( x, y ); pglTexCoord2f( 0, 0 ); pglVertex2f( x, y+h ); pglTexCoord2f( texwidth, 0 ); pglVertex2f( x+w, y+h ); pglTexCoord2f( texwidth, texheight ); pglVertex2f( x+w, y ); pglEnd(); }
/* ================= R_Bloom_SamplePass ================= */ inline static void R_Bloom_SamplePass( int xpos, int ypos ) { pglBegin( GL_QUADS ); pglTexCoord2f( 0, sampleText_tch ); pglVertex2f( xpos, ypos ); pglTexCoord2f( 0, 0 ); pglVertex2f( xpos, ypos+sample_height ); pglTexCoord2f( sampleText_tcw, 0 ); pglVertex2f( xpos+sample_width, ypos+sample_height ); pglTexCoord2f( sampleText_tcw, sampleText_tch ); pglVertex2f( xpos+sample_width, ypos ); pglEnd(); }
/* ============= R_DrawStretchPic ============= */ void R_DrawStretchPic( float x, float y, float w, float h, float s1, float t1, float s2, float t2, int texnum ) { GL_Bind( GL_TEXTURE0, texnum ); pglBegin( GL_QUADS ); pglTexCoord2f( s1, t1 ); pglVertex2f( x, y ); pglTexCoord2f( s2, t1 ); pglVertex2f( x + w, y ); pglTexCoord2f( s2, t2 ); pglVertex2f( x + w, y + h ); pglTexCoord2f( s1, t2 ); pglVertex2f( x, y + h ); pglEnd(); }
/* ================ VGUI_DrawQuad generic method to fill rectangle ================ */ void VGUI_DrawQuad( const vpoint_t *ul, const vpoint_t *lr ) { ASSERT( ul != NULL && lr != NULL ); pglBegin( GL_QUADS ); pglTexCoord2f( ul->coord[0], ul->coord[1] ); pglVertex2f( ul->point[0], ul->point[1] ); pglTexCoord2f( lr->coord[0], ul->coord[1] ); pglVertex2f( lr->point[0], ul->point[1] ); pglTexCoord2f( lr->coord[0], lr->coord[1] ); pglVertex2f( lr->point[0], lr->point[1] ); pglTexCoord2f( ul->coord[0], lr->coord[1] ); pglVertex2f( ul->point[0], lr->point[1] ); pglEnd(); }
/* =========== SCR_DrawNetGraph =========== */ void SCR_DrawNetGraph( void ) { wrect_t rect; float avg_ping; int ping_count; int w, x, y; if( !host.developer ) return; if( cls.state != ca_active ) return; if( !net_graph->value ) return; if( net_scale->value <= 0 ) Cvar_SetFloat( "net_scale", 0.1f ); NetGraph_GetScreenPos( &rect, &w, &x, &y ); NetGraph_GetFrameData( &avg_ping, &ping_count ); NetGraph_DrawTextFields( x, y, w, rect, ping_count, avg_ping, packet_loss, packet_choke ); if( net_graph->value < 3 ) { pglEnable( GL_BLEND ); pglDisable( GL_TEXTURE_2D ); pglTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); pglBlendFunc( GL_SRC_ALPHA, GL_ONE ); pglBegin( GL_QUADS ); // draw all the fills as a long solid sequence of quads for speedup reasons // NOTE: fill colors without texture at this point NetGraph_DrawDataUsage( x, y, w ); NetGraph_DrawTimes( rect, x, w ); pglEnd(); pglColor4ub( 255, 255, 255, 255 ); pglEnable( GL_TEXTURE_2D ); pglDisable( GL_BLEND ); } }
// render bounding box static void RenderWireframeBox( FLOAT3D vMinVtx, FLOAT3D vMaxVtx, COLOR col) { // only for OpenGL (for now) if( _pGfx->gl_eCurrentAPI!=GAT_OGL) return; // prepare wireframe OpenGL settings gfxDisableDepthTest(); gfxDisableDepthWrite(); gfxDisableBlend(); gfxDisableAlphaTest(); gfxDisableTexture(); // fill vertex array so it represents bounding box FLOAT3D vBoxVtxs[8]; vBoxVtxs[0] = FLOAT3D( vMinVtx(1), vMinVtx(2), vMinVtx(3)); vBoxVtxs[1] = FLOAT3D( vMaxVtx(1), vMinVtx(2), vMinVtx(3)); vBoxVtxs[2] = FLOAT3D( vMaxVtx(1), vMinVtx(2), vMaxVtx(3)); vBoxVtxs[3] = FLOAT3D( vMinVtx(1), vMinVtx(2), vMaxVtx(3)); vBoxVtxs[4] = FLOAT3D( vMinVtx(1), vMaxVtx(2), vMinVtx(3)); vBoxVtxs[5] = FLOAT3D( vMaxVtx(1), vMaxVtx(2), vMinVtx(3)); vBoxVtxs[6] = FLOAT3D( vMaxVtx(1), vMaxVtx(2), vMaxVtx(3)); vBoxVtxs[7] = FLOAT3D( vMinVtx(1), vMaxVtx(2), vMaxVtx(3)); // connect vertices into lines of bounding box INDEX iBoxLines[12][2]; iBoxLines[ 0][0] = 0; iBoxLines[ 0][1] = 1; iBoxLines[ 1][0] = 1; iBoxLines[ 1][1] = 2; iBoxLines[ 2][0] = 2; iBoxLines[ 2][1] = 3; iBoxLines[ 3][0] = 3; iBoxLines[ 3][1] = 0; iBoxLines[ 4][0] = 0; iBoxLines[ 4][1] = 4; iBoxLines[ 5][0] = 1; iBoxLines[ 5][1] = 5; iBoxLines[ 6][0] = 2; iBoxLines[ 6][1] = 6; iBoxLines[ 7][0] = 3; iBoxLines[ 7][1] = 7; iBoxLines[ 8][0] = 4; iBoxLines[ 8][1] = 5; iBoxLines[ 9][0] = 5; iBoxLines[ 9][1] = 6; iBoxLines[10][0] = 6; iBoxLines[10][1] = 7; iBoxLines[11][0] = 7; iBoxLines[11][1] = 4; // for all vertices in bounding box glCOLOR(col); pglBegin( GL_LINES); for( INDEX i=0; i<12; i++) { // get starting and ending vertices of one line FLOAT3D &v0 = vBoxVtxs[iBoxLines[i][0]]; FLOAT3D &v1 = vBoxVtxs[iBoxLines[i][1]]; pglVertex3f( v0(1), v0(2), v0(3)); pglVertex3f( v1(1), v1(2), v1(3)); } pglEnd(); OGL_CHECKERROR; }
void DrawSingleDecal( decal_t *pDecal, msurface_t *fa ) { float *v; int i, numVerts; v = R_DecalSetupVerts( pDecal, fa, pDecal->texture, &numVerts ); if( !numVerts ) return; GL_Bind( GL_TEXTURE0, pDecal->texture ); pglBegin( GL_POLYGON ); for( i = 0; i < numVerts; i++, v += VERTEXSIZE ) { pglTexCoord2f( v[3], v[4] ); pglVertex3fv( v ); } pglEnd(); }
/* ================= R_Bloom_DrawEffect ================= */ static void R_Bloom_DrawEffect( void ) { GL_Bind( GL_TEXTURE0, r_bloomeffecttexture ); pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); pglColor4f( r_bloom_alpha->value, r_bloom_alpha->value, r_bloom_alpha->value, 1.0f ); pglBlendFunc( GL_ONE, GL_ONE ); pglEnable( GL_BLEND ); pglBegin( GL_QUADS ); pglTexCoord2f( 0, sampleText_tch ); pglVertex2f( curView_x, curView_y ); pglTexCoord2f( 0, 0 ); pglVertex2f( curView_x, curView_y+curView_height ); pglTexCoord2f( sampleText_tcw, 0 ); pglVertex2f( curView_x+curView_width, curView_y+curView_height ); pglTexCoord2f( sampleText_tcw, sampleText_tch ); pglVertex2f( curView_x+curView_width, curView_y ); pglEnd(); pglDisable( GL_BLEND ); }
/* ============= Draw_TileClear This repeats a 64*64 tile graphic to fill the screen around a sized down refresh window. ============= */ void R_DrawTileClear( int x, int y, int w, int h ) { float tw, th; gltexture_t *glt; GL_SetRenderMode( kRenderNormal ); pglColor4f( 1.0f, 1.0f, 1.0f, 1.0f ); GL_Bind( GL_TEXTURE0, cls.tileImage ); glt = R_GetTexture( cls.tileImage ); tw = glt->srcWidth; th = glt->srcHeight; pglBegin( GL_QUADS ); pglTexCoord2f( x / tw, y / th ); pglVertex2f( x, y ); pglTexCoord2f((x + w) / tw, y / th ); pglVertex2f( x + w, y ); pglTexCoord2f((x + w) / tw, (y + h) / th ); pglVertex2f( x + w, y + h ); pglTexCoord2f( x / tw, (y + h) / th ); pglVertex2f( x, y + h ); pglEnd (); }
/* ============= R_DrawStretchRaw ============= */ void R_DrawStretchRaw( float x, float y, float w, float h, int cols, int rows, const byte *data, qboolean dirty ) { byte *raw = NULL; gltexture_t *tex; if( !GL_Support( GL_ARB_TEXTURE_NPOT_EXT )) { int width = 1, height = 1; // check the dimensions width = NearestPOW( cols, true ); height = NearestPOW( rows, false ); if( cols != width || rows != height ) { raw = GL_ResampleTexture( data, cols, rows, width, height, false ); cols = width; rows = height; } } else { raw = (byte *)data; } if( cols > glConfig.max_2d_texture_size ) Host_Error( "R_DrawStretchRaw: size %i exceeds hardware limits\n", cols ); if( rows > glConfig.max_2d_texture_size ) Host_Error( "R_DrawStretchRaw: size %i exceeds hardware limits\n", rows ); pglDisable( GL_BLEND ); pglDisable( GL_ALPHA_TEST ); pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE ); tex = R_GetTexture( tr.cinTexture ); GL_Bind( GL_TEXTURE0, tr.cinTexture ); if( cols == tex->width && rows == tex->height ) { if( dirty ) { pglTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, cols, rows, GL_BGRA, GL_UNSIGNED_BYTE, raw ); } } else { tex->width = cols; tex->height = rows; if( dirty ) { pglTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, cols, rows, 0, GL_BGRA, GL_UNSIGNED_BYTE, raw ); } } pglBegin( GL_QUADS ); pglTexCoord2f( 0, 0 ); pglVertex2f( x, y ); pglTexCoord2f( 1, 0 ); pglVertex2f( x + w, y ); pglTexCoord2f( 1, 1 ); pglVertex2f( x + w, y + h ); pglTexCoord2f( 0, 1 ); pglVertex2f( x, y + h ); pglEnd(); }
void CParticleSystem :: DrawParticle( CParticle *part, Vector &right, Vector &up ) { float fSize = part->m_fSize; // nothing to draw? if( fSize <= 0 ) return; // frustrum visible check if( !ParticleIsVisible( part )) return; Vector point1, point2, point3, point4; Vector origin = part->origin; float fCosSize = CosLookup( part->m_fAngle ) * fSize; float fSinSize = SinLookup( part->m_fAngle ) * fSize; // calculate the four corners of the sprite point1 = origin + up * fSinSize + right * -fCosSize; point2 = origin + up * fCosSize + right * fSinSize; point3 = origin + up * -fSinSize + right * fCosSize; point4 = origin + up * -fCosSize + right * -fSinSize; int iContents = CONTENTS_NONE; model_t *pModel; for( CParticle *pDraw = part; pDraw; pDraw = pDraw->m_pOverlay ) { if( !pDraw->pType->m_hSprite ) continue; if( pDraw->pType->m_iDrawCond ) { if( pDraw->pType->m_iDrawCond == CONTENT_SPOTLIGHT ) { if( !R_CountPlights( )) continue; // fast reject for( int i = 0; i < MAX_PLIGHTS; i++ ) { plight_t *pl = &cl_plights[i]; if( pl->die < GET_CLIENT_TIME() || !pl->radius ) continue; if( !R_CullSphereExt( pl->frustum, part->origin, part->m_fSize + 1, pl->clipflags )) break; // cone intersected with particle } if( i == MAX_PLIGHTS ) continue; // no intersection } else { if( iContents == CONTENTS_NONE ) iContents = POINT_CONTENTS( origin ); if( iContents != pDraw->pType->m_iDrawCond ) continue; } } pModel = (model_t *)gEngfuncs.GetSpritePointer( pDraw->pType->m_hSprite ); // if we've reached the end of the sprite's frames, loop back while (pDraw->frame > pModel->numframes) pDraw->frame -= pModel->numframes; while (pDraw->frame < 0) pDraw->frame += pModel->numframes; if( !TriSpriteTexture( pModel, (int)pDraw->frame )) continue; gEngfuncs.pTriAPI->RenderMode( pDraw->pType->m_iRenderMode ); if( m_iLightingModel >= 1 ) { color24 lightColor; Vector lightingColor; if( m_iLightingModel == 1 ) R_LightForPoint( part->origin, &lightColor, false, true, fSize + 1 ); else R_LightForPoint( part->origin, &lightColor, false, true, 0.0f ); // FIXME: this code is totally wrong. // We need a fake lightmap here like in sprite implementation lightingColor.x = pDraw->m_fRed * lightColor.r * (1.0f / 255.0f); lightingColor.y = pDraw->m_fGreen * lightColor.g * (1.0f / 255.0f); lightingColor.z = pDraw->m_fBlue * lightColor.b * (1.0f / 255.0f); pglColor4f( lightingColor.x, lightingColor.y, lightingColor.z, pDraw->m_fAlpha ); } else pglColor4f( pDraw->m_fRed, pDraw->m_fGreen, pDraw->m_fBlue, pDraw->m_fAlpha ); pglBegin( GL_QUADS ); pglTexCoord2f( 0.0f, 0.0f ); pglVertex3fv( point1 ); pglTexCoord2f( 1.0f, 0.0f ); pglVertex3fv( point2 ); pglTexCoord2f( 1.0f, 1.0f ); pglVertex3fv( point3 ); pglTexCoord2f( 0.0f, 1.0f ); pglVertex3fv( point4 ); pglEnd(); if( m_iLightingModel >=2 && R_CountPlights( )) { for( int i = 0; i < MAX_PLIGHTS; i++ ) { plight_t *pl = &cl_plights[i]; if( pl->die < GET_CLIENT_TIME() || !pl->radius ) continue; if( R_CullSphereExt( pl->frustum, part->origin, part->m_fSize + 1, pl->clipflags )) continue; R_BeginDrawProjection( pl ); pglBegin( GL_QUADS ); pglVertex3fv( point1 ); pglVertex3fv( point2 ); pglVertex3fv( point3 ); pglVertex3fv( point4 ); pglEnd(); R_EndDrawProjection(); } } } }
/* ================ CL_UpdateParticle update particle color, position etc ================ */ void CL_UpdateParticle( particle_t *p, float ft ) { float time3 = 15.0 * ft; float time2 = 10.0 * ft; float time1 = 5.0 * ft; float dvel = 4 * ft; float grav = ft * clgame.movevars.gravity * 0.05f; float size = 1.5f; int i, iRamp, alpha = 255; vec3_t right, up; rgb_t color; r_stats.c_particle_count++; switch( p->type ) { case pt_static: break; case pt_tracer: case pt_clientcustom: if( p->callback ) { p->callback( p, ft ); } if( p->type == pt_tracer ) return; // already drawed break; case pt_fire: p->ramp += time1; if( p->ramp >= 6 ) p->die = -1; else p->color = ramp3[(int)p->ramp]; p->vel[2] += grav; break; case pt_explode: p->ramp += time2; if( p->ramp >= 8 ) p->die = -1; else p->color = ramp1[(int)p->ramp]; for( i = 0; i < 3; i++ ) p->vel[i] += p->vel[i] * dvel; p->vel[2] -= grav; break; case pt_explode2: p->ramp += time3; if( p->ramp >= 8 ) p->die = -1; else p->color = ramp2[(int)p->ramp]; for( i = 0; i < 3; i++ ) p->vel[i] -= p->vel[i] * ft; p->vel[2] -= grav; break; case pt_blob: case pt_blob2: p->ramp += time2; iRamp = (int)p->ramp >> SIMSHIFT; if( iRamp >= SPARK_COLORCOUNT ) { p->ramp = 0.0f; iRamp = 0; } p->color = CL_LookupColor( gSparkRamp[iRamp][0], gSparkRamp[iRamp][1], gSparkRamp[iRamp][2] ); for( i = 0; i < 2; i++ ) p->vel[i] -= p->vel[i] * 0.5f * ft; p->vel[2] -= grav * 5.0f; if( Com_RandomLong( 0, 3 )) { p->type = pt_blob; alpha = 0; } else { p->type = pt_blob2; alpha = 255; } break; case pt_grav: p->vel[2] -= grav * 20; break; case pt_slowgrav: p->vel[2] -= grav; break; case pt_vox_grav: p->vel[2] -= grav * 8; break; case pt_vox_slowgrav: p->vel[2] -= grav * 4; break; } #if 0 // HACKHACK a scale up to keep particles from disappearing size += (p->org[0] - RI.vieworg[0]) * RI.vforward[0]; size += (p->org[1] - RI.vieworg[1]) * RI.vforward[1]; size += (p->org[2] - RI.vieworg[2]) * RI.vforward[2]; if( size < 20.0f ) size = 1.0f; else size = 1.0f + size * 0.004f; #endif // scale the axes by radius VectorScale( RI.vright, size, right ); VectorScale( RI.vup, size, up ); p->color = bound( 0, p->color, 255 ); VectorSet( color, clgame.palette[p->color][0], clgame.palette[p->color][1], clgame.palette[p->color][2] ); GL_SetRenderMode( kRenderTransTexture ); pglColor4ub( color[0], color[1], color[2], alpha ); GL_Bind( GL_TEXTURE0, cls.particleImage ); // add the 4 corner vertices. pglBegin( GL_QUADS ); pglTexCoord2f( 0.0f, 1.0f ); pglVertex3f( p->org[0] - right[0] + up[0], p->org[1] - right[1] + up[1], p->org[2] - right[2] + up[2] ); pglTexCoord2f( 0.0f, 0.0f ); pglVertex3f( p->org[0] + right[0] + up[0], p->org[1] + right[1] + up[1], p->org[2] + right[2] + up[2] ); pglTexCoord2f( 1.0f, 0.0f ); pglVertex3f( p->org[0] + right[0] - up[0], p->org[1] + right[1] - up[1], p->org[2] + right[2] - up[2] ); pglTexCoord2f( 1.0f, 1.0f ); pglVertex3f( p->org[0] - right[0] - up[0], p->org[1] - right[1] - up[1], p->org[2] - right[2] - up[2] ); pglEnd(); if( p->type != pt_clientcustom ) { // update position. VectorMA( p->org, ft, p->vel, p->org ); } }
static void CL_BulletTracerDraw( particle_t *p, float frametime ) { vec3_t lineDir, viewDir, cross; vec3_t vecEnd, vecStart, vecDir; float sDistance, eDistance, totalDist; float dDistance, dTotal, fOffset; int alpha = (int)(traceralpha->value * 255); float width = 3.0f, life, frac, length; vec3_t tmp; // calculate distance VectorCopy( p->vel, vecDir ); totalDist = VectorNormalizeLength( vecDir ); length = p->ramp; // ramp used as length // calculate fraction life = ( totalDist + length ) / ( max( 1.0f, tracerspeed->value )); frac = life - ( p->die - cl.time ) + frametime; // calculate our distance along our path sDistance = tracerspeed->value * frac; eDistance = sDistance - length; // clip to start sDistance = max( 0.0f, sDistance ); eDistance = max( 0.0f, eDistance ); if(( sDistance == 0.0f ) && ( eDistance == 0.0f )) return; // clip it if( totalDist != 0.0f ) { sDistance = min( sDistance, totalDist ); eDistance = min( eDistance, totalDist ); } // get our delta to calculate the tc offset dDistance = fabs( sDistance - eDistance ); dTotal = ( length != 0.0f ) ? length : 0.01f; fOffset = ( dDistance / dTotal ); // find our points along our path VectorMA( p->org, sDistance, vecDir, vecEnd ); VectorMA( p->org, eDistance, vecDir, vecStart ); // setup our info for drawing the line VectorSubtract( vecEnd, vecStart, lineDir ); VectorSubtract( vecEnd, RI.vieworg, viewDir ); CrossProduct( lineDir, viewDir, cross ); VectorNormalize( cross ); GL_SetRenderMode( kRenderTransTexture ); GL_Bind( GL_TEXTURE0, cls.particleImage ); pglBegin( GL_QUADS ); pglColor4ub( clgame.palette[p->color][0], clgame.palette[p->color][1], clgame.palette[p->color][2], alpha ); VectorMA( vecStart, -width, cross, tmp ); pglTexCoord2f( 1.0f, 0.0f ); pglVertex3fv( tmp ); VectorMA( vecStart, width, cross, tmp ); pglTexCoord2f( 0.0f, 0.0f ); pglVertex3fv( tmp ); VectorMA( vecEnd, width, cross, tmp ); pglTexCoord2f( 0.0f, fOffset ); pglVertex3fv( tmp ); VectorMA( vecEnd, -width, cross, tmp ); pglTexCoord2f( 1.0f, fOffset ); pglVertex3fv( tmp ); pglEnd(); }
void blitter_opengl_update() { float VALA=512/(float)visible_area.w-1.0; /* 240.0f*2.0f/304.0f - 1.0f */ int VALB=.0625; /* 16.0f/256.0f */ int VALC=.9375; /* 240.0f/256.0f */ //int VALD .25 /* 64.0f/256.0f */ int VALD=1.0; if (neffect == 0) { #ifndef USE_GL2 pglTexImage2D(GL_TEXTURE_2D, 0, 3, 256, 256, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, buffer->pixels + (visible_area.x<<1)); pglBegin(GL_QUADS); //pglTexCoord2f(16.0f/256.0f, 16.0f/256.0f); //pglVertex2f (-1.0f, 1.0f); pglTexCoord2f(0.0f, 16.0f/256.0f); pglVertex2f (-1.0f, 1.0f); pglTexCoord2f(1.0f, 16.0f/256.0f); pglVertex2f (VALA, 1.0f); pglTexCoord2f(1.0f, 1.0f-16.0f/256.0f); pglVertex2f (VALA, -1.0f); pglTexCoord2f(0.0f, 1.0f-16.0f/256.0f); pglVertex2f (-1.0f, -1.0f); pglEnd(); pglTexImage2D(GL_TEXTURE_2D, 0, 3, 64, 256, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, buffer->pixels + 512+ (visible_area.x<<1)); pglBegin(GL_QUADS); pglTexCoord2f(0.0f, 16.0f/256.0f); pglVertex2f (VALA, 1.0f); pglTexCoord2f(1.0, 16.0f/256.0f); pglVertex2f (1.0f, 1.0f); pglTexCoord2f(1.0, 1.0f-16.0f/256.0f); pglVertex2f (1.0f, -1.0f); pglTexCoord2f(0.0f, 1.0f-16.0f/256.0f); pglVertex2f (VALA, -1.0f); pglEnd(); #else SDL_BlitSurface(buffer, &visible_area, tex_opengl, NULL); pglTexImage2D(GL_TEXTURE_2D, 0, 3, 512, 256, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, tex_opengl->pixels); pglBegin(GL_QUADS); pglTexCoord2f(0.0f, 0.0f); pglVertex2f (-1.0f, 1.0f); pglTexCoord2f((float)visible_area.w/512.0f, 0.0f); pglVertex2f (1.0f, 1.0f); pglTexCoord2f((float)visible_area.w/512.0f, 1.0f-32.0f/256.0f); pglVertex2f (1.0f, -1.0f); pglTexCoord2f(0.0f, 1.0f-32.0f/256.0f); pglVertex2f (-1.0f, -1.0f); pglEnd(); #endif } else { #ifndef USE_GL2 pglTexImage2D(GL_TEXTURE_2D, 0, 3, 256, 256, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, screen->pixels ); pglBegin(GL_QUADS); pglTexCoord2f(0.0f, 0.0f); pglVertex2f (-1.0f, 1.0f); pglTexCoord2f(1.0f, 0.0f); pglVertex2f (a, 1.0f); pglTexCoord2f(1.0f, c); pglVertex2f (a, 0.0f); pglTexCoord2f(0.0f, c); pglVertex2f (-1.0f, 0.0f); pglEnd(); pglTexImage2D(GL_TEXTURE_2D, 0, 3, 256, 256, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, screen->pixels + 512 ); pglBegin(GL_QUADS); pglTexCoord2f(0.0f, 0.0f); pglVertex2f (a, 1.0f); pglTexCoord2f(1.0f, 0.0f); pglVertex2f (b, 1.0f); pglTexCoord2f(1.0f, c); pglVertex2f (b, 0.0f); pglTexCoord2f(0.0f, c); pglVertex2f (a, 0.0f); pglEnd(); pglTexImage2D(GL_TEXTURE_2D, 0, 3, 256, 256, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, screen->pixels + 1024 ); pglBegin(GL_QUADS); pglTexCoord2f(0.0f, 0.0f); pglVertex2f (b, 1.0f); pglTexCoord2f(d, 0.0f); pglVertex2f (1.0f, 1.0f); pglTexCoord2f(d, c); pglVertex2f (1.0f, 0.0f); pglTexCoord2f(0.0f, c); pglVertex2f (b, 0.0f); pglEnd(); pglTexImage2D(GL_TEXTURE_2D, 0, 3, 256, 256, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, screen->pixels + (visible_area.w<<2) * 224 ); pglBegin(GL_QUADS); pglTexCoord2f(0.0f, 0.0f); pglVertex2f (-1.0f, 0.0f); pglTexCoord2f(1.0f, 0.0f); pglVertex2f (a, 0.0f); pglTexCoord2f(1.0f, c); pglVertex2f (a, -1.0f); pglTexCoord2f(0.0f, c); pglVertex2f (-1.0f, -1.0f); pglEnd(); pglTexImage2D(GL_TEXTURE_2D, 0, 3, 256, 256, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, screen->pixels + (visible_area.w<<2) * 224 + 512 ); pglBegin(GL_QUADS); pglTexCoord2f(0.0f, 0.0f); pglVertex2f (a, 0.0f); pglTexCoord2f(1.0f, 0.0f); pglVertex2f (b, 0.0f); pglTexCoord2f(1.0f, c); pglVertex2f (b, -1.0f); pglTexCoord2f(0.0f, c); pglVertex2f (a, -1.0f); pglEnd(); pglTexImage2D(GL_TEXTURE_2D, 0, 3, 256, 256, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, screen->pixels + (visible_area.w<<2) * 224 + 1024 ); pglBegin(GL_QUADS); pglTexCoord2f(0.0f, 0.0f); pglVertex2f (b, 0.0f); pglTexCoord2f(d, 0.0f); pglVertex2f (1.0f, 0.0f); pglTexCoord2f(d, c); pglVertex2f (1.0f, -1.0f); pglTexCoord2f(0.0f, c); pglVertex2f (b, -1.0f); pglEnd(); #else SDL_BlitSurface(screen, &glrectef, tex_opengl, NULL); pglTexImage2D(GL_TEXTURE_2D, 0, 3, 1024, 512, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, tex_opengl->pixels); pglBegin(GL_QUADS); pglTexCoord2f(0.0f, 0.0f); pglVertex2f (-1.0f, 1.0f); pglTexCoord2f((float)visible_area.w*2/1024.0f, 0.0f); pglVertex2f (1.0f, 1.0f); pglTexCoord2f((float)visible_area.w*2/1024.0f, 448.0f/512.0f); pglVertex2f (1.0f, -1.0f); pglTexCoord2f(0.0f, 448.0f/512.0f); pglVertex2f (-1.0f, -1.0f); pglEnd(); #endif } SDL_GL_SwapBuffers(); }
/* =============== R_ShowTextures Draw all the images to the screen, on top of whatever was there. This is used to test for texture thrashing. =============== */ void R_ShowTextures( void ) { gltexture_t *image; float x, y, w, h; int i, j, k, base_w, base_h; int total, start, end; rgba_t color = { 192, 192, 192, 255 }; int charHeight, numTries = 0; static qboolean showHelp = true; string shortname; if( !gl_showtextures->integer ) return; if( showHelp ) { CL_CenterPrint( "use '<-' and '->' keys to view all the textures", 0.25f ); showHelp = false; } pglClear( GL_COLOR_BUFFER_BIT ); pglFinish(); base_w = 8; base_h = 6; rebuild_page: total = base_w * base_h; start = total * (gl_showtextures->integer - 1); end = total * gl_showtextures->integer; if( end > MAX_TEXTURES ) end = MAX_TEXTURES; w = glState.width / (float)base_w; h = glState.height / (float)base_h; Con_DrawStringLen( NULL, NULL, &charHeight ); for( i = j = 0; i < MAX_TEXTURES; i++ ) { image = R_GetTexture( i ); if( j == start ) break; // found start if( pglIsTexture( image->texnum )) j++; } if( i == MAX_TEXTURES && gl_showtextures->integer != 1 ) { // bad case, rewind to one and try again Cvar_SetFloat( "r_showtextures", max( 1, gl_showtextures->integer - 1 )); if( ++numTries < 2 ) goto rebuild_page; // to prevent infinite loop } for( k = 0; i < MAX_TEXTURES; i++ ) { if( j == end ) break; // page is full image = R_GetTexture( i ); if( !pglIsTexture( image->texnum )) continue; x = k % base_w * w; y = k / base_w * h; pglColor4f( 1.0f, 1.0f, 1.0f, 1.0f ); GL_Bind( XASH_TEXTURE0, i ); // NOTE: don't use image->texnum here, because skybox has a 'wrong' indexes if(( image->flags & TF_DEPTHMAP ) && !( image->flags & TF_NOCOMPARE )) pglTexParameteri( image->target, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE ); pglBegin( GL_QUADS ); pglTexCoord2f( 0, 0 ); pglVertex2f( x, y ); if( image->flags & TF_TEXTURE_RECTANGLE ) pglTexCoord2f( image->width, 0 ); else pglTexCoord2f( 1, 0 ); pglVertex2f( x + w, y ); if( image->flags & TF_TEXTURE_RECTANGLE ) pglTexCoord2f( image->width, image->height ); else pglTexCoord2f( 1, 1 ); pglVertex2f( x + w, y + h ); if( image->flags & TF_TEXTURE_RECTANGLE ) pglTexCoord2f( 0, image->height ); else pglTexCoord2f( 0, 1 ); pglVertex2f( x, y + h ); pglEnd(); if(( image->flags & TF_DEPTHMAP ) && !( image->flags & TF_NOCOMPARE )) pglTexParameteri( image->target, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB ); FS_FileBase( image->name, shortname ); if( Q_strlen( shortname ) > 18 ) { // cutoff too long names, it looks ugly shortname[16] = '.'; shortname[17] = '.'; shortname[18] = '\0'; } Con_DrawString( x + 1, y + h - charHeight, shortname, color ); j++, k++; } CL_DrawCenterPrint (); pglFinish(); }
void DrawSurfaceDecals( msurface_t *fa ) { decal_t *p; cl_entity_t *e; if( !fa->pdecals ) return; e = RI.currententity; ASSERT( e != NULL ); if( e->curstate.rendermode == kRenderNormal || e->curstate.rendermode == kRenderTransAlpha ) { pglDepthMask( GL_FALSE ); pglEnable( GL_BLEND ); if( e->curstate.rendermode == kRenderTransAlpha ) pglDisable( GL_ALPHA_TEST ); } if( e->curstate.rendermode == kRenderTransColor ) pglEnable( GL_TEXTURE_2D ); if( e->curstate.rendermode == kRenderTransTexture || e->curstate.rendermode == kRenderTransAdd ) GL_Cull( GL_NONE ); pglEnable( GL_POLYGON_OFFSET_FILL ); pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); if( fa->flags & SURF_TRANSPARENT && glState.stencilEnabled ) { mtexinfo_t *tex = fa->texinfo; for( p = fa->pdecals; p; p = p->pnext ) { if( p->texture ) { float *o, *v; int i, numVerts; o = R_DecalSetupVerts( p, fa, p->texture, &numVerts ); pglEnable( GL_STENCIL_TEST ); pglStencilFunc( GL_ALWAYS, 1, 0xFFFFFFFF ); pglColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE ); pglStencilOp( GL_KEEP, GL_KEEP, GL_REPLACE ); pglBegin( GL_POLYGON ); for( i = 0, v = o; i < numVerts; i++, v += VERTEXSIZE ) { v[5] = ( DotProduct( v, tex->vecs[0] ) + tex->vecs[0][3] ) / tex->texture->width; v[6] = ( DotProduct( v, tex->vecs[1] ) + tex->vecs[1][3] ) / tex->texture->height; pglTexCoord2f( v[5], v[6] ); pglVertex3fv( v ); } pglEnd(); pglStencilOp( GL_KEEP, GL_KEEP, GL_DECR ); pglEnable( GL_ALPHA_TEST ); pglBegin( GL_POLYGON ); for( i = 0, v = o; i < numVerts; i++, v += VERTEXSIZE ) { pglTexCoord2f( v[5], v[6] ); pglVertex3fv( v ); } pglEnd(); pglDisable( GL_ALPHA_TEST ); pglColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE ); pglStencilFunc( GL_EQUAL, 0, 0xFFFFFFFF ); pglStencilOp( GL_KEEP, GL_KEEP, GL_KEEP ); } } } for( p = fa->pdecals; p; p = p->pnext ) { if( p->texture ) { gltexture_t *glt = R_GetTexture( p->texture ); // normal HL decal with alpha-channel if( glt->flags & TF_HAS_ALPHA ) { // draw transparent decals with GL_MODULATE if( glt->fogParams[3] > DECAL_TRANSPARENT_THRESHOLD ) pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); else pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE ); pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); } else { // color decal like detail texture. Base color is 127 127 127 pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE ); pglBlendFunc( GL_DST_COLOR, GL_SRC_COLOR ); } DrawSingleDecal( p, fa ); } } if( fa->flags & SURF_TRANSPARENT && glState.stencilEnabled ) pglDisable( GL_STENCIL_TEST ); if( e->curstate.rendermode == kRenderNormal || e->curstate.rendermode == kRenderTransAlpha ) { pglDepthMask( GL_TRUE ); pglDisable( GL_BLEND ); if( e->curstate.rendermode == kRenderTransAlpha ) pglEnable( GL_ALPHA_TEST ); } pglDisable( GL_POLYGON_OFFSET_FILL ); if( e->curstate.rendermode == kRenderTransTexture || e->curstate.rendermode == kRenderTransAdd ) GL_Cull( GL_FRONT ); if( e->curstate.rendermode == kRenderTransColor ) pglDisable( GL_TEXTURE_2D ); // restore blendfunc here if( e->curstate.rendermode == kRenderTransAdd || e->curstate.rendermode == kRenderGlow ) pglBlendFunc( GL_SRC_ALPHA, GL_ONE ); }
/* ================= R_ShadowPassDrawBrushModel ================= */ void R_ShadowPassDrawBrushModel( cl_entity_t *e, const plight_t *pl ) { Vector mins, maxs; model_t *clmodel; bool rotated; clmodel = e->model; if( e->angles != g_vecZero ) { for( int i = 0; i < 3; i++ ) { mins[i] = e->origin[i] - clmodel->radius; maxs[i] = e->origin[i] + clmodel->radius; } rotated = true; } else { mins = e->origin + clmodel->mins; maxs = e->origin + clmodel->maxs; rotated = false; } if( R_CullBox( mins, maxs, RI.clipFlags )) return; if( RI.params & ( RP_SKYPORTALVIEW|RP_PORTALVIEW|RP_SCREENVIEW )) { if( rotated ) { if( R_VisCullSphere( e->origin, clmodel->radius )) return; } else { if( R_VisCullBox( mins, maxs )) return; } } if( rotated ) R_RotateForEntity( e ); else R_TranslateForEntity( e ); if( rotated ) tr.modelorg = RI.objectMatrix.VectorITransform( RI.vieworg ); else tr.modelorg = RI.vieworg - e->origin; // accumulate lit surfaces msurface_t *psurf = &clmodel->surfaces[clmodel->firstmodelsurface]; for( int i = 0; i < clmodel->nummodelsurfaces; i++, psurf++ ) { float *v; int k; if( psurf->flags & (SURF_DRAWTILED|SURF_PORTAL|SURF_REFLECT)) continue; R_AddToGrassChain( psurf, pl->frustum, pl->clipflags, false ); if( R_CullSurfaceExt( psurf, pl->frustum, 0 )) continue; // draw depth-mask on transparent textures if( psurf->flags & SURF_TRANSPARENT ) { pglEnable( GL_ALPHA_TEST ); pglEnable( GL_TEXTURE_2D ); pglAlphaFunc( GL_GREATER, 0.0f ); GL_Bind( GL_TEXTURE0, psurf->texinfo->texture->gl_texturenum ); } pglBegin( GL_POLYGON ); for( k = 0, v = psurf->polys->verts[0]; k < psurf->polys->numverts; k++, v += VERTEXSIZE ) { if( psurf->flags & SURF_TRANSPARENT ) pglTexCoord2f( v[3], v[4] ); pglVertex3fv( v ); } pglEnd(); if( psurf->flags & SURF_TRANSPARENT ) { pglDisable( GL_ALPHA_TEST ); pglDisable( GL_TEXTURE_2D ); } } R_LoadIdentity(); // restore worldmatrix }