Commit 06888f13 by SteelT

OpenGL gifs 2:the gifing

Attempt to fix OpenGL gifs crash the game. But I almost got OpenGL APNG working in the process, so that's a plus!
parent 6c3218f0
......@@ -706,40 +706,25 @@ UINT8 *HWR_GetScreenshot(void)
return buf;
}
boolean HWR_Screenshot(const char *lbmname)
boolean HWR_Screenshot(const char *pathname)
{
int i;
boolean ret;
byte *bufw, *dest;
unsigned short *bufr, rgb565;
UINT8 *buf = malloc(vid.width * vid.height * 3 * sizeof (*buf));
bufr = malloc(vid.width * vid.height * 2);
if (!bufr)
return false;
bufw = malloc(vid.width * vid.height * 3);
if (!bufw)
if (!buf)
{
free(bufr);
CONS_Printf("HWR_Screenshot: Failed to allocate memory\n");
return false;
}
// returns 16bit 565 RGB
HWD.pfnReadRect(0, 0, vid.width, vid.height, vid.width * 2, bufr);
for (dest = bufw, i = 0; i < vid.width * vid.height; i++)
{
rgb565 = bufr[i];
*(dest++) = (byte)((rgb565 & 31) <<3);
*(dest++) = (byte)(((rgb565 >> 5) & 63) <<2);
*(dest++) = (byte)(((rgb565 >> 11) & 31) <<3);
}
free(bufr);
// returns 24bit 888 RGB
HWD.pfnReadRect(0, 0, vid.width, vid.height, vid.width * 3, (void *)buf);
#ifdef USE_PNG
ret = M_SavePNG(lbmname, bufw, vid.width, vid.height, NULL);
ret = M_SavePNG(pathname, buf, vid.width, vid.height, NULL);
#else
ret = saveTGA(lbmname, bufw, vid.width, vid.height);
ret = saveTGA(pathname, buf, vid.width, vid.height);
#endif
free(bufw);
free(buf);
return ret;
}
......@@ -31,6 +31,10 @@
#include <math.h>
#include "r_opengl.h"
/* Raster functions */
#define pglPixelStorei glPixelStorei
#define pglReadPixels glReadPixels
// for KOS: GL_TEXTURE_ENV, glAlphaFunc, glColorMask, glPolygonOffset, glReadPixels, GL_ALPHA_TEST, GL_POLYGON_OFFSET_FILL
// ==========================================================================
......@@ -82,7 +86,6 @@ static GLdouble projMatrix[16];
static GLint viewport[4];
#endif
#ifdef USE_PALETTED_TEXTURE
PFNGLCOLORTABLEEXTPROC glColorTableEXT = NULL;
GLubyte palette_tex[256*3];
......@@ -395,30 +398,53 @@ EXPORT void HWRAPI(ClearMipMapCache) (void)
// : store pixels as 16bit 565 RGB
// Returns : 16bit 565 RGB pixel array stored in dst_data
// -----------------+
EXPORT void HWRAPI(ReadRect) (int x, int y, int width, int height,
int dst_stride, unsigned short * dst_data)
EXPORT void HWRAPI(ReadRect) (INT32 x, INT32 y, INT32 width, INT32 height,
INT32 dst_stride, UINT16 * dst_data)
{
INT32 i;
// DBG_Printf ("ReadRect()\n");
GLubyte *image;
int i, j;
dst_stride = 0;
#ifdef KOS_GL_COMPATIBILITY
x = y = width = height = i = j = 0;
image = dst_data = NULL;
#else
image = (GLubyte *) malloc(width*height*3*sizeof (GLubyte));
glReadPixels(x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, image);
for (i = height-1; i >= 0; i--)
for (j = 0; j < width; j++)
dst_data[(height-1-i)*width+j] = (unsigned short)(
((image[(i*width+j)*3]>>3)<<11) |
((image[(i*width+j)*3+1]>>2)<<5) |
((image[(i*width+j)*3+2]>>3)));
free(image);
#endif
if (dst_stride == width*3)
{
GLubyte*top = (GLvoid*)dst_data, *bottom = top + dst_stride * (height - 1);
GLubyte *row = malloc(dst_stride);
if (!row) return;
pglPixelStorei(GL_PACK_ALIGNMENT, 1);
pglReadPixels(x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, dst_data);
pglPixelStorei(GL_UNPACK_ALIGNMENT, 1);
for(i = 0; i < height/2; i++)
{
memcpy(row, top, dst_stride);
memcpy(top, bottom, dst_stride);
memcpy(bottom, row, dst_stride);
top += dst_stride;
bottom -= dst_stride;
}
free(row);
}
else
{
INT32 j;
GLubyte *image = malloc(width*height*3*sizeof (*image));
if (!image) return;
pglPixelStorei(GL_PACK_ALIGNMENT, 1);
pglReadPixels(x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, image);
pglPixelStorei(GL_UNPACK_ALIGNMENT, 1);
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);
}
}
#ifdef HAVE_SDL
EXPORT boolean HWRAPI(ReadScreenTexture) (INT32 x, INT32 y, INT32 width,
INT32 height, INT32 dst_stride,
......
......@@ -460,32 +460,27 @@ static UINT8 *gifframe_data = NULL;
static size_t gifframe_size = 8192;
#ifdef HWRENDER
static void hwrconvert(void)
static void GIF_rgbconvert(UINT8 *linear, UINT8 *scr)
{
UINT8 *linear = HWR_GetScreenshot();
UINT8 *dest = screens[2];
UINT8 r, g, b;
INT32 x, y;
size_t i = 0;
size_t src = 0, dest = 0;
size_t size = (vid.width * vid.height * 3);
InitColorLUT(gif_palette);
InitColorLUT(gif_palette);;
for (y = 0; y < vid.height; y++)
while (src < size)
{
for (x = 0; x < vid.width; x++, i += 3)
{
r = (UINT8)linear[i];
g = (UINT8)linear[i + 1];
b = (UINT8)linear[i + 2];
CONS_Printf("colorlookup %d %d %d\n", colorlookup[r >> SHIFTCOLORBITS][g >> SHIFTCOLORBITS][b >> SHIFTCOLORBITS]);
dest[(y * vid.width) + x] = colorlookup[r >> SHIFTCOLORBITS][g >> SHIFTCOLORBITS][b >> SHIFTCOLORBITS];
}
r = (UINT8)linear[src];
g = (UINT8)linear[src + 1];
b = (UINT8)linear[src + 2];
scr[dest] = colorlookup[r >> SHIFTCOLORBITS][g >> SHIFTCOLORBITS][b >> SHIFTCOLORBITS];
src += (3 * scrbuf_downscaleamt);
dest += scrbuf_downscaleamt;
}
free(linear);
}
#endif
//
// GIF_framewrite
// writes a frame into the file.
......@@ -515,7 +510,11 @@ static void GIF_framewrite(void)
I_ReadScreen(movie_screen);
#ifdef HWRENDER
else if (rendermode == render_opengl)
hwrconvert();
{
UINT8 *linear = HWR_GetScreenshot();
GIF_rgbconvert(linear, movie_screen);
free(linear);
}
#endif
}
else
......@@ -524,22 +523,25 @@ static void GIF_framewrite(void)
blitw = vid.width;
blith = vid.height;
if (gif_frames == 0)
{
if (rendermode == render_soft)
I_ReadScreen(movie_screen);
#ifdef HWRENDER
else if (rendermode == render_opengl)
{
hwrconvert();
VID_BlitLinearScreen(screens[2], screens[0], vid.width*vid.bpp, vid.height, vid.width*vid.bpp, vid.rowbytes);
}
#endif
// Copy the current OpenGL frame into the base screen
if (rendermode == render_opengl)
{
UINT8 *linear = HWR_GetScreenshot();
GIF_rgbconvert(linear, screens[0]);
free(linear);
}
#endif
// Copy the first frame into the movie screen
// OpenGL already does the same above.
if (gif_frames == 0 && rendermode == render_soft)
I_ReadScreen(movie_screen);
movie_screen = screens[0];
}
// screen regions are handled in GIF_lzw
{
int d1 = (int)((100.0f/NEWTICRATE)*(gif_frames+1));
......@@ -644,10 +646,11 @@ INT32 GIF_open(const char *filename)
// In hardware mode, uses the master palette
gif_palette = (
#ifdef HWRENDER
(rendermode == render_soft)
(rendermode == render_opengl)
#endif
? pLocalPalette
: pMasterPalette);
CONS_Printf("%s\n", gif_palette);
GIF_headwrite();
gif_frames = 0;
return 1;
......
......@@ -37,7 +37,7 @@
#if defined (DC) || defined (_WIN32_WCE) || defined (PSP)
#define NUMSCREENS 2
#else
#define NUMSCREENS 4
#define NUMSCREENS 5
#endif
// Size of statusbar.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment