void GAME_EXPORT GL_SetRenderMode( int mode ) { pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); switch( mode ) { case kRenderNormal: default: pglDisable( GL_BLEND ); pglDisable( GL_ALPHA_TEST ); break; case kRenderTransColor: case kRenderTransTexture: pglEnable( GL_BLEND ); pglDisable( GL_ALPHA_TEST ); pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); break; case kRenderTransAlpha: pglDisable( GL_BLEND ); pglEnable( GL_ALPHA_TEST ); break; case kRenderGlow: case kRenderTransAdd: pglEnable( GL_BLEND ); pglDisable( GL_ALPHA_TEST ); #if defined(XASH_BLEND_ES_WORKAROUND) // Problem with blending exists on every GLES configuration, not only on Android pglBlendFunc( GL_ONE, GL_ONE ); #else pglBlendFunc( GL_SRC_ALPHA, GL_ONE ); #endif break; } }
PDGL_API void pdglBlendFunc(int sfac, int dfac) { if(pglBlendFunc) { pglBlendFunc(sfac, dfac); return; } pglBlendFunc=pdglGetProcAddress("glBlendFunc"); pglBlendFunc(sfac, dfac); }
void VGUI_SetupDrawingRect( int *pColor ) { pglEnable( GL_BLEND ); pglDisable( GL_ALPHA_TEST ); pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); pglColor4ub( pColor[0], pColor[1], pColor[2], 255 - pColor[3] ); }
// set blending operations static void ogl_BlendFunc( GfxBlend eSrc, GfxBlend eDst) { // check consistency ASSERT( _pGfx->gl_eCurrentAPI==GAT_OGL); GLenum gleSrc, gleDst; #ifndef NDEBUG GfxBlend gfxSrc, gfxDst; pglGetIntegerv( GL_BLEND_SRC, (GLint*)&gleSrc); pglGetIntegerv( GL_BLEND_DST, (GLint*)&gleDst); OGL_CHECKERROR; gfxSrc = BlendFromOGL(gleSrc); gfxDst = BlendFromOGL(gleDst); ASSERT( gfxSrc==GFX_eBlendSrc && gfxDst==GFX_eBlendDst); #endif // cached? if( eSrc==GFX_eBlendSrc && eDst==GFX_eBlendDst && gap_bOptimizeStateChanges) return; _sfStats.StartTimer(CStatForm::STI_GFXAPI); gleSrc = BlendToOGL(eSrc); gleDst = BlendToOGL(eDst); pglBlendFunc( gleSrc, gleDst); OGL_CHECKERROR; // done GFX_eBlendSrc = eSrc; GFX_eBlendDst = eDst; _sfStats.StopTimer(CStatForm::STI_GFXAPI); }
void VGUI_SetupDrawingImage( int *pColor ) { pglEnable( GL_BLEND ); pglEnable( GL_ALPHA_TEST ); pglAlphaFunc( GL_GREATER, 0.0f ); pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); pglColor4ub( pColor[0], pColor[1], pColor[2], 255 - pColor[3] ); }
/* =========== 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 ); } }
/* ================= R_Bloom_DownsampleView ================= */ static void R_Bloom_DownsampleView( void ) { pglDisable( GL_BLEND ); pglColor4f( 1.0f, 1.0f, 1.0f, 1.0f ); if( r_screendownsamplingtexture_size ) { // stepped downsample int midsample_width = ( r_screendownsamplingtexture_size * sampleText_tcw ); int midsample_height = ( r_screendownsamplingtexture_size * sampleText_tch ); // copy the screen and draw resized GL_Bind( GL_TEXTURE0, r_bloomscreentexture ); pglCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, curView_x, glState.height - ( curView_y + curView_height ), curView_width, curView_height ); R_Bloom_Quad( 0, glState.height - midsample_height, midsample_width, midsample_height, screenTex_tcw, screenTex_tch ); // now copy into downsampling (mid-sized) texture GL_Bind( GL_TEXTURE0, r_bloomdownsamplingtexture ); pglCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, 0, midsample_width, midsample_height ); // now draw again in bloom size pglColor4f( 0.5f, 0.5f, 0.5f, 1.0f ); R_Bloom_Quad( 0, glState.height - sample_height, sample_width, sample_height, sampleText_tcw, sampleText_tch ); // now blend the big screen texture into the bloom generation space (hoping it adds some blur) pglEnable( GL_BLEND ); pglBlendFunc( GL_ONE, GL_ONE ); pglColor4f( 0.5f, 0.5f, 0.5f, 1.0f ); GL_Bind( GL_TEXTURE0, r_bloomscreentexture ); R_Bloom_Quad( 0, glState.height - sample_height, sample_width, sample_height, screenTex_tcw, screenTex_tch ); pglColor4f( 1.0f, 1.0f, 1.0f, 1.0f ); pglDisable( GL_BLEND ); } else { // downsample simple GL_Bind( GL_TEXTURE0, r_bloomscreentexture ); pglCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, curView_x, glState.height - ( curView_y + curView_height ), curView_width, curView_height ); R_Bloom_Quad( 0, glState.height - sample_height, sample_width, sample_height, screenTex_tcw, screenTex_tch ); } }
/* ================= 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 ); }
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_Bloom_GeneratexDiamonds ================= */ static void R_Bloom_GeneratexDiamonds( void ) { int i, j; float intensity; // set up sample size workspace pglScissor( 0, 0, sample_width, sample_height ); pglViewport( 0, 0, sample_width, sample_height ); pglMatrixMode( GL_PROJECTION ); pglLoadIdentity(); pglOrtho( 0, sample_width, sample_height, 0, -10, 100 ); pglMatrixMode( GL_MODELVIEW ); pglLoadIdentity(); // copy small scene into r_bloomeffecttexture GL_Bind( GL_TEXTURE0, r_bloomeffecttexture ); pglCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, 0, sample_width, sample_height ); // start modifying the small scene corner pglColor4f( 1.0f, 1.0f, 1.0f, 1.0f ); pglEnable( GL_BLEND ); // darkening passes if( r_bloom_darken->value ) { pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); pglBlendFunc( GL_DST_COLOR, GL_ZERO ); for( i = 0; i < (int)r_bloom_darken->value; i++ ) R_Bloom_SamplePass( 0, 0 ); pglCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, 0, sample_width, sample_height ); } // bluring passes pglBlendFunc( GL_ONE, GL_ONE_MINUS_SRC_COLOR ); if( r_bloom_diamond_size->value > 7.0f || r_bloom_diamond_size->value <= 3.0f ) { if( r_bloom_diamond_size->value != 8.0f ) CVAR_SET_FLOAT( "r_bloom_diamond_size", 8.0f ); for( i = 0; i < r_bloom_diamond_size->value; i++ ) { for( j = 0; j < r_bloom_diamond_size->value; j++ ) { intensity = r_bloom_intensity->value * 0.3f * Diamond8x[i][j]; if( intensity < 0.01f ) continue; pglColor4f( intensity, intensity, intensity, 1.0f ); R_Bloom_SamplePass( i-4, j-4 ); } } } else if( r_bloom_diamond_size->value > 5.0f ) { if( r_bloom_diamond_size->value != 6.0f ) CVAR_SET_FLOAT( "r_bloom_diamond_size", 6.0f ); for( i = 0; i < r_bloom_diamond_size->value; i++ ) { for( j = 0; j < r_bloom_diamond_size->value; j++ ) { intensity = r_bloom_intensity->value * 0.5f * Diamond6x[i][j]; if( intensity < 0.01f ) continue; pglColor4f( intensity, intensity, intensity, 1.0f ); R_Bloom_SamplePass( i-3, j-3 ); } } } else if( r_bloom_diamond_size->value > 3.0f ) { if( r_bloom_diamond_size->value != 4.0f ) CVAR_SET_FLOAT( "r_bloom_diamond_size", 4.0f ); for( i = 0; i < r_bloom_diamond_size->value; i++ ) { for( j = 0; j < r_bloom_diamond_size->value; j++ ) { intensity = r_bloom_intensity->value * 0.8f * Diamond4x[i][j]; if( intensity < 0.01f ) continue; pglColor4f( intensity, intensity, intensity, 1.0f ); R_Bloom_SamplePass( i-2, j-2 ); } } } pglCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, 0, sample_width, sample_height ); // restore full screen workspace pglScissor( 0, 0, glState.width, glState.height ); pglViewport( 0, 0, glState.width, glState.height ); pglMatrixMode( GL_PROJECTION ); pglLoadIdentity(); pglOrtho( 0, glState.width, glState.height, 0, -10, 100 ); pglMatrixMode( GL_MODELVIEW ); pglLoadIdentity(); }