Fix palette rendering brightness issues on wipes, add timedemo support to gif recording

This commit is contained in:
Hannu Hanhi 2021-09-14 00:17:34 +03:00
parent 913bbb3fc0
commit f7a8bedec1
10 changed files with 171 additions and 232 deletions

View file

@ -329,5 +329,18 @@ enum hwdfiltermode
HWD_SET_TEXTUREFILTER_MIXED3, HWD_SET_TEXTUREFILTER_MIXED3,
}; };
// Screen texture slots
enum hwdscreentexture
{
HWD_SCREENTEXTURE_WIPE_START, // source image for the wipe/fade effect
HWD_SCREENTEXTURE_WIPE_END, // destination image for the wipe/fade effect
HWD_SCREENTEXTURE_GENERIC1, // underwater/heat effect, intermission background
HWD_SCREENTEXTURE_GENERIC2, // screen before palette rendering's postprocessing
HWD_SCREENTEXTURE_GENERIC3, // screen after palette rendering's postprocessing
NUMSCREENTEXTURES, // (generic3 is unused if palette rendering is disabled)
};
typedef enum hwdscreentexture hwdscreentexture_t;
#endif //_HWR_DEFS_ #endif //_HWR_DEFS_

View file

@ -1484,11 +1484,12 @@ static inline boolean saveTGA(const char *file_name, void *buffer,
UINT8 *HWR_GetScreenshot(void) UINT8 *HWR_GetScreenshot(void)
{ {
UINT8 *buf = malloc(vid.width * vid.height * 3 * sizeof (*buf)); UINT8 *buf = malloc(vid.width * vid.height * 3 * sizeof (*buf));
int tex = HWR_ShouldUsePaletteRendering() ? HWD_SCREENTEXTURE_GENERIC3 : HWD_SCREENTEXTURE_GENERIC2;
if (!buf) if (!buf)
return NULL; return NULL;
// returns 24bit 888 RGB // returns 24bit 888 RGB
HWD.pfnReadRect(0, 0, vid.width, vid.height, vid.width * 3, (void *)buf); HWD.pfnReadRect(tex, (void *)buf);
return buf; return buf;
} }
@ -1496,6 +1497,7 @@ boolean HWR_Screenshot(const char *pathname)
{ {
boolean ret; boolean ret;
UINT8 *buf = malloc(vid.width * vid.height * 3 * sizeof (*buf)); UINT8 *buf = malloc(vid.width * vid.height * 3 * sizeof (*buf));
int tex = HWR_ShouldUsePaletteRendering() ? HWD_SCREENTEXTURE_GENERIC3 : HWD_SCREENTEXTURE_GENERIC2;
if (!buf) if (!buf)
{ {
@ -1504,7 +1506,7 @@ boolean HWR_Screenshot(const char *pathname)
} }
// returns 24bit 888 RGB // returns 24bit 888 RGB
HWD.pfnReadRect(0, 0, vid.width, vid.height, vid.width * 3, (void *)buf); HWD.pfnReadRect(tex, (void *)buf);
#ifdef USE_PNG #ifdef USE_PNG
ret = M_SavePNG(pathname, buf, vid.width, vid.height, NULL); ret = M_SavePNG(pathname, buf, vid.width, vid.height, NULL);

View file

@ -43,7 +43,7 @@ EXPORT void HWRAPI(ClearBuffer) (FBOOLEAN ColorMask, FBOOLEAN DepthMask, FRGBAFl
EXPORT void HWRAPI(SetTexture) (GLMipmap_t *TexInfo); EXPORT void HWRAPI(SetTexture) (GLMipmap_t *TexInfo);
EXPORT void HWRAPI(UpdateTexture) (GLMipmap_t *TexInfo); EXPORT void HWRAPI(UpdateTexture) (GLMipmap_t *TexInfo);
EXPORT void HWRAPI(DeleteTexture) (GLMipmap_t *TexInfo); EXPORT void HWRAPI(DeleteTexture) (GLMipmap_t *TexInfo);
EXPORT void HWRAPI(ReadRect) (INT32 x, INT32 y, INT32 width, INT32 height, INT32 dst_stride, UINT16 *dst_data); EXPORT void HWRAPI(ReadRect) (int tex, UINT8 *dst_data);
EXPORT void HWRAPI(GClipRect) (INT32 minx, INT32 miny, INT32 maxx, INT32 maxy, float nearclip); EXPORT void HWRAPI(GClipRect) (INT32 minx, INT32 miny, INT32 maxx, INT32 maxy, float nearclip);
EXPORT void HWRAPI(ClearMipMapCache) (void); EXPORT void HWRAPI(ClearMipMapCache) (void);
@ -55,13 +55,11 @@ EXPORT void HWRAPI(SetTransform) (FTransform *ptransform);
EXPORT INT32 HWRAPI(GetTextureUsed) (void); EXPORT INT32 HWRAPI(GetTextureUsed) (void);
EXPORT void HWRAPI(FlushScreenTextures) (void); EXPORT void HWRAPI(FlushScreenTextures) (void);
EXPORT void HWRAPI(StartScreenWipe) (void); EXPORT void HWRAPI(SwapScreenTextures) (int tex1, int tex2);
EXPORT void HWRAPI(EndScreenWipe) (void); EXPORT void HWRAPI(DoScreenWipe) (int wipeStart, int wipeEnd);
EXPORT void HWRAPI(DoScreenWipe) (void); EXPORT void HWRAPI(DrawScreenTexture) (int tex);
EXPORT void HWRAPI(DrawIntermissionBG) (void); EXPORT void HWRAPI(MakeScreenTexture) (int tex);
EXPORT void HWRAPI(MakeScreenTexture) (void); EXPORT void HWRAPI(DrawScreenFinalTexture) (int tex, int width, int height);
EXPORT void HWRAPI(MakeScreenFinalTexture) (void);
EXPORT void HWRAPI(DrawScreenFinalTexture) (int width, int height);
#define SCREENVERTS 10 #define SCREENVERTS 10
EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2]); EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2]);
@ -115,12 +113,10 @@ struct hwdriver_s
#endif #endif
PostImgRedraw pfnPostImgRedraw; PostImgRedraw pfnPostImgRedraw;
FlushScreenTextures pfnFlushScreenTextures; FlushScreenTextures pfnFlushScreenTextures;
StartScreenWipe pfnStartScreenWipe; SwapScreenTextures pfnSwapScreenTextures;
EndScreenWipe pfnEndScreenWipe;
DoScreenWipe pfnDoScreenWipe; DoScreenWipe pfnDoScreenWipe;
DrawIntermissionBG pfnDrawIntermissionBG; DrawScreenTexture pfnDrawScreenTexture;
MakeScreenTexture pfnMakeScreenTexture; MakeScreenTexture pfnMakeScreenTexture;
MakeScreenFinalTexture pfnMakeScreenFinalTexture;
DrawScreenFinalTexture pfnDrawScreenFinalTexture; DrawScreenFinalTexture pfnDrawScreenFinalTexture;
InitShaders pfnInitShaders; InitShaders pfnInitShaders;

