PDGL_API void pdglViewport(int x, int y, int width, int height) { if(pglViewport) { pglViewport(x, y, width, height); return; } pglViewport=pdglGetProcAddress("glViewport"); pglViewport(x, y, width, height); }
/* ============= R_ShadowPassSetupGL ============= */ static void R_ShadowPassSetupGL( const plight_t *pl ) { // matrices already computed RI.worldviewMatrix = pl->modelviewMatrix; RI.projectionMatrix = pl->projectionMatrix; RI.worldviewProjectionMatrix = RI.projectionMatrix.Concat( RI.worldviewMatrix ); GLfloat dest[16]; // tell engine about worldviewprojection matrix so TriWorldToScreen and TriScreenToWorld // will be working properly RI.worldviewProjectionMatrix.CopyToArray( dest ); SET_ENGINE_WORLDVIEW_MATRIX( dest ); pglScissor( RI.scissor[0], RI.scissor[1], RI.scissor[2], RI.scissor[3] ); pglViewport( RI.viewport[0], RI.viewport[1], RI.viewport[2], RI.viewport[3] ); pglMatrixMode( GL_PROJECTION ); GL_LoadMatrix( RI.projectionMatrix ); pglMatrixMode( GL_MODELVIEW ); GL_LoadMatrix( RI.worldviewMatrix ); GL_Cull( GL_FRONT ); pglColor4f( 1.0f, 1.0f, 1.0f, 1.0f ); pglColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE ); pglEnable( GL_POLYGON_OFFSET_FILL ); pglDisable( GL_TEXTURE_2D ); pglDepthMask( GL_TRUE ); pglPolygonOffset( 8, 30 ); pglEnable( GL_DEPTH_TEST ); pglDisable( GL_ALPHA_TEST ); pglDisable( GL_BLEND ); }
/* =============== R_Set2DMode =============== */ void R_Set2DMode( qboolean enable ) { if( enable ) { if( glState.in2DMode ) return; // set 2D virtual screen size 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, -99999, 99999 ); pglMatrixMode( GL_MODELVIEW ); pglLoadIdentity(); GL_Cull( 0 ); pglDepthMask( GL_FALSE ); pglDisable( GL_DEPTH_TEST ); pglColor4f( 1.0f, 1.0f, 1.0f, 1.0f ); glState.in2DMode = true; RI.currententity = NULL; RI.currentmodel = NULL; } else { pglDepthMask( GL_TRUE ); pglEnable( GL_DEPTH_TEST ); pglMatrixMode( GL_MODELVIEW ); glState.in2DMode = false; } }
/* ============= R_SetupGL ============= */ static void R_SetupGL( void ) { if( RI.refdef.waterlevel >= 3 ) { float f; f = sin( cl.time * 0.4f * ( M_PI * 2.7f )); RI.refdef.fov_x += f; RI.refdef.fov_y -= f; } R_SetupModelviewMatrix( &RI.refdef, RI.worldviewMatrix ); R_SetupProjectionMatrix( &RI.refdef, RI.projectionMatrix ); // if( RI.params & RP_MIRRORVIEW ) RI.projectionMatrix[0][0] = -RI.projectionMatrix[0][0]; Matrix4x4_Concat( RI.worldviewProjectionMatrix, RI.projectionMatrix, RI.worldviewMatrix ); pglScissor( RI.scissor[0], RI.scissor[1], RI.scissor[2], RI.scissor[3] ); pglViewport( RI.viewport[0], RI.viewport[1], RI.viewport[2], RI.viewport[3] ); pglMatrixMode( GL_PROJECTION ); GL_LoadMatrix( RI.projectionMatrix ); pglMatrixMode( GL_MODELVIEW ); GL_LoadMatrix( RI.worldviewMatrix ); if( RI.params & RP_CLIPPLANE ) { GLdouble clip[4]; mplane_t *p = &RI.clipPlane; clip[0] = p->normal[0]; clip[1] = p->normal[1]; clip[2] = p->normal[2]; clip[3] = -p->dist; pglClipPlane( GL_CLIP_PLANE0, clip ); pglEnable( GL_CLIP_PLANE0 ); } if( RI.params & RP_FLIPFRONTFACE ) GL_FrontFace( !glState.frontFace ); GL_Cull( GL_FRONT ); pglDisable( GL_BLEND ); pglDisable( GL_ALPHA_TEST ); pglColor4f( 1.0f, 1.0f, 1.0f, 1.0f ); }
SDL_bool blitter_opengl_resize(int w,int h) { Uint32 sdl_flags; sdl_flags = SDL_DOUBLEBUF | SDL_HWSURFACE | SDL_HWPALETTE | SDL_OPENGL | SDL_RESIZABLE; video_opengl = SDL_SetVideoMode(w, h, 16, sdl_flags); if ( video_opengl == NULL) return SDL_FALSE; pglEnable(GL_TEXTURE_2D); pglViewport(0, 0, w, h); return SDL_TRUE; }
/* ============= R_SetupGL ============= */ static void R_SetupGL( void ) { if( r_underwater_distortion->value && RI.refdef.waterlevel >= 3 ) { float f; f = sin( cl.time * r_underwater_distortion->value * ( M_PI * 2.7f )); RI.refdef.fov_x += f; RI.refdef.fov_y -= f; } R_SetupModelviewMatrix( &RI.refdef, RI.worldviewMatrix ); R_SetupProjectionMatrix( &RI.refdef, RI.projectionMatrix ); // if( RI.params & RP_MIRRORVIEW ) RI.projectionMatrix[0][0] = -RI.projectionMatrix[0][0]; Matrix4x4_Concat( RI.worldviewProjectionMatrix, RI.projectionMatrix, RI.worldviewMatrix ); if( RP_NORMALPASS( )) { int x, x2, y, y2; // set up viewport (main, playersetup) x = floor( RI.viewport[0] * glState.width / glState.width ); x2 = ceil(( RI.viewport[0] + RI.viewport[2] ) * glState.width / glState.width ); y = floor( glState.height - RI.viewport[1] * glState.height / glState.height ); y2 = ceil( glState.height - ( RI.viewport[1] + RI.viewport[3] ) * glState.height / glState.height ); pglViewport( x, y2, x2 - x, y - y2 ); } else { // envpass, mirrorpass pglViewport( RI.viewport[0], RI.viewport[1], RI.viewport[2], RI.viewport[3] ); } pglMatrixMode( GL_PROJECTION ); GL_LoadMatrix( RI.projectionMatrix ); pglMatrixMode( GL_MODELVIEW ); GL_LoadMatrix( RI.worldviewMatrix ); if( RI.params & RP_CLIPPLANE ) { GLdouble clip[4]; mplane_t *p = &RI.clipPlane; clip[0] = p->normal[0]; clip[1] = p->normal[1]; clip[2] = p->normal[2]; clip[3] = -p->dist; pglClipPlane( GL_CLIP_PLANE0, clip ); pglEnable( GL_CLIP_PLANE0 ); } if( RI.params & RP_FLIPFRONTFACE ) GL_FrontFace( !glState.frontFace ); GL_Cull( GL_FRONT ); pglDisable( GL_BLEND ); pglDisable( GL_ALPHA_TEST ); pglColor4f( 1.0f, 1.0f, 1.0f, 1.0f ); }
/* ================= R_BloomBlend ================= */ void R_BloomBlend( const ref_params_t *fd ) { if( !r_bloom->value ) return; if( !BLOOM_SIZE ) R_Bloom_InitTextures(); if( screen_texture_width < BLOOM_SIZE || screen_texture_height < BLOOM_SIZE ) return; // set up 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(); pglDisable( GL_DEPTH_TEST ); pglDisable( GL_ALPHA_TEST ); pglDepthMask( GL_FALSE ); pglDisable( GL_BLEND ); GL_Cull( 0 ); pglColor4f( 1.0f, 1.0f, 1.0f, 1.0f ); pglTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); // set up current sizes curView_x = fd->viewport[0]; curView_y = fd->viewport[1]; curView_width = fd->viewport[2]; curView_height = fd->viewport[3]; screenTex_tcw = ( (float)curView_width / (float)screen_texture_width ); screenTex_tch = ( (float)curView_height / (float)screen_texture_height ); if( curView_height > curView_width ) { sampleText_tcw = ( (float)curView_width / (float)curView_height ); sampleText_tch = 1.0f; } else { sampleText_tcw = 1.0f; sampleText_tch = ( (float)curView_height / (float)curView_width ); } sample_width = ( BLOOM_SIZE * sampleText_tcw ); sample_height = ( BLOOM_SIZE * sampleText_tch ); // copy the screen space we'll use to work into the backup texture GL_Bind( GL_TEXTURE0, r_bloombackuptexture ); pglCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, 0, r_screenbackuptexture_width * sampleText_tcw, r_screenbackuptexture_height * sampleText_tch ); // create the bloom image R_Bloom_DownsampleView(); R_Bloom_GeneratexDiamonds(); pglDisable( GL_BLEND ); // restore the screen-backup to the screen GL_Bind( GL_TEXTURE0, r_bloombackuptexture ); pglColor4f( 1, 1, 1, 1 ); R_Bloom_Quad( 0, glState.height - (r_screenbackuptexture_height * sampleText_tch), r_screenbackuptexture_width * sampleText_tcw, r_screenbackuptexture_height * sampleText_tch, sampleText_tcw, sampleText_tch ); pglScissor( RI.scissor[0], RI.scissor[1], RI.scissor[2], RI.scissor[3] ); R_Bloom_DrawEffect(); pglViewport( RI.viewport[0], RI.viewport[1], RI.viewport[2], RI.viewport[3] ); pglMatrixMode( GL_PROJECTION ); GL_LoadMatrix( RI.projectionMatrix ); pglMatrixMode( GL_MODELVIEW ); GL_LoadMatrix( RI.worldviewMatrix ); pglEnable( GL_DEPTH_TEST ); pglDepthMask( GL_TRUE ); pglDisable( GL_BLEND ); GL_Cull( GL_FRONT ); }
/* ================= 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(); }
SDL_bool blitter_opengl_init() { Uint32 sdl_flags; Uint32 width = visible_area.w; Uint32 height = visible_area.h; if (load_glproc() == SDL_FALSE) return SDL_FALSE; sdl_flags = (fullscreen?SDL_FULLSCREEN:0)| SDL_DOUBLEBUF | SDL_HWSURFACE | SDL_HWPALETTE | SDL_OPENGL | SDL_RESIZABLE; SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); if ((effect[neffect].x_ratio!=2 || effect[neffect].y_ratio!=2) && (effect[neffect].x_ratio!=1 || effect[neffect].y_ratio!=1) ) { printf("Opengl support only effect with a ratio of 2x2 or 1x1\n"); return SDL_FALSE; } /* if (conf.res_x==304 && conf.res_y==224) { */ if (scale < 2) { width *=effect[neffect].x_ratio; height*=effect[neffect].y_ratio; } width *= scale; height *= scale; /* } else { width = conf.res_x; height=conf.res_y; } */ conf.res_x=width; conf.res_y=height; video_opengl = SDL_SetVideoMode(width, height, 16, sdl_flags); if ( video_opengl == NULL) return SDL_FALSE; pglClearColor(0, 0, 0, 0); pglClear(GL_COLOR_BUFFER_BIT); pglEnable(GL_TEXTURE_2D); pglViewport(0, 0, width, height); /* Linear Filter */ pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); /* pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); */ /* Texture Mode */ pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); if (neffect == 0) { /* Texture limits */ /* a = (240.0/304.0); b = (48.0/256.0); c = (240.0/256.0); */ #ifdef USE_GL2 tex_opengl= SDL_CreateRGBSurface(SDL_SWSURFACE, 512, 256, 16, 0xF800, 0x7E0, 0x1F, 0); #else pglPixelStorei(GL_UNPACK_ROW_LENGTH, 352); #endif } else { /* Texture limits */ a = ((256.0/(float)visible_area.w) - 1.0f)*effect[neffect].x_ratio/2.0; b = ((512.0/(float)visible_area.w) - 1.0f)*effect[neffect].x_ratio/2.0; c = (((float)visible_area.h/256.0))*effect[neffect].y_ratio/2.0; d = (((float)((visible_area.w<<1)-512)/256.0))*effect[neffect].y_ratio/2.0; screen = SDL_CreateRGBSurface(SDL_SWSURFACE, visible_area.w<<1, /*visible_area.h<<1*/512, 16, 0xF800, 0x7E0, 0x1F, 0); //printf("[opengl] create_screen %p\n",screen); #ifdef USE_GL2 tex_opengl= SDL_CreateRGBSurface(SDL_SWSURFACE, 1024, 512, 16, 0xF800, 0x7E0, 0x1F, 0); if (visible_area.w==320) { glrectef.x=0; glrectef.y=0; glrectef.w=320*2; glrectef.h=224*2; } else { glrectef.x=0; glrectef.y=0; glrectef.w=304*2; glrectef.h=224*2; } #else pglPixelStorei(GL_UNPACK_ROW_LENGTH, visible_area.w<<1); #endif } return SDL_TRUE; }