void SCR_TimeRefresh_f(void) { int i; int start, stop; float time; if (cls.state != ca_active) { return; } start = Sys_Milliseconds(); if (Cmd_Argc() == 2) { /* run without page flipping */ int j; for (j = 0; j < 1000; j++) { R_BeginFrame(0); for (i = 0; i < 128; i++) { cl.refdef.viewangles[1] = i / 128.0f * 360.0f; R_RenderFrame(&cl.refdef); } GLimp_EndFrame(); } } else { for (i = 0; i < 128; i++) { cl.refdef.viewangles[1] = i / 128.0f * 360.0f; R_BeginFrame(0); R_RenderFrame(&cl.refdef); GLimp_EndFrame(); } } stop = Sys_Milliseconds(); time = (stop - start) / 1000.0f; Com_Printf("%f seconds (%f fps)\n", time, 128 / time); }
int R_MME_MultiPassNext( ) { mmeBlurControl_t* control = &passData.control; byte* outAlloc; __m64 *outAlign; int index; if ( !shotData.take || tr.finishStereo ) { shotData.take = qfalse; return 0; } if ( !control->totalFrames ) return 0; index = control->totalIndex; outAlloc = (byte *)ri.Hunk_AllocateTempMemory( mainData.pixelCount * 3 + 16); outAlign = (__m64 *)((((intptr_t)(outAlloc)) + 15) & ~15); GLimp_EndFrame(); R_MME_GetShot( outAlign ); R_MME_BlurAccumAdd( &passData.dof, outAlign ); tr.capturingDofOrStereo = qtrue; ri.Hunk_FreeTempMemory( outAlloc ); if ( ++(control->totalIndex) < control->totalFrames ) { int nextIndex = control->totalIndex; if ( ++(nextIndex) >= control->totalFrames && r_stereoSeparation->value == 0.0f ) tr.latestDofOrStereoFrame = qtrue; return 1; } control->totalIndex = 0; R_MME_BlurAccumShift( &passData.dof ); return 0; }
/* ==================== RB_ExecuteRenderCommands This function will be called synchronously if running without smp extensions, or asynchronously by another thread. ==================== */ void RB_ExecuteRenderCommands( renderCommandList_t *cmds ) { int t1, t2; t1 = ri.Milliseconds (); if ( !r_smp->integer || cmds == &backEndData[0]->commands ) { backEnd.smpFrame = 0; } else { backEnd.smpFrame = 1; } if( !glimp_suspendRender ) { uint i; for( i = 0; i < MAX_RENDER_COMMANDS; i++ ) { if( !cmds->cmds[i].func ) break; cmds->cmds[i].func( cmds->cmds[i].data ); } } else { //try to do a swap to make it wake up when the window comes back GLimp_EndFrame(); RB_SetProjection2D( qfalse ); } t2 = ri.Milliseconds (); backEnd.pc.msec = t2 - t1; }
/* ============= RB_SwapBuffers ============= */ const void *RB_SwapBuffers(const void *data) { const swapBuffersCommand_t *cmd; // finish any 2D drawing if needed if (tess.numIndexes) { RB_EndSurface(); } // texture swapping test if (r_showImages->integer) { RB_ShowImages(); } cmd = ( const swapBuffersCommand_t * ) data; if (!glState.finishCalled) { qglFinish(); } GLimp_LogComment("***************** RB_SwapBuffers *****************\n\n\n"); GLimp_EndFrame(); backEnd.projection2D = qfalse; return ( const void * ) (cmd + 1); }
/* ============= RB_SwapBuffers ============= */ const void *RB_SwapBuffers( const void *data ) { const swapBuffersCommand_t *cmd; // finish any 2D drawing if needed if ( tess.numIndexes ) { RB_EndSurface(); } // texture swapping test if ( r_showImages->integer ) { RB_ShowImages(); } cmd = (const swapBuffersCommand_t *)data; // we measure overdraw by reading back the stencil buffer and // counting up the number of increments that have happened #ifndef USE_OPENGLES if ( r_measureOverdraw->integer ) { int i; long sum = 0; unsigned char *stencilReadback; stencilReadback = ri.Hunk_AllocateTempMemory( glConfig.vidWidth * glConfig.vidHeight ); qglReadPixels( 0, 0, glConfig.vidWidth, glConfig.vidHeight, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, stencilReadback ); for ( i = 0; i < glConfig.vidWidth * glConfig.vidHeight; i++ ) { sum += stencilReadback[i]; } backEnd.pc.c_overDraw += sum; ri.Hunk_FreeTempMemory( stencilReadback ); } #endif if ( !glState.finishCalled ) { qglFinish(); } GLimp_LogComment( "***************** RB_SwapBuffers *****************\n\n\n" ); GLimp_EndFrame(); backEnd.projection2D = qfalse; #ifdef USE_BLOOM backEnd.doneBloom = qfalse; backEnd.doneSurfaces = qfalse; #endif return (const void *)( cmd + 1 ); }
/* * Shuts the SDL render backend down */ void GLimp_Shutdown(void) { /* Clear the backbuffer and make it current. This may help some broken video drivers like the AMD Catalyst to avoid artifacts in unused screen areas. */ if (SDL_WasInit(SDL_INIT_VIDEO)) { glClearColor(0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); GLimp_EndFrame(); } #ifdef X11GAMMA RestoreGamma(); #endif if (window) { /* cleanly ungrab input (needs window) */ GLimp_GrabInput(false); #if SDL_VERSION_ATLEAST(2, 0, 0) if(context) { SDL_GL_DeleteContext(context); context = NULL; } SDL_DestroyWindow(window); #else SDL_FreeSurface(window); #endif } window = NULL; if (SDL_WasInit(SDL_INIT_EVERYTHING) == SDL_INIT_VIDEO) { SDL_Quit(); } else { SDL_QuitSubSystem(SDL_INIT_VIDEO); } gl_state.hwgamma = false; }
void R_Splash() { #ifndef _XBOX image_t *pImage; /* const char* s = Cvar_VariableString("se_language"); if (stricmp(s,"english")) { pImage = R_FindImageFile( "menu/splash_eur", qfalse, qfalse, qfalse, GL_CLAMP); } else { pImage = R_FindImageFile( "menu/splash", qfalse, qfalse, qfalse, GL_CLAMP); } */ pImage = R_FindImageFile( "menu/splash", qfalse, qfalse, qfalse, GL_CLAMP); extern void RB_SetGL2D (void); RB_SetGL2D(); if (pImage ) {//invalid paths? GL_Bind( pImage ); } GL_State(GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO); const int width = 640; const int height = 480; const float x1 = 320 - width / 2; const float x2 = 320 + width / 2; const float y1 = 240 - height / 2; const float y2 = 240 + height / 2; qglBegin (GL_TRIANGLE_STRIP); qglTexCoord2f( 0, 0 ); qglVertex2f(x1, y1); qglTexCoord2f( 1 , 0 ); qglVertex2f(x2, y1); qglTexCoord2f( 0, 1 ); qglVertex2f(x1, y2); qglTexCoord2f( 1, 1 ); qglVertex2f(x2, y2); qglEnd(); GLimp_EndFrame(); #endif }
const void *RB_SwapBuffers( const void *data ) { const swapBuffersCommand_t *cmd; // finish any 2D drawing if needed if ( tess.numIndexes ) { RB_EndSurface(); } // texture swapping test if ( r_showImages->integer ) { RB_ShowImages(); } cmd = (const swapBuffersCommand_t *)data; // we measure overdraw by reading back the stencil buffer and // counting up the number of increments that have happened if ( r_measureOverdraw->integer ) { int i; long sum = 0; unsigned char *stencilReadback; stencilReadback = (unsigned char *) Z_Malloc( glConfig.vidWidth * glConfig.vidHeight, TAG_TEMP_WORKSPACE, qfalse ); qglReadPixels( 0, 0, glConfig.vidWidth, glConfig.vidHeight, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, stencilReadback ); for ( i = 0; i < glConfig.vidWidth * glConfig.vidHeight; i++ ) { sum += stencilReadback[i]; } backEnd.pc.c_overDraw += sum; Z_Free( stencilReadback ); } if ( !glState.finishCalled ) { qglFinish(); } GLimp_LogComment( "***************** RB_SwapBuffers *****************\n\n\n" ); GLimp_EndFrame(); backEnd.projection2D = qfalse; return (const void *)(cmd + 1); }
/* * Shuts the SDL render backend down */ void GLimp_Shutdown(void) { /* Clear the backbuffer and make it current. This may help some broken video drivers like the AMD Catalyst to avoid artifacts in unused screen areas. */ if (SDL_WasInit(SDL_INIT_VIDEO)) { glClearColor(0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); GLimp_EndFrame(); } if (surface) { SDL_FreeSurface(surface); } surface = NULL; if (SDL_WasInit(SDL_INIT_EVERYTHING) == SDL_INIT_VIDEO) { SDL_Quit(); } else { SDL_QuitSubSystem(SDL_INIT_VIDEO); } #ifdef X11GAMMA if (gl_state.hwgamma == true) { XF86VidModeSetGamma(dpy, screen, &x11_oldgamma); /* This forces X11 to update the gamma tables */ XF86VidModeGetGamma(dpy, screen, &x11_oldgamma); } #endif //gl_state.hwgamma = false; }
static void SoundResetDefaultsFunc ( void *unused ) { Cvar_SetToDefault ("s_volume"); Cvar_SetToDefault ("cd_nocd"); Cvar_SetToDefault ("cd_loopcount"); Cvar_SetToDefault ("s_khz"); Cvar_SetToDefault ("s_loadas8bit"); Cvar_SetToDefault ("s_primary"); Menu_DrawTextBox (168, 192, 36, 3); SCR_DrawString (188, 192+MENU_FONT_SIZE, ALIGN_CENTER, S_COLOR_ALT"Restarting the sound system. This", 255); SCR_DrawString (188, 192+MENU_FONT_SIZE*2, ALIGN_CENTER, S_COLOR_ALT"could take up to a minute, so", 255); SCR_DrawString (188, 192+MENU_FONT_SIZE*3, ALIGN_CENTER, S_COLOR_ALT"please be patient.", 255); // the text box won't show up unless we do a buffer swap GLimp_EndFrame(); CL_Snd_Restart_f(); SoundSetMenuItemValues(); }
/* ============= RB_SwapBuffers ============= */ void RB_SwapBuffers( const void *data ) { // finish any 2D drawing if needed if ( tess.numIndexes ) { RB_EndSurface(); } // texture swapping test if ( r_showImages->integer ) { RB_ShowImages(); } // we measure overdraw by reading back the stencil buffer and // counting up the number of increments that have happened if ( r_measureOverdraw->integer ) { int i; long sum = 0; unsigned char *stencilReadback; stencilReadback = ri.Hunk_AllocateTempMemory( glConfig.vidWidth * glConfig.vidHeight ); glReadPixels( 0, 0, glConfig.vidWidth, glConfig.vidHeight, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, stencilReadback ); for ( i = 0; i < glConfig.vidWidth * glConfig.vidHeight; i++ ) { sum += stencilReadback[i]; } backEnd.pc.c_overDraw += sum; ri.Hunk_FreeTempMemory( stencilReadback ); } if ( !glState.finishCalled ) { glFinish(); } GLimp_EndFrame(); RB_SetProjection2D( qfalse ); }
static void UpdateSoundQualityFunc ( void *unused ) { //Knightmare- added DMP's 44/48 KHz sound support //** DMP check the newly added sound quality menu options switch (s_options_sound_quality_list.curvalue) { case 1: Cvar_SetValue( "s_khz", 22 ); Cvar_SetValue( "s_loadas8bit", false ); break; case 2: Cvar_SetValue( "s_khz", 44 ); Cvar_SetValue( "s_loadas8bit", false ); break; case 3: Cvar_SetValue( "s_khz", 48 ); Cvar_SetValue( "s_loadas8bit", false ); break; default: Cvar_SetValue( "s_khz", 11 ); Cvar_SetValue( "s_loadas8bit", true ); break; } //** DMP end sound menu changes Cvar_SetValue ("s_primary", s_options_sound_compatibility_list.curvalue); Menu_DrawTextBox (168, 192, 36, 3); SCR_DrawString (188, 192+MENU_FONT_SIZE, ALIGN_CENTER, S_COLOR_ALT"Restarting the sound system. This", 255); SCR_DrawString (188, 192+MENU_FONT_SIZE*2, ALIGN_CENTER, S_COLOR_ALT"could take up to a minute, so", 255); SCR_DrawString (188, 192+MENU_FONT_SIZE*3, ALIGN_CENTER, S_COLOR_ALT"please be patient.", 255); // the text box won't show up unless we do a buffer swap GLimp_EndFrame(); CL_Snd_Restart_f(); }
/* * RB_SwapBuffers * */ const void * RB_SwapBuffers(const void *data) { const swapBuffersCommand_t *cmd; /* finish any 2D drawing if needed */ if(tess.numIndexes){ RB_EndSurface(); } /* texture swapping test */ if(r_showImages->integer){ RB_ShowImages(); } cmd = (const swapBuffersCommand_t*)data; /* we measure overdraw by reading back the stencil buffer and * counting up the number of increments that have happened */ if(r_measureOverdraw->integer){ int i; long sum = 0; unsigned char *stencilReadback; stencilReadback = ri.hunkalloctemp(glConfig.vidWidth * glConfig.vidHeight); qglReadPixels(0, 0, glConfig.vidWidth, glConfig.vidHeight, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, stencilReadback); for(i = 0; i < glConfig.vidWidth * glConfig.vidHeight; i++) sum += stencilReadback[i]; backEnd.pc.c_overDraw += sum; ri.hunkfreetemp(stencilReadback); } if(glRefConfig.framebufferObject){ /* copy final image to screen */ Vec2 texScale; Vec4 srcBox, dstBox, white; texScale[0] = texScale[1] = 1.0f; white[0] = white[1] = white[2] = pow(2, tr.overbrightBits); /* exp2(tr.overbrightBits); */ white[3] = 1.0f; setv34(dstBox, 0, 0, glConfig.vidWidth, glConfig.vidHeight); if(backEnd.framePostProcessed){ /* frame was postprocessed into screen fbo, copy from there */ setv34(srcBox, 0, 0, tr.screenScratchFbo->width, tr.screenScratchFbo->height); FBO_Blit(tr.screenScratchFbo, srcBox, texScale, NULL, dstBox, &tr.textureColorShader, white, 0); }else{ /* frame still in render fbo, copy from there */ setv34(srcBox, 0, 0, tr.renderFbo->width, tr.renderFbo->height); FBO_Blit(tr.renderFbo, srcBox, texScale, NULL, dstBox, &tr.textureColorShader, white, 0); } } if(!glState.finishCalled){ qglFinish(); } GLimp_LogComment("***************** RB_SwapBuffers *****************\n\n\n"); GLimp_EndFrame(); backEnd.framePostProcessed = qfalse; backEnd.projection2D = qfalse; return (const void*)(cmd + 1); }
/* ============= RB_SwapBuffers ============= */ const void *RB_SwapBuffers( const void *data ) { const swapBuffersCommand_t *cmd; // finish any 2D drawing if needed if ( tess.numIndexes ) { RB_EndSurface(); } // texture swapping test if ( r_showImages->integer ) { RB_ShowImages(); } cmd = (const swapBuffersCommand_t *)data; // we measure overdraw by reading back the stencil buffer and // counting up the number of increments that have happened if ( r_measureOverdraw->integer ) { int i; long sum = 0; unsigned char *stencilReadback; stencilReadback = ri.Hunk_AllocateTempMemory( glConfig.vidWidth * glConfig.vidHeight ); qglReadPixels( 0, 0, glConfig.vidWidth, glConfig.vidHeight, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, stencilReadback ); for ( i = 0; i < glConfig.vidWidth * glConfig.vidHeight; i++ ) { sum += stencilReadback[i]; } backEnd.pc.c_overDraw += sum; ri.Hunk_FreeTempMemory( stencilReadback ); } if (glRefConfig.framebufferObject) { if (!backEnd.framePostProcessed) { if (tr.msaaResolveFbo && r_hdr->integer) { // Resolving an RGB16F MSAA FBO to the screen messes with the brightness, so resolve to an RGB16F FBO first FBO_FastBlit(tr.renderFbo, NULL, tr.msaaResolveFbo, NULL, GL_COLOR_BUFFER_BIT, GL_NEAREST); FBO_FastBlit(tr.msaaResolveFbo, NULL, NULL, NULL, GL_COLOR_BUFFER_BIT, GL_NEAREST); } else if (tr.renderFbo) { FBO_FastBlit(tr.renderFbo, NULL, NULL, NULL, GL_COLOR_BUFFER_BIT, GL_NEAREST); } } } if ( !glState.finishCalled ) { qglFinish(); } GLimp_LogComment( "***************** RB_SwapBuffers *****************\n\n\n" ); GLimp_EndFrame(); backEnd.framePostProcessed = qfalse; backEnd.projection2D = qfalse; return (const void *)(cmd + 1); }
/* ============= RB_SwapBuffers ============= */ static int RB_SwapBuffers( const void *data ) { // finish any 2D drawing if needed if ( tess.numIndexes ) { RB_EndSurface(); } // texture swapping test if ( r_showImages->integer ) { RB_ShowImages(); } backEnd.projection2D = qfalse; tr.capturingDofOrStereo = qfalse; tr.latestDofOrStereoFrame = qfalse; /* Take and merge DOF frames */ if ( r_stereoSeparation->value <= 0.0f && !tr.finishStereo) { if ( R_MME_MultiPassNext() ) { return 1; } } else if ( r_stereoSeparation->value > 0.0f) { if ( R_MME_MultiPassNextStereo() ) { return 1; } } // we measure overdraw by reading back the stencil buffer and // counting up the number of increments that have happened if ( r_measureOverdraw->integer ) { int i; long sum = 0; unsigned char *stencilReadback; stencilReadback = ri.Hunk_AllocateTempMemory( glConfig.vidWidth * glConfig.vidHeight ); qglReadPixels( 0, 0, glConfig.vidWidth, glConfig.vidHeight, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, stencilReadback ); for ( i = 0; i < glConfig.vidWidth * glConfig.vidHeight; i++ ) { sum += stencilReadback[i]; } backEnd.pc.c_overDraw += sum; ri.Hunk_FreeTempMemory( stencilReadback ); } if ( !glState.finishCalled ) { qglFinish(); } /* Allow MME to take a screenshot */ if ( r_stereoSeparation->value < 0.0f && tr.finishStereo) { tr.capturingDofOrStereo = qtrue; tr.latestDofOrStereoFrame = qtrue; Cvar_SetValue("r_stereoSeparation", -r_stereoSeparation->value); return 1; } else if ( r_stereoSeparation->value <= 0.0f) { if ( R_MME_TakeShot( ) && r_stereoSeparation->value != 0.0f) { tr.capturingDofOrStereo = qtrue; tr.latestDofOrStereoFrame = qfalse; Cvar_SetValue("r_stereoSeparation", -r_stereoSeparation->value); tr.finishStereo = qtrue; return 1; } } else if ( r_stereoSeparation->value > 0.0f) { if ( tr.finishStereo) { R_MME_TakeShotStereo( ); R_MME_DoNotTake( ); Cvar_SetValue("r_stereoSeparation", -r_stereoSeparation->value); tr.finishStereo = qfalse; } } R_FrameBuffer_EndFrame(); GLimp_LogComment( "***************** RB_SwapBuffers *****************\n\n\n" ); GLimp_EndFrame(); return 0; }
/* ============= RB_SwapBuffers ============= */ const void *RB_SwapBuffers( const void *data ) { const swapBuffersCommand_t *cmd; // finish any 2D drawing if needed if ( tess.numIndexes ) { RB_EndSurface(); } // texture swapping test if ( r_showImages->integer ) { RB_ShowImages(); } cmd = (const swapBuffersCommand_t *)data; // we measure overdraw by reading back the stencil buffer and // counting up the number of increments that have happened // there is an extension to read from stencil buffer on GLES, but it's not available on every device, and I'm too lazy #ifndef GL_VERSION_ES_CM_1_0 if ( r_measureOverdraw->integer ) { int i; long sum = 0; unsigned char *stencilReadback; stencilReadback = ri.Hunk_AllocateTempMemory( glConfig.vidWidth * glConfig.vidHeight ); qglReadPixels( 0, 0, glConfig.vidWidth, glConfig.vidHeight, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, stencilReadback ); for ( i = 0; i < glConfig.vidWidth * glConfig.vidHeight; i++ ) { sum += stencilReadback[i]; } backEnd.pc.c_overDraw += sum; ri.Hunk_FreeTempMemory( stencilReadback ); } #endif if ( !glState.finishCalled ) { qglFinish(); } GLimp_LogComment( "***************** RB_SwapBuffers *****************\n\n\n" ); GLimp_EndFrame(); /* if (r_cardboardStereo->integer && Key_GetCatcher( ) & (KEYCATCH_UI | KEYCATCH_CONSOLE)) { qglColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); qglClearColor(0.0f, 0.0f, 0.0f, 1.0f); qglClear(GL_COLOR_BUFFER_BIT); } */ #ifdef __ANDROID__ // On-screen keyboard messes up GL state a bit glState.currenttextures[0] = 0; glState.currenttmu = 0; glState.texEnv[glState.currenttmu] = GL_MODULATE; glState.glStateBits &= ~(GLS_SRCBLEND_BITS | GLS_DSTBLEND_BITS); glState.glStateBits |= (GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA); #endif backEnd.projection2D = qfalse; backEnd.doneBloom = qfalse; backEnd.donepostproc = qfalse; backEnd.doneSurfaces = qfalse; return (const void *)(cmd + 1); }
void Glimp_ClearScreen(void) { qglClearColor(0, 0, 0, 1); qglClear(GL_COLOR_BUFFER_BIT); GLimp_EndFrame(); }
void R_RemapDeluxeImages( world_t *world ) { int i; if( !tr.deluxemaps[0] ) return; R_InitConverter(); R_StateSetActiveTmuUntracked( GL_TEXTURE0 ); R_StateSetActiveClientTmuUntracked( GL_TEXTURE0 ); glPushAttrib( GL_ALL_ATTRIB_BITS ); glPushClientAttrib( GL_CLIENT_ALL_ATTRIB_BITS ); glEnableClientState( GL_VERTEX_ARRAY ); glEnableClientState( GL_NORMAL_ARRAY ); glEnableVertexAttribArrayARB( 6 ); glEnableVertexAttribArrayARB( 7 ); glClearColor( 0, 0, 0, 0 ); glDisable( GL_DEPTH_TEST ); glDisable( GL_STENCIL_TEST ); glDisable( GL_ALPHA_TEST ); glDisable( GL_BLEND ); glDisable( GL_CULL_FACE ); glDisable( GL_MULTISAMPLE ); glEnable( GL_POLYGON_SMOOTH ); glMatrixMode( GL_PROJECTION ); glLoadIdentity(); glMatrixMode( GL_MODELVIEW ); glLoadIdentity(); glEnable( GL_VERTEX_PROGRAM_ARB ); glBindProgramARB( GL_VERTEX_PROGRAM_ARB, conv.vp ); glEnable( GL_FRAGMENT_PROGRAM_ARB ); glBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, conv.fp ); glEnable( GL_TEXTURE_2D ); for( i = 0; i < tr.numLightmaps; i++ ) { int j, y; unsigned *buf0, *buf1; image_t *img = tr.deluxemaps[i]; glBindTexture( GL_TEXTURE_2D, img->texnum ); glClear( GL_COLOR_BUFFER_BIT ); glViewport( 0, img->uploadHeight, img->uploadWidth, img->uploadHeight ); glDisable( GL_VERTEX_PROGRAM_ARB ); glDisable( GL_FRAGMENT_PROGRAM_ARB ); glBegin( GL_QUADS ); { glTexCoord2f( 0, 0 ); glVertex2f( -1, -1 ); glTexCoord2f( 0, 1 ); glVertex2f( -1, 1 ); glTexCoord2f( 1, 1 ); glVertex2f( 1, 1 ); glTexCoord2f( 1, 0 ); glVertex2f( 1, -1 ); } glEnd(); glEnable( GL_VERTEX_PROGRAM_ARB ); glEnable( GL_FRAGMENT_PROGRAM_ARB ); glViewport( 0, 0, img->uploadWidth, img->uploadHeight ); glProgramLocalParameter4fARB( GL_VERTEX_PROGRAM_ARB, 0, img->uploadWidth, img->uploadHeight, 1.0F / img->uploadWidth, 1.0F / img->uploadHeight ); for( j = 0; j < world->numsurfaces; j++ ) { const msurface_t *srf = world->surfaces + j; const shader_t *shader = srf->shader; const msurface_ex_t *exsrf = srf->redirect; if( !shader->stages[0] || !shader->stages[0]->active ) continue; if( shader->stages[0]->deluxeMap != img ) continue; if( !exsrf ) continue; glVertexPointer( 2, GL_FLOAT, sizeof( drawVert_ex_t ), &exsrf->verts[0].uvL ); glNormalPointer( GL_FLOAT, sizeof( drawVert_ex_t ), &exsrf->verts[0].norm ); glVertexAttribPointerARB( 6, 3, GL_FLOAT, GL_FALSE, sizeof( drawVert_ex_t ), &exsrf->verts[0].tan ); glVertexAttribPointerARB( 7, 3, GL_FLOAT, GL_FALSE, sizeof( drawVert_ex_t ), &exsrf->verts[0].bin ); glDrawElements( exsrf->primType, exsrf->numIndices, GL_UNSIGNED_SHORT, exsrf->indices ); } glFinish(); buf0 = (unsigned*)ri.Hunk_AllocateTempMemory( img->uploadWidth * img->uploadHeight * 4 ); buf1 = (unsigned*)ri.Hunk_AllocateTempMemory( img->uploadWidth * img->uploadHeight * 4 ); //can't just copy to the texture since we //need the custom mipmap generator glReadPixels( 0, 0, img->uploadWidth, img->uploadHeight, GL_RGBA, GL_UNSIGNED_BYTE, buf0 ); #define DELUXEL( buf, x, y ) ((byte*)(buf) + (((y) * img->uploadWidth + (x)) * 4)) Com_Memcpy( buf1, buf0, img->uploadWidth * img->uploadHeight * 4 ); for( j = 0; j < 4; j++ ) { for( y = 0; y < img->uploadHeight; y++ ) { int x; for( x = 0; x < img->uploadWidth; x++ ) { static int neighbors[8][2] = { { 0, 1 }, { 1, 1 }, { 1, 0 }, { 1, -1 }, { 0, -1 }, { -1, -1 }, { -1, 0 }, { -1, 1 } }; int i; int sum[3], c; byte *cIn = DELUXEL( buf0, x, y ); byte *cOut = DELUXEL( buf1, x, y ); cOut[3] = cIn[3]; if( cIn[2] ) { //if it has some Z value //then it's already good cOut[0] = cIn[0]; cOut[1] = cIn[1]; cOut[2] = cIn[2]; continue; } c = 0; sum[0] = sum[1] = sum[2] = 0; for( i = 0; i < lengthof( neighbors ); i++ ) { int nx = x + neighbors[i][0]; int ny = y + neighbors[i][1]; if( nx >= 0 && nx < img->uploadWidth && ny >= 0 && ny < img->uploadHeight ) { byte *n = DELUXEL( buf0, nx, ny ); if( !n[2] ) continue; sum[0] += n[0]; sum[1] += n[1]; sum[2] += n[2]; c++; } } if( c ) { cOut[0] = sum[0] / c; cOut[1] = sum[1] / c; cOut[2] = sum[2] / c; } } } Com_Memcpy( buf0, buf1, img->uploadWidth * img->uploadHeight * 4 ); } for( y = 0; y < img->uploadHeight; y++ ) { int x; for( x = 0; x < img->uploadWidth; x++ ) { byte *d = DELUXEL( buf1, x, y ); if( !d[2] ) { d[0] = 0; d[1] = 0; d[2] = 0xFF; } } } //write it out to file { int size; char path[MAX_QPATH]; byte *out_buf; Com_sprintf( path, sizeof( path ), "deluxe/%s/dm_%04d.tga", world->baseName, i ); size = 18 + img->uploadWidth * img->uploadHeight * 3; out_buf = (byte*)ri.Hunk_AllocateTempMemory( size ); Com_Memset( out_buf, 0, 18 ); out_buf[2] = 2; // uncompressed type out_buf[12] = img->uploadWidth & 255; out_buf[13] = img->uploadWidth >> 8; out_buf[14] = img->uploadHeight & 255; out_buf[15] = img->uploadHeight >> 8; out_buf[16] = 24; // pixel size out_buf[17] = 0x20; // reverse row order for( y = 0; y < img->uploadHeight; y++ ) { int x; for( x = 0; x < img->uploadWidth; x++ ) { byte *d = DELUXEL( buf1, x, y ); out_buf[18 + (y * img->uploadWidth + x) * 3 + 0] = d[2]; out_buf[18 + (y * img->uploadWidth + x) * 3 + 1] = d[1]; out_buf[18 + (y * img->uploadWidth + x) * 3 + 2] = d[0]; } } ri.FS_WriteFile( path, out_buf, size ); ri.Hunk_FreeTempMemory( out_buf ); } #undef DELUXEL Upload32( buf1, qfalse, img, ILF_VECTOR_SB3 ); #ifdef _DEBUG glEnable( GL_TEXTURE_2D ); glBindTexture( GL_TEXTURE_2D, img->texnum ); glViewport( img->uploadWidth, 0, img->uploadWidth, img->uploadHeight ); glDisable( GL_VERTEX_PROGRAM_ARB ); glDisable( GL_FRAGMENT_PROGRAM_ARB ); glBegin( GL_QUADS ); { glTexCoord2f( 0, 0 ); glVertex2f( -1, -1 ); glTexCoord2f( 0, 1 ); glVertex2f( -1, 1 ); glTexCoord2f( 1, 1 ); glVertex2f( 1, 1 ); glTexCoord2f( 1, 0 ); glVertex2f( 1, -1 ); } glEnd(); glEnable( GL_VERTEX_PROGRAM_ARB ); glEnable( GL_FRAGMENT_PROGRAM_ARB ); GLimp_EndFrame(); #endif ri.Hunk_FreeTempMemory( buf1 ); ri.Hunk_FreeTempMemory( buf0 ); } glPopClientAttrib(); glPopAttrib(); glDeleteProgramsARB( 1, &conv.vp ); glDeleteProgramsARB( 1, &conv.fp ); }