View file

@ -6715,7 +6715,7 @@ void HWR_DoPostProcessor(player_t *player)
// Capture the screen for intermission and screen waving // Capture the screen for intermission and screen waving
if(gamestate != GS_INTERMISSION) if(gamestate != GS_INTERMISSION)
HWD.pfnMakeScreenTexture(); HWD.pfnMakeScreenTexture(HWD_SCREENTEXTURE_GENERIC1);
if (splitscreen) // Not supported in splitscreen - someone want to add support? if (splitscreen) // Not supported in splitscreen - someone want to add support?
return; return;
@ -6760,26 +6760,26 @@ void HWR_DoPostProcessor(player_t *player)
// Capture the screen again for screen waving on the intermission // Capture the screen again for screen waving on the intermission
if(gamestate != GS_INTERMISSION) if(gamestate != GS_INTERMISSION)
HWD.pfnMakeScreenTexture(); HWD.pfnMakeScreenTexture(HWD_SCREENTEXTURE_GENERIC1);
} }
// Flipping of the screen isn't done here anymore // Flipping of the screen isn't done here anymore
} }
void HWR_StartScreenWipe(void) void HWR_StartScreenWipe()
{ {
//CONS_Debug(DBG_RENDER, "In HWR_StartScreenWipe()\n"); //CONS_Debug(DBG_RENDER, "In HWR_StartScreenWipe()\n");
HWD.pfnStartScreenWipe(); HWD.pfnMakeScreenTexture(HWD_SCREENTEXTURE_WIPE_START);
} }
void HWR_EndScreenWipe(void) void HWR_EndScreenWipe(void)
{ {
//CONS_Debug(DBG_RENDER, "In HWR_EndScreenWipe()\n"); //CONS_Debug(DBG_RENDER, "In HWR_EndScreenWipe()\n");
HWD.pfnEndScreenWipe(); HWD.pfnMakeScreenTexture(HWD_SCREENTEXTURE_WIPE_END);
} }
void HWR_DrawIntermissionBG(void) void HWR_DrawIntermissionBG(void)
{ {
HWD.pfnDrawIntermissionBG(); HWD.pfnDrawScreenTexture(HWD_SCREENTEXTURE_GENERIC1);
} }
// //
@ -6824,7 +6824,7 @@ void HWR_DoWipe(UINT8 wipenum, UINT8 scrnnum)
return; return;
HWR_GetFadeMask(wipelumpnum); HWR_GetFadeMask(wipelumpnum);
HWD.pfnDoScreenWipe(); HWD.pfnDoScreenWipe(HWD_SCREENTEXTURE_WIPE_START, HWD_SCREENTEXTURE_WIPE_END);
} }
void HWR_DoTintedWipe(UINT8 wipenum, UINT8 scrnnum) void HWR_DoTintedWipe(UINT8 wipenum, UINT8 scrnnum)
@ -6835,12 +6835,14 @@ void HWR_DoTintedWipe(UINT8 wipenum, UINT8 scrnnum)
void HWR_MakeScreenFinalTexture(void) void HWR_MakeScreenFinalTexture(void)
{ {
HWD.pfnMakeScreenFinalTexture(); int tex = HWR_ShouldUsePaletteRendering() ? HWD_SCREENTEXTURE_GENERIC3 : HWD_SCREENTEXTURE_GENERIC2;
HWD.pfnMakeScreenTexture(tex);
} }
void HWR_DrawScreenFinalTexture(int width, int height) void HWR_DrawScreenFinalTexture(int width, int height)
{ {
HWD.pfnDrawScreenFinalTexture(width, height); int tex = HWR_ShouldUsePaletteRendering() ? HWD_SCREENTEXTURE_GENERIC3 : HWD_SCREENTEXTURE_GENERIC2;
HWD.pfnDrawScreenFinalTexture(tex, width, height);
} }
#endif // HWRENDER #endif // HWRENDER

View file

@ -104,10 +104,7 @@ static GLint viewport[4];
// flush all of the stored textures, leaving them unavailable at times such as between levels // flush all of the stored textures, leaving them unavailable at times such as between levels
// These need to start at 0 and be set to their number, and be reset to 0 when deleted so that intel GPUs // These need to start at 0 and be set to their number, and be reset to 0 when deleted so that intel GPUs
// can know when the textures aren't there, as textures are always considered resident in their virtual memory // can know when the textures aren't there, as textures are always considered resident in their virtual memory
static GLuint screentexture = 0; static GLuint screenTextures[NUMSCREENTEXTURES] = {0};
static GLuint startScreenWipe = 0;
static GLuint endScreenWipe = 0;
static GLuint finalScreenTexture = 0;
// shortcut for ((float)1/i) // shortcut for ((float)1/i)
static const GLfloat byte2float[256] = { static const GLfloat byte2float[256] = {
@ -400,6 +397,8 @@ typedef void (APIENTRY * PFNglTexImage2D) (GLenum target, GLint level, GLint int
static PFNglTexImage2D pglTexImage2D; static PFNglTexImage2D pglTexImage2D;
typedef void (APIENTRY * PFNglTexSubImage2D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); typedef void (APIENTRY * PFNglTexSubImage2D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
static PFNglTexSubImage2D pglTexSubImage2D; static PFNglTexSubImage2D pglTexSubImage2D;
typedef void (APIENTRY * PFNglGetTexImage) (GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels);
static PFNglGetTexImage pglGetTexImage;
/* 1.1 functions */ /* 1.1 functions */
/* texture objects */ //GL_EXT_texture_object /* texture objects */ //GL_EXT_texture_object
@ -544,6 +543,7 @@ boolean SetupGLfunc(void)
GETOPENGLFUNC(pglTexImage1D, glTexImage1D) GETOPENGLFUNC(pglTexImage1D, glTexImage1D)
GETOPENGLFUNC(pglTexImage2D, glTexImage2D) GETOPENGLFUNC(pglTexImage2D, glTexImage2D)
GETOPENGLFUNC(pglTexSubImage2D, glTexSubImage2D) GETOPENGLFUNC(pglTexSubImage2D, glTexSubImage2D)
GETOPENGLFUNC(pglGetTexImage, glGetTexImage)
GETOPENGLFUNC(pglGenTextures, glGenTextures) GETOPENGLFUNC(pglGenTextures, glGenTextures)
GETOPENGLFUNC(pglDeleteTextures, glDeleteTextures) GETOPENGLFUNC(pglDeleteTextures, glDeleteTextures)
@ -1163,55 +1163,83 @@ EXPORT void HWRAPI(ClearMipMapCache) (void)
} }
// -----------------+ // Writes screen texture tex into dst_data.
// ReadRect : Read a rectangle region of the truecolor framebuffer // Pixel format is 24-bit RGB. Row order is top to bottom.
// : store pixels as 16bit 565 RGB // Dimensions are screen_width * screen_height.
// Returns : 16bit 565 RGB pixel array stored in dst_data // TODO should rename to ReadScreenTexture
// -----------------+ EXPORT void HWRAPI(ReadRect) (int tex, UINT8 *dst_data)
EXPORT void HWRAPI(ReadRect) (INT32 x, INT32 y, INT32 width, INT32 height,
INT32 dst_stride, UINT16 * dst_data)
{ {
INT32 i; INT32 i;
int dst_stride = screen_width * 3; // stride between rows of image data
GLubyte*top = (GLvoid*)dst_data, *bottom = top + dst_stride * (screen_height - 1);
//precise_t ts1, ts2, ts3, ts4, ts5, total_time, get_time, loop_time;
GLubyte *row;
//ts1 = I_GetPreciseTime();
row = malloc(dst_stride);
if (!row) return;
//ts2 = I_GetPreciseTime();
// at the time this function is called, generic2 can be found drawn on the framebuffer
// if some other screen texture is needed, draw it to the framebuffer
// and draw generic2 back after reading the framebuffer.
// this hack is for some reason **much** faster than the simple solution of using glGetTexImage.
if (tex != HWD_SCREENTEXTURE_GENERIC2)
DrawScreenTexture(tex);
pglPixelStorei(GL_PACK_ALIGNMENT, 1);
pglReadPixels(0, 0, screen_width, screen_height, GL_RGB, GL_UNSIGNED_BYTE, dst_data);
if (tex != HWD_SCREENTEXTURE_GENERIC2)
DrawScreenTexture(HWD_SCREENTEXTURE_GENERIC2);
//ts3 = I_GetPreciseTime();
// Flip image upside down.
// In other words, convert OpenGL's "bottom->top" row order into "top->bottom".
for(i = 0; i < screen_height/2; i++)
{
memcpy(row, top, dst_stride);
memcpy(top, bottom, dst_stride);
memcpy(bottom, row, dst_stride);
top += dst_stride;
bottom -= dst_stride;
}
//ts4 = I_GetPreciseTime();
free(row);
//ts5 = I_GetPreciseTime();
//total_time = I_PreciseToMicros(ts5 - ts1);
//get_time = I_PreciseToMicros(ts3 - ts2);
//loop_time = I_PreciseToMicros(ts4 - ts3);
//CONS_Printf("ReadRect: total time: %" PRIu64 ", read pixels thing: %" PRIu64 " memcpy loop: %" PRIu64 "\n", total_time, get_time, loop_time);
// the slow glGetTexImage based implementation. left in here in case i wanna test it more
// TODO remove this at some point
/*int texsize = 512;
GLsizei buffer_size;
GLubyte *buffer;
// GL_DBG_Printf ("ReadRect()\n"); // GL_DBG_Printf ("ReadRect()\n");
if (dst_stride == width*3) precise_t ts1, ts2, ts3, ts4, ts5, total_time, get_time, loop_time;
{ ts1 = I_GetPreciseTime();
GLubyte*top = (GLvoid*)dst_data, *bottom = top + dst_stride * (height - 1); // look for power of two that is large enough for the screen
GLubyte *row = malloc(dst_stride); while (texsize < screen_width || texsize < screen_height)
if (!row) return; texsize <<= 1;
pglPixelStorei(GL_PACK_ALIGNMENT, 1); buffer_size = texsize * texsize * 4;
pglReadPixels(x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, dst_data); buffer = malloc(buffer_size);
pglPixelStorei(GL_UNPACK_ALIGNMENT, 1); tex_downloaded = screenTextures[tex];
for(i = 0; i < height/2; i++) pglBindTexture(GL_TEXTURE_2D, tex_downloaded);
{ ts2 = I_GetPreciseTime();
memcpy(row, top, dst_stride); pglGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_BYTE, buffer); // GL better not overwrite my buffer :v
memcpy(top, bottom, dst_stride); ts3 = I_GetPreciseTime();
memcpy(bottom, row, dst_stride); //for (i = 0; i < screen_height; i++) // i: pixel row index that we are writing
top += dst_stride; //{
bottom -= dst_stride; // // read the frame from the lower left corner of the GL screen texture
} // // flip it upside down so it's in correct format
free(row); // memcpy(dst_data + (screen_height - i - 1) * screen_width * 3,
} // buffer + i * texsize * 3, screen_width * 3);
else //}
{ ts4 = I_GetPreciseTime();
INT32 j; free(buffer);
GLubyte *image = malloc(width*height*3*sizeof (*image)); ts5 = I_GetPreciseTime();
if (!image) return; total_time = I_PreciseToMicros(ts5 - ts1);
pglPixelStorei(GL_PACK_ALIGNMENT, 1); get_time = I_PreciseToMicros(ts3 - ts2);
pglReadPixels(x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, image); loop_time = I_PreciseToMicros(ts4 - ts3);
pglPixelStorei(GL_UNPACK_ALIGNMENT, 1); CONS_Printf("ReadRect: total time: %" PRIu64 ", glGetTexImage: %" PRIu64 " memcpy loop: %" PRIu64 "\n", total_time, get_time, loop_time);*/
for (i = height-1; i >= 0; i--)
{
for (j = 0; j < width; j++)
{
dst_data[(height-1-i)*width+j] =
(UINT16)(
((image[(i*width+j)*3]>>3)<<11) |
((image[(i*width+j)*3+1]>>2)<<5) |
((image[(i*width+j)*3+2]>>3)));
}
}
free(image);
}
} }
@ -2896,7 +2924,7 @@ EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2])
INT32 x, y; INT32 x, y;
float float_x, float_y, float_nextx, float_nexty; float float_x, float_y, float_nextx, float_nexty;
float xfix, yfix; float xfix, yfix;
INT32 texsize = 2048; INT32 texsize = 512;
const float blackBack[16] = const float blackBack[16] =
{ {
@ -2906,11 +2934,9 @@ EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2])
16.0f, -16.0f, 6.0f 16.0f, -16.0f, 6.0f
}; };
// Use a power of two texture, dammit // look for power of two that is large enough for the screen
if(screen_width <= 1024) while (texsize < screen_width || texsize < screen_height)
texsize = 1024; texsize <<= 1;
if(screen_width <= 512)
texsize = 512;
// X/Y stretch fix for all resolutions(!) // X/Y stretch fix for all resolutions(!)
xfix = (float)(texsize)/((float)((screen_width)/(float)(SCREENVERTS-1))); xfix = (float)(texsize)/((float)((screen_width)/(float)(SCREENVERTS-1)));
@ -2984,84 +3010,24 @@ EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2])
// a new size // a new size
EXPORT void HWRAPI(FlushScreenTextures) (void) EXPORT void HWRAPI(FlushScreenTextures) (void)
{ {
pglDeleteTextures(1, &screentexture); int i;
pglDeleteTextures(1, &startScreenWipe); pglDeleteTextures(NUMSCREENTEXTURES, screenTextures);
pglDeleteTextures(1, &endScreenWipe); for (i = 0; i < NUMSCREENTEXTURES; i++)
pglDeleteTextures(1, &finalScreenTexture); screenTextures[i] = 0;
screentexture = 0;
startScreenWipe = 0;
endScreenWipe = 0;
finalScreenTexture = 0;
} }
// Create Screen to fade from EXPORT void HWRAPI(SwapScreenTextures) (int tex1, int tex2)
EXPORT void HWRAPI(StartScreenWipe) (void)
{ {
INT32 texsize = 2048; GLuint temp = screenTextures[tex1];
boolean firstTime = (startScreenWipe == 0); screenTextures[tex1] = screenTextures[tex2];
screenTextures[tex2] = temp;
// Use a power of two texture, dammit
if(screen_width <= 512)
texsize = 512;
else if(screen_width <= 1024)
texsize = 1024;
// Create screen texture
if (firstTime)
pglGenTextures(1, &startScreenWipe);
pglBindTexture(GL_TEXTURE_2D, startScreenWipe);
if (firstTime)
{
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
Clamp2D(GL_TEXTURE_WRAP_S);
Clamp2D(GL_TEXTURE_WRAP_T);
pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsize, texsize, 0);
}
else
pglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, texsize, texsize);
tex_downloaded = startScreenWipe;
}
// Create Screen to fade to
EXPORT void HWRAPI(EndScreenWipe)(void)
{
INT32 texsize = 2048;
boolean firstTime = (endScreenWipe == 0);
// Use a power of two texture, dammit
if(screen_width <= 512)
texsize = 512;
else if(screen_width <= 1024)
texsize = 1024;
// Create screen texture
if (firstTime)
pglGenTextures(1, &endScreenWipe);
pglBindTexture(GL_TEXTURE_2D, endScreenWipe);
if (firstTime)
{
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
Clamp2D(GL_TEXTURE_WRAP_S);
Clamp2D(GL_TEXTURE_WRAP_T);
pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsize, texsize, 0);
}
else
pglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, texsize, texsize);
tex_downloaded = endScreenWipe;
} }
// Draw the last scene under the intermission EXPORT void HWRAPI(DrawScreenTexture)(int tex)
EXPORT void HWRAPI(DrawIntermissionBG)(void)
{ {
float xfix, yfix; float xfix, yfix;
INT32 texsize = 2048; INT32 texsize = 512;
const float screenVerts[12] = const float screenVerts[12] =
{ {
@ -3073,10 +3039,9 @@ EXPORT void HWRAPI(DrawIntermissionBG)(void)
float fix[8]; float fix[8];
if(screen_width <= 1024) // look for power of two that is large enough for the screen
texsize = 1024; while (texsize < screen_width || texsize < screen_height)
if(screen_width <= 512) texsize <<= 1;
texsize = 512;
xfix = 1/((float)(texsize)/((float)((screen_width)))); xfix = 1/((float)(texsize)/((float)((screen_width))));
yfix = 1/((float)(texsize)/((float)((screen_height)))); yfix = 1/((float)(texsize)/((float)((screen_height))));
@ -3095,20 +3060,21 @@ EXPORT void HWRAPI(DrawIntermissionBG)(void)
pglClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); pglClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
pglBindTexture(GL_TEXTURE_2D, screentexture); pglBindTexture(GL_TEXTURE_2D, screenTextures[tex]);
Shader_SetUniforms(NULL, NULL, NULL, NULL); // prepare shader, if it is enabled
pglColor4ubv(white); pglColor4ubv(white);
pglTexCoordPointer(2, GL_FLOAT, 0, fix); pglTexCoordPointer(2, GL_FLOAT, 0, fix);
pglVertexPointer(3, GL_FLOAT, 0, screenVerts); pglVertexPointer(3, GL_FLOAT, 0, screenVerts);
pglDrawArrays(GL_TRIANGLE_FAN, 0, 4); pglDrawArrays(GL_TRIANGLE_FAN, 0, 4);
tex_downloaded = screentexture; tex_downloaded = screenTextures[tex];
} }
// Do screen fades! // Do screen fades!
EXPORT void HWRAPI(DoScreenWipe)(void) EXPORT void HWRAPI(DoScreenWipe)(int wipeStart, int wipeEnd)
{ {
INT32 texsize = 2048; INT32 texsize = 512;
float xfix, yfix; float xfix, yfix;
INT32 fademaskdownloaded = tex_downloaded; // the fade mask that has been set INT32 fademaskdownloaded = tex_downloaded; // the fade mask that has been set
@ -3131,11 +3097,9 @@ EXPORT void HWRAPI(DoScreenWipe)(void)
1.0f, 1.0f 1.0f, 1.0f
}; };
// Use a power of two texture, dammit // look for power of two that is large enough for the screen
if(screen_width <= 1024) while (texsize < screen_width || texsize < screen_height)
texsize = 1024; texsize <<= 1;
if(screen_width <= 512)
texsize = 512;
xfix = 1/((float)(texsize)/((float)((screen_width)))); xfix = 1/((float)(texsize)/((float)((screen_width))));
yfix = 1/((float)(texsize)/((float)((screen_height)))); yfix = 1/((float)(texsize)/((float)((screen_height))));
@ -3158,7 +3122,7 @@ EXPORT void HWRAPI(DoScreenWipe)(void)
pglEnable(GL_TEXTURE_2D); pglEnable(GL_TEXTURE_2D);
// Draw the original screen // Draw the original screen
pglBindTexture(GL_TEXTURE_2D, startScreenWipe); pglBindTexture(GL_TEXTURE_2D, screenTextures[wipeStart]);
pglColor4ubv(white); pglColor4ubv(white);
pglTexCoordPointer(2, GL_FLOAT, 0, fix); pglTexCoordPointer(2, GL_FLOAT, 0, fix);
pglVertexPointer(3, GL_FLOAT, 0, screenVerts); pglVertexPointer(3, GL_FLOAT, 0, screenVerts);
@ -3169,7 +3133,7 @@ EXPORT void HWRAPI(DoScreenWipe)(void)
// Draw the end screen that fades in // Draw the end screen that fades in
pglActiveTexture(GL_TEXTURE0); pglActiveTexture(GL_TEXTURE0);
pglEnable(GL_TEXTURE_2D); pglEnable(GL_TEXTURE_2D);
pglBindTexture(GL_TEXTURE_2D, endScreenWipe); pglBindTexture(GL_TEXTURE_2D, screenTextures[wipeEnd]);
pglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); pglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
pglActiveTexture(GL_TEXTURE1); pglActiveTexture(GL_TEXTURE1);
@ -3193,25 +3157,23 @@ EXPORT void HWRAPI(DoScreenWipe)(void)
pglActiveTexture(GL_TEXTURE0); pglActiveTexture(GL_TEXTURE0);
pglClientActiveTexture(GL_TEXTURE0); pglClientActiveTexture(GL_TEXTURE0);
tex_downloaded = endScreenWipe; tex_downloaded = screenTextures[wipeEnd];
} }
// Create a texture from the screen. // Create a texture from the screen.
EXPORT void HWRAPI(MakeScreenTexture) (void) EXPORT void HWRAPI(MakeScreenTexture) (int tex)
{ {
INT32 texsize = 2048; INT32 texsize = 512;
boolean firstTime = (screentexture == 0); boolean firstTime = (screenTextures[tex] == 0);
// Use a power of two texture, dammit // look for power of two that is large enough for the screen
if(screen_width <= 512) while (texsize < screen_width || texsize < screen_height)
texsize = 512; texsize <<= 1;
else if(screen_width <= 1024)
texsize = 1024;
// Create screen texture // Create screen texture
if (firstTime) if (firstTime)
pglGenTextures(1, &screentexture); pglGenTextures(1, &screenTextures[tex]);
pglBindTexture(GL_TEXTURE_2D, screentexture); pglBindTexture(GL_TEXTURE_2D, screenTextures[tex]);
if (firstTime) if (firstTime)
{ {
@ -3224,54 +3186,23 @@ EXPORT void HWRAPI(MakeScreenTexture) (void)
else else
pglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, texsize, texsize); pglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, texsize, texsize);
tex_downloaded = screentexture; tex_downloaded = screenTextures[tex];
} }
EXPORT void HWRAPI(MakeScreenFinalTexture) (void) EXPORT void HWRAPI(DrawScreenFinalTexture)(int tex, int width, int height)
{
INT32 texsize = 2048;
boolean firstTime = (finalScreenTexture == 0);
// Use a power of two texture, dammit
if(screen_width <= 512)
texsize = 512;
else if(screen_width <= 1024)
texsize = 1024;
// Create screen texture
if (firstTime)
pglGenTextures(1, &finalScreenTexture);
pglBindTexture(GL_TEXTURE_2D, finalScreenTexture);
if (firstTime)
{
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
Clamp2D(GL_TEXTURE_WRAP_S);
Clamp2D(GL_TEXTURE_WRAP_T);
pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsize, texsize, 0);
}
else
pglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, texsize, texsize);
tex_downloaded = finalScreenTexture;
}
EXPORT void HWRAPI(DrawScreenFinalTexture)(int width, int height)
{ {
float xfix, yfix; float xfix, yfix;
float origaspect, newaspect; float origaspect, newaspect;
float xoff = 1, yoff = 1; // xoffset and yoffset for the polygon to have black bars around the screen float xoff = 1, yoff = 1; // xoffset and yoffset for the polygon to have black bars around the screen
FRGBAFloat clearColour; FRGBAFloat clearColour;
INT32 texsize = 2048; INT32 texsize = 512;
float off[12]; float off[12];
float fix[8]; float fix[8];
if(screen_width <= 1024) // look for power of two that is large enough for the screen
texsize = 1024; while (texsize < screen_width || texsize < screen_height)
if(screen_width <= 512) texsize <<= 1;
texsize = 512;
xfix = 1/((float)(texsize)/((float)((screen_width)))); xfix = 1/((float)(texsize)/((float)((screen_width))));
yfix = 1/((float)(texsize)/((float)((screen_height)))); yfix = 1/((float)(texsize)/((float)((screen_height))));
@ -3318,10 +3249,7 @@ EXPORT void HWRAPI(DrawScreenFinalTexture)(int width, int height)
clearColour.red = clearColour.green = clearColour.blue = 0; clearColour.red = clearColour.green = clearColour.blue = 0;
clearColour.alpha = 1; clearColour.alpha = 1;
ClearBuffer(true, false, &clearColour); ClearBuffer(true, false, &clearColour);
pglBindTexture(GL_TEXTURE_2D, finalScreenTexture); pglBindTexture(GL_TEXTURE_2D, screenTextures[tex]);
// prepare shader, if it is enabled
Shader_SetUniforms(NULL, NULL, NULL, NULL);
pglColor4ubv(white); pglColor4ubv(white);
@ -3329,7 +3257,7 @@ EXPORT void HWRAPI(DrawScreenFinalTexture)(int width, int height)
pglVertexPointer(3, GL_FLOAT, 0, off); pglVertexPointer(3, GL_FLOAT, 0, off);
pglDrawArrays(GL_TRIANGLE_FAN, 0, 4); pglDrawArrays(GL_TRIANGLE_FAN, 0, 4);
tex_downloaded = finalScreenTexture; tex_downloaded = screenTextures[tex];
} }
EXPORT void HWRAPI(SetPaletteLookup)(UINT8 *lut) EXPORT void HWRAPI(SetPaletteLookup)(UINT8 *lut)

View file

@ -21,6 +21,7 @@
#include "i_system.h" // I_GetPreciseTime #include "i_system.h" // I_GetPreciseTime
#include "m_misc.h" #include "m_misc.h"
#include "st_stuff.h" // st_palette #include "st_stuff.h" // st_palette
#include "doomstat.h" // singletics
#ifdef HWRENDER #ifdef HWRENDER
#include "hardware/hw_main.h" #include "hardware/hw_main.h"
@ -604,7 +605,7 @@ static void GIF_framewrite(void)
UINT16 delay = 0; UINT16 delay = 0;
INT32 startline; INT32 startline;
if (gif_dynamicdelay ==(UINT8) 2) if (gif_dynamicdelay ==(UINT8) 2 && !singletics)
{ {
// golden's attempt at creating a "dynamic delay" // golden's attempt at creating a "dynamic delay"
UINT16 mingifdelay = 10; // minimum gif delay in milliseconds (keep at 10 because gifs can't get more precise). UINT16 mingifdelay = 10; // minimum gif delay in milliseconds (keep at 10 because gifs can't get more precise).
@ -617,7 +618,7 @@ static void GIF_framewrite(void)
gif_delayus -= frames*(mingifdelay*1000); // remove frames by the amount of milliseconds they take. don't reset to 0, the microseconds help consistency. gif_delayus -= frames*(mingifdelay*1000); // remove frames by the amount of milliseconds they take. don't reset to 0, the microseconds help consistency.
} }
} }
else if (gif_dynamicdelay ==(UINT8) 1) else if (gif_dynamicdelay ==(UINT8) 1 && !singletics)
{ {
float delayf = ceil(100.0f/NEWTICRATE); float delayf = ceil(100.0f/NEWTICRATE);

View file

@ -1250,7 +1250,7 @@ void M_SaveFrame(void)
// paranoia: should be unnecessary without singletics // paranoia: should be unnecessary without singletics
static tic_t oldtic = 0; static tic_t oldtic = 0;
if (oldtic == I_GetTime()) if (oldtic == I_GetTime() && !singletics)
return; return;
else else
oldtic = I_GetTime(); oldtic = I_GetTime();

View file

@ -97,12 +97,10 @@ void *hwSym(const char *funcName,void *handle)
GETFUNC(SetTransform); GETFUNC(SetTransform);
GETFUNC(PostImgRedraw); GETFUNC(PostImgRedraw);
GETFUNC(FlushScreenTextures); GETFUNC(FlushScreenTextures);
GETFUNC(StartScreenWipe); GETFUNC(SwapScreenTextures);
GETFUNC(EndScreenWipe);
GETFUNC(DoScreenWipe); GETFUNC(DoScreenWipe);
GETFUNC(DrawIntermissionBG); GETFUNC(DrawScreenTexture);
GETFUNC(MakeScreenTexture); GETFUNC(MakeScreenTexture);
GETFUNC(MakeScreenFinalTexture);
GETFUNC(DrawScreenFinalTexture); GETFUNC(DrawScreenFinalTexture);
GETFUNC(InitShaders); GETFUNC(InitShaders);

View file

@ -1244,11 +1244,10 @@ void I_FinishUpdate(void)
// Final postprocess step of palette rendering, after everything else has been drawn. // Final postprocess step of palette rendering, after everything else has been drawn.
if (HWR_ShouldUsePaletteRendering()) if (HWR_ShouldUsePaletteRendering())
{ {
// not using the function for its original named purpose but can be used like this too HWD.pfnMakeScreenTexture(HWD_SCREENTEXTURE_GENERIC2);
HWR_MakeScreenFinalTexture();
HWD.pfnSetSpecialState(HWD_SET_SHADERS, 1); HWD.pfnSetSpecialState(HWD_SET_SHADERS, 1);
HWD.pfnSetShader(HWR_GetShaderFromTarget(SHADER_PALETTE_POSTPROCESS)); HWD.pfnSetShader(HWR_GetShaderFromTarget(SHADER_PALETTE_POSTPROCESS));
HWR_DrawScreenFinalTexture(vid.width, vid.height); HWD.pfnDrawScreenTexture(HWD_SCREENTEXTURE_GENERIC2);
HWD.pfnUnSetShader(); HWD.pfnUnSetShader();
HWD.pfnSetSpecialState(HWD_SET_SHADERS, 0); HWD.pfnSetSpecialState(HWD_SET_SHADERS, 0);
} }
@ -1881,12 +1880,10 @@ void VID_StartupOpenGL(void)
HWD.pfnSetTransform = hwSym("SetTransform",NULL); HWD.pfnSetTransform = hwSym("SetTransform",NULL);
HWD.pfnPostImgRedraw = hwSym("PostImgRedraw",NULL); HWD.pfnPostImgRedraw = hwSym("PostImgRedraw",NULL);
HWD.pfnFlushScreenTextures=hwSym("FlushScreenTextures",NULL); HWD.pfnFlushScreenTextures=hwSym("FlushScreenTextures",NULL);
HWD.pfnStartScreenWipe = hwSym("StartScreenWipe",NULL); HWD.pfnSwapScreenTextures=hwSym("SwapScreenTextures",NULL);
HWD.pfnEndScreenWipe = hwSym("EndScreenWipe",NULL);
HWD.pfnDoScreenWipe = hwSym("DoScreenWipe",NULL); HWD.pfnDoScreenWipe = hwSym("DoScreenWipe",NULL);
HWD.pfnDrawIntermissionBG=hwSym("DrawIntermissionBG",NULL); HWD.pfnDrawScreenTexture= hwSym("DrawScreenTexture",NULL);
HWD.pfnMakeScreenTexture= hwSym("MakeScreenTexture",NULL); HWD.pfnMakeScreenTexture= hwSym("MakeScreenTexture",NULL);
HWD.pfnMakeScreenFinalTexture=hwSym("MakeScreenFinalTexture",NULL);
HWD.pfnDrawScreenFinalTexture=hwSym("DrawScreenFinalTexture",NULL); HWD.pfnDrawScreenFinalTexture=hwSym("DrawScreenFinalTexture",NULL);
HWD.pfnInitShaders = hwSym("InitShaders",NULL); HWD.pfnInitShaders = hwSym("InitShaders",NULL);

View file

@ -230,7 +230,9 @@ void OglSdlFinishUpdate(boolean waitvbl)
// Sryder: We need to draw the final screen texture again into the other buffer in the original position so that // Sryder: We need to draw the final screen texture again into the other buffer in the original position so that
// effects that want to take the old screen can do so after this // effects that want to take the old screen can do so after this
HWR_DrawScreenFinalTexture(realwidth, realheight); // Generic2 has the screen image without palette rendering brightness adjustments.
// Using that here will prevent brightness adjustments being applied twice.
DrawScreenTexture(HWD_SCREENTEXTURE_GENERIC2);
} }
EXPORT void HWRAPI(OglSdlSetPalette) (RGBA_t *palette) EXPORT void HWRAPI(OglSdlSetPalette) (RGBA_t *palette)