From fd091d66e2673b19eb9c7d73d95160ef874de5e6 Mon Sep 17 00:00:00 2001 From: havoc Date: Wed, 28 Nov 2007 05:22:48 +0000 Subject: [PATCH] changed texture formats from RGBA to BGRA, yes this is a massive change, aimed solely at reducing load times, but it failed at that. this contains several cleanups, and shouldn't reduce performance on any hardware, so it still goes in. git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@7725 d7cf8633-e32d-0410-b094-e92efae38249 --- cl_main.c | 10 +- cl_parse.c | 2 +- cl_particles.c | 20 +-- cl_screen.c | 73 +++++---- cl_video.c | 17 ++- clvm_cmds.c | 2 +- csprogs.c | 4 +- gl_draw.c | 46 +++--- gl_rmain.c | 214 +++++++++++++------------- gl_rsurf.c | 21 +-- gl_textures.c | 33 ++-- image.c | 398 ++++++++++++++++++------------------------------- image.h | 24 ++- image_png.c | 7 +- image_png.h | 2 +- jpeg.c | 32 ++-- jpeg.h | 2 +- menu.c | 78 +++++----- model_alias.c | 2 +- model_brush.c | 63 ++++---- model_shared.c | 18 +-- model_sprite.c | 65 ++++---- palette.c | 174 +++++++++------------ palette.h | 30 ++-- r_explosion.c | 8 +- r_light.c | 2 +- r_lightning.c | 106 ++++++------- r_shadow.c | 31 ++-- r_sky.c | 16 +- r_textures.h | 24 +-- render.h | 3 +- sbar.c | 18 +-- wad.c | 10 +- wad.h | 6 +- 34 files changed, 713 insertions(+), 848 deletions(-) diff --git a/cl_main.c b/cl_main.c index 2bf63aba..a0b5f09d 100644 --- a/cl_main.c +++ b/cl_main.c @@ -864,11 +864,11 @@ void CL_UpdateNetworkEntity(entity_t *e, int recursionlimit, qboolean interpolat { unsigned char *cbcolor; e->render.colormap = e->state_current.colormap; - cbcolor = (unsigned char *) (&palette_pantscolormap[e->render.colormap & 0xF]); + cbcolor = palette_rgb_pantscolormap[e->render.colormap & 0xF]; e->render.colormap_pantscolor[0] = cbcolor[0] * (1.0f / 255.0f); e->render.colormap_pantscolor[1] = cbcolor[1] * (1.0f / 255.0f); e->render.colormap_pantscolor[2] = cbcolor[2] * (1.0f / 255.0f); - cbcolor = (unsigned char *) (&palette_shirtcolormap[(e->render.colormap & 0xF0) >> 4]); + cbcolor = palette_rgb_shirtcolormap[(e->render.colormap & 0xF0) >> 4]; e->render.colormap_shirtcolor[0] = cbcolor[0] * (1.0f / 255.0f); e->render.colormap_shirtcolor[1] = cbcolor[1] * (1.0f / 255.0f); e->render.colormap_shirtcolor[2] = cbcolor[2] * (1.0f / 255.0f); @@ -877,11 +877,11 @@ void CL_UpdateNetworkEntity(entity_t *e, int recursionlimit, qboolean interpolat { unsigned char *cbcolor; e->render.colormap = cl.scores[e->state_current.colormap - 1].colors; // color it - cbcolor = (unsigned char *) (&palette_pantscolormap[e->render.colormap & 0xF]); + cbcolor = palette_rgb_pantscolormap[e->render.colormap & 0xF]; e->render.colormap_pantscolor[0] = cbcolor[0] * (1.0f / 255.0f); e->render.colormap_pantscolor[1] = cbcolor[1] * (1.0f / 255.0f); e->render.colormap_pantscolor[2] = cbcolor[2] * (1.0f / 255.0f); - cbcolor = (unsigned char *) (&palette_shirtcolormap[(e->render.colormap & 0xF0) >> 4]); + cbcolor = palette_rgb_shirtcolormap[(e->render.colormap & 0xF0) >> 4]; e->render.colormap_shirtcolor[0] = cbcolor[0] * (1.0f / 255.0f); e->render.colormap_shirtcolor[1] = cbcolor[1] * (1.0f / 255.0f); e->render.colormap_shirtcolor[2] = cbcolor[2] * (1.0f / 255.0f); @@ -1393,7 +1393,7 @@ void CL_LinkNetworkEntity(entity_t *e) // * 4 for the expansion from 0-255 to 0-1023 range, // / 255 to scale down byte colors dlightradius = max(dlightradius, e->state_current.glowsize * 4); - VectorMA(dlightcolor, (1.0f / 255.0f), (unsigned char *)&palette_complete[e->state_current.glowcolor], dlightcolor); + VectorMA(dlightcolor, (1.0f / 255.0f), palette_rgb[e->state_current.glowcolor], dlightcolor); } // make the glow dlight if (dlightradius > 0 && (dlightcolor[0] || dlightcolor[1] || dlightcolor[2]) && !(e->render.flags & RENDER_VIEWMODEL) && r_refdef.numlights < MAX_DLIGHTS) diff --git a/cl_parse.c b/cl_parse.c index 2a906d35..9c541155 100644 --- a/cl_parse.c +++ b/cl_parse.c @@ -2515,7 +2515,7 @@ void CL_ParseTempEntity(void) colorStart = MSG_ReadByte(); colorLength = MSG_ReadByte(); CL_ParticleExplosion2(pos, colorStart, colorLength); - tempcolor = (unsigned char *)&palette_complete[(rand()%colorLength) + colorStart]; + tempcolor = palette_rgb[(rand()%colorLength) + colorStart]; color[0] = tempcolor[0] * (2.0f / 255.0f); color[1] = tempcolor[1] * (2.0f / 255.0f); color[2] = tempcolor[2] * (2.0f / 255.0f); diff --git a/cl_particles.c b/cl_particles.c index 29e68637..a12e6844 100644 --- a/cl_particles.c +++ b/cl_particles.c @@ -1904,9 +1904,9 @@ void particletextureblotch(unsigned char *data, float radius, float red, float g if (f > 1) f = 1; d = data + (y * PARTICLETEXTURESIZE + x) * 4; - d[0] += (int)(f * (red - d[0])); + d[0] += (int)(f * (blue - d[0])); d[1] += (int)(f * (green - d[1])); - d[2] += (int)(f * (blue - d[2])); + d[2] += (int)(f * (red - d[2])); } } } @@ -1917,9 +1917,9 @@ void particletextureclamp(unsigned char *data, int minr, int ming, int minb, int int i; for (i = 0;i < PARTICLETEXTURESIZE*PARTICLETEXTURESIZE;i++, data += 4) { - data[0] = bound(minr, data[0], maxr); + data[0] = bound(minb, data[0], maxb); data[1] = bound(ming, data[1], maxg); - data[2] = bound(minb, data[2], maxb); + data[2] = bound(minr, data[2], maxr); } } @@ -1985,7 +1985,7 @@ static void R_InitParticleTexture (void) // we invert it again during the blendfunc to make it work... #ifndef DUMPPARTICLEFONT - particlefonttexture = loadtextureimage(particletexturepool, "particles/particlefont.tga", 0, 0, false, TEXF_ALPHA | TEXF_PRECACHE, true); + particlefonttexture = loadtextureimage(particletexturepool, "particles/particlefont.tga", false, TEXF_ALPHA | TEXF_PRECACHE, true); if (!particlefonttexture) #endif { @@ -2109,10 +2109,10 @@ static void R_InitParticleTexture (void) } #ifdef DUMPPARTICLEFONT - Image_WriteTGARGBA ("particles/particlefont.tga", PARTICLEFONTSIZE, PARTICLEFONTSIZE, particletexturedata); + Image_WriteTGABGRA ("particles/particlefont.tga", PARTICLEFONTSIZE, PARTICLEFONTSIZE, particletexturedata); #endif - particlefonttexture = R_LoadTexture2D(particletexturepool, "particlefont", PARTICLEFONTSIZE, PARTICLEFONTSIZE, particletexturedata, TEXTYPE_RGBA, TEXF_ALPHA | TEXF_PRECACHE, NULL); + particlefonttexture = R_LoadTexture2D(particletexturepool, "particlefont", PARTICLEFONTSIZE, PARTICLEFONTSIZE, particletexturedata, TEXTYPE_BGRA, TEXF_ALPHA | TEXF_PRECACHE, NULL); Mem_Free(particletexturedata); } @@ -2128,7 +2128,7 @@ static void R_InitParticleTexture (void) } #ifndef DUMPPARTICLEFONT - particletexture[tex_beam].texture = loadtextureimage(particletexturepool, "particles/nexbeam.tga", 0, 0, false, TEXF_ALPHA | TEXF_PRECACHE, true); + particletexture[tex_beam].texture = loadtextureimage(particletexturepool, "particles/nexbeam.tga", false, TEXF_ALPHA | TEXF_PRECACHE, true); if (!particletexture[tex_beam].texture) #endif { @@ -2149,9 +2149,9 @@ static void R_InitParticleTexture (void) } #ifdef DUMPPARTICLEFONT - Image_WriteTGARGBA ("particles/nexbeam.tga", 64, 64, &data2[0][0][0]); + Image_WriteTGABGRA ("particles/nexbeam.tga", 64, 64, &data2[0][0][0]); #endif - particletexture[tex_beam].texture = R_LoadTexture2D(particletexturepool, "nexbeam", 16, 64, &data2[0][0][0], TEXTYPE_RGBA, TEXF_PRECACHE, NULL); + particletexture[tex_beam].texture = R_LoadTexture2D(particletexturepool, "nexbeam", 16, 64, &data2[0][0][0], TEXTYPE_BGRA, TEXF_PRECACHE, NULL); } particletexture[tex_beam].s1 = 0; particletexture[tex_beam].t1 = 0; diff --git a/cl_screen.c b/cl_screen.c index 55603fe6..09f56f8a 100644 --- a/cl_screen.c +++ b/cl_screen.c @@ -1123,8 +1123,8 @@ void SCR_CaptureVideo_BeginVideo(void) cls.capturevideo.frame = 0; cls.capturevideo.soundsampleframe = 0; cls.capturevideo.realtime = cl_capturevideo_realtime.integer != 0; - cls.capturevideo.screenbuffer = (unsigned char *)Mem_Alloc(tempmempool, vid.width * vid.height * 3); - cls.capturevideo.outbuffer = (unsigned char *)Mem_Alloc(tempmempool, width * height * (3+3+3) + 18); + cls.capturevideo.screenbuffer = (unsigned char *)Mem_Alloc(tempmempool, vid.width * vid.height * 4); + cls.capturevideo.outbuffer = (unsigned char *)Mem_Alloc(tempmempool, width * height * (4+4) + 18); gamma = 1.0/scr_screenshot_gammaboost.value; dpsnprintf(cls.capturevideo.basename, sizeof(cls.capturevideo.basename), "video/dpvideo%03i", cl_capturevideo_number.integer); Cvar_SetValueQuick(&cl_capturevideo_number, cl_capturevideo_number.integer + 1); @@ -1426,50 +1426,43 @@ void SCR_CaptureVideo_EndVideo(void) memset(&cls.capturevideo, 0, sizeof(cls.capturevideo)); } -// converts from RGB24 to I420 colorspace (identical to YV12 except chroma plane order is reversed), this colorspace is handled by the Intel(r) 4:2:0 codec on Windows -void SCR_CaptureVideo_ConvertFrame_RGB_to_I420_flip(int width, int height, unsigned char *instart, unsigned char *outstart) +// converts from BGRA32 to I420 colorspace (identical to YV12 except chroma plane order is reversed), this colorspace is handled by the Intel(r) 4:2:0 codec on Windows +void SCR_CaptureVideo_ConvertFrame_BGRA_to_I420_flip(int width, int height, unsigned char *instart, unsigned char *outstart) { int x, y; + int blockr, blockg, blockb; int outoffset = (width/2)*(height/2); unsigned char *b, *out; // process one line at a time, and CbCr every other line at 2 pixel intervals for (y = 0;y < height;y++) { // 1x1 Y - for (b = instart + (height-1-y)*width*3, out = outstart + y*width, x = 0;x < width;x++, b += 3, out++) - *out = cls.capturevideo.yuvnormalizetable[0][cls.capturevideo.rgbtoyuvscaletable[0][0][b[0]] + cls.capturevideo.rgbtoyuvscaletable[0][1][b[1]] + cls.capturevideo.rgbtoyuvscaletable[0][2][b[2]]]; + for (b = instart + (height-1-y)*width*4, out = outstart + y*width, x = 0;x < width;x++, b += 4, out++) + { + blockr = b[2]; + blockg = b[1]; + blockb = b[0]; + *out = cls.capturevideo.yuvnormalizetable[0][cls.capturevideo.rgbtoyuvscaletable[0][0][blockr] + cls.capturevideo.rgbtoyuvscaletable[0][1][blockg] + cls.capturevideo.rgbtoyuvscaletable[0][2][blockb]]; + } if ((y & 1) == 0) { // 2x2 Cr and Cb planes -#if 0 - // low quality, no averaging - for (b = instart + (height-2-y)*width*3, out = outstart + width*height + (y/2)*(width/2), x = 0;x < width/2;x++, b += 6, out++) - { - // Cr - out[0 ] = cls.capturevideo.yuvnormalizetable[1][cls.capturevideo.rgbtoyuvscaletable[1][0][b[0]] + cls.capturevideo.rgbtoyuvscaletable[1][1][b[1]] + cls.capturevideo.rgbtoyuvscaletable[1][2][b[2]] + 128]; - // Cb - out[outoffset] = cls.capturevideo.yuvnormalizetable[2][cls.capturevideo.rgbtoyuvscaletable[2][0][b[0]] + cls.capturevideo.rgbtoyuvscaletable[2][1][b[1]] + cls.capturevideo.rgbtoyuvscaletable[2][2][b[2]] + 128]; - } -#else - // high quality, averaging - int inpitch = width*3; - for (b = instart + (height-2-y)*width*3, out = outstart + width*height + (y/2)*(width/2), x = 0;x < width/2;x++, b += 6, out++) + int inpitch = width*4; + for (b = instart + (height-2-y)*width*4, out = outstart + width*height + (y/2)*(width/2), x = 0;x < width/2;x++, b += 8, out++) { - int blockr, blockg, blockb; - blockr = (b[0] + b[3] + b[inpitch+0] + b[inpitch+3]) >> 2; - blockg = (b[1] + b[4] + b[inpitch+1] + b[inpitch+4]) >> 2; - blockb = (b[2] + b[5] + b[inpitch+2] + b[inpitch+5]) >> 2; + blockr = (b[2] + b[6] + b[inpitch+2] + b[inpitch+6]) >> 2; + blockg = (b[1] + b[5] + b[inpitch+1] + b[inpitch+5]) >> 2; + blockb = (b[0] + b[4] + b[inpitch+0] + b[inpitch+4]) >> 2; // Cr out[0 ] = cls.capturevideo.yuvnormalizetable[1][cls.capturevideo.rgbtoyuvscaletable[1][0][blockr] + cls.capturevideo.rgbtoyuvscaletable[1][1][blockg] + cls.capturevideo.rgbtoyuvscaletable[1][2][blockb] + 128]; // Cb out[outoffset] = cls.capturevideo.yuvnormalizetable[2][cls.capturevideo.rgbtoyuvscaletable[2][0][blockr] + cls.capturevideo.rgbtoyuvscaletable[2][1][blockg] + cls.capturevideo.rgbtoyuvscaletable[2][2][blockb] + 128]; } -#endif } } } -static void SCR_ScaleDown(unsigned char *in, int inw, int inh, unsigned char *out, int outw, int outh) +static void SCR_ScaleDownBGRA(unsigned char *in, int inw, int inh, unsigned char *out, int outw, int outh) { // TODO optimize this function @@ -1479,7 +1472,7 @@ static void SCR_ScaleDown(unsigned char *in, int inw, int inh, unsigned char *ou // memcpy is faster than me if(inw == outw && inh == outh) { - memcpy(out, in, 3 * inw * inh); + memcpy(out, in, 4 * inw * inh); return; } @@ -1493,7 +1486,7 @@ static void SCR_ScaleDown(unsigned char *in, int inw, int inh, unsigned char *ou { float inx0 = x / (float)outw * inw; int inx0_i = floor(inx0); float inx1 = (x+1) / (float)outw * inw; int inx1_i = ceil(inx1); - float r = 0, g = 0, b = 0; + float r = 0, g = 0, b = 0, alpha = 0; int xx, yy; for(yy = iny0_i; yy < iny1_i; ++yy) @@ -1502,15 +1495,17 @@ static void SCR_ScaleDown(unsigned char *in, int inw, int inh, unsigned char *ou for(xx = inx0_i; xx < inx1_i; ++xx) { float a = ya * (min(xx+1, inx1) - max(inx0, xx)); - r += a * in[3*(xx + inw * yy)+0]; - g += a * in[3*(xx + inw * yy)+1]; - b += a * in[3*(xx + inw * yy)+2]; + r += a * in[4*(xx + inw * yy)+0]; + g += a * in[4*(xx + inw * yy)+1]; + b += a * in[4*(xx + inw * yy)+2]; + alpha += a * in[4*(xx + inw * yy)+3]; } } - out[3*(x + outw * y)+0] = r * area; - out[3*(x + outw * y)+1] = g * area; - out[3*(x + outw * y)+2] = b * area; + out[4*(x + outw * y)+0] = r * area; + out[4*(x + outw * y)+1] = g * area; + out[4*(x + outw * y)+2] = b * area; + out[4*(x + outw * y)+3] = alpha * area; } } } @@ -1529,11 +1524,11 @@ qboolean SCR_CaptureVideo_VideoFrame(int newframenum) if (!cls.capturevideo.videofile) return false; // FIXME: width/height must be multiple of 2, enforce this? - qglReadPixels (x, y, vid.width, vid.height, GL_RGB, GL_UNSIGNED_BYTE, cls.capturevideo.screenbuffer);CHECKGLERROR - SCR_ScaleDown (cls.capturevideo.screenbuffer, vid.width, vid.height, cls.capturevideo.outbuffer, width, height); + qglReadPixels (x, y, vid.width, vid.height, GL_BGRA, GL_UNSIGNED_BYTE, cls.capturevideo.screenbuffer);CHECKGLERROR + SCR_ScaleDownBGRA (cls.capturevideo.screenbuffer, vid.width, vid.height, cls.capturevideo.outbuffer, width, height); in = cls.capturevideo.outbuffer; - out = cls.capturevideo.outbuffer + width*height*3; - SCR_CaptureVideo_ConvertFrame_RGB_to_I420_flip(width, height, in, out); + out = cls.capturevideo.outbuffer + width*height*4; + SCR_CaptureVideo_ConvertFrame_BGRA_to_I420_flip(width, height, in, out); x = width*height+(width/2)*(height/2)*2; SCR_CaptureVideo_RIFF_OverflowCheck(8 + x); for (;cls.capturevideo.frame < newframenum;cls.capturevideo.frame++) @@ -1788,7 +1783,7 @@ qboolean SCR_ScreenShot(char *filename, unsigned char *buffer1, unsigned char *b return false; CHECKGLERROR - qglReadPixels (x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, buffer1);CHECKGLERROR + qglReadPixels (x, y, width, height, jpeg ? GL_RGB : GL_BGR, GL_UNSIGNED_BYTE, buffer1);CHECKGLERROR if (scr_screenshot_gammaboost.value != 1 && gammacorrect) { @@ -1806,7 +1801,7 @@ qboolean SCR_ScreenShot(char *filename, unsigned char *buffer1, unsigned char *b if (jpeg) ret = JPEG_SaveImage_preflipped (filename, width, height, buffer2); else - ret = Image_WriteTGARGB_preflipped (filename, width, height, buffer2, buffer3); + ret = Image_WriteTGABGR_preflipped (filename, width, height, buffer2, buffer3); return ret; } diff --git a/cl_video.c b/cl_video.c index 9c753de2..2bfc51cf 100644 --- a/cl_video.c +++ b/cl_video.c @@ -42,7 +42,7 @@ static void VideoUpdateCallback(rtexture_t *rt, void *data) { static void LinkVideoTexture( clvideo_t *video ) { video->cpif.tex = R_LoadTexture2D( cl_videotexturepool, video->cpif.name, - video->cpif.width, video->cpif.height, NULL, TEXTYPE_RGBA, TEXF_ALWAYSPRECACHE, NULL ); + video->cpif.width, video->cpif.height, NULL, TEXTYPE_BGRA, TEXF_ALWAYSPRECACHE, NULL ); R_MakeTextureDynamic( video->cpif.tex, VideoUpdateCallback, video ); CL_LinkDynTexture( video->cpif.name, video->cpif.tex ); } @@ -361,11 +361,20 @@ static void cl_video_newmap( void ) void CL_Video_Init( void ) { + union + { + unsigned char b[4]; + unsigned int i; + } + bgra; + cl_num_videos = 0; cl_videobytesperpixel = 4; - cl_videormask = BigLong(0xFF000000); - cl_videogmask = BigLong(0x00FF0000); - cl_videobmask = BigLong(0x0000FF00); + + // set masks in an endian-independent way (as they really represent bytes) + bgra.i = 0;bgra.b[0] = 0xFF;cl_videobmask = bgra.i; + bgra.i = 0;bgra.b[1] = 0xFF;cl_videogmask = bgra.i; + bgra.i = 0;bgra.b[2] = 0xFF;cl_videormask = bgra.i; Cmd_AddCommand( "playvideo", CL_PlayVideo_f, "play a .dpv video file" ); Cmd_AddCommand( "stopvideo", CL_StopVideo_f, "stop playing a .dpv video file" ); diff --git a/clvm_cmds.c b/clvm_cmds.c index 8a111161..11178bfa 100644 --- a/clvm_cmds.c +++ b/clvm_cmds.c @@ -1654,7 +1654,7 @@ static void VM_CL_te_explosion2 (void) colorLength = (int)PRVM_G_FLOAT(OFS_PARM2); CL_FindNonSolidLocation(pos, pos2, 10); CL_ParticleExplosion2(pos2, colorStart, colorLength); - tempcolor = (unsigned char *)&palette_complete[(rand()%colorLength) + colorStart]; + tempcolor = palette_rgb[(rand()%colorLength) + colorStart]; color[0] = tempcolor[0] * (2.0f / 255.0f); color[1] = tempcolor[1] * (2.0f / 255.0f); color[2] = tempcolor[2] * (2.0f / 255.0f); diff --git a/csprogs.c b/csprogs.c index 6a0bf4c8..5b803276 100644 --- a/csprogs.c +++ b/csprogs.c @@ -214,11 +214,11 @@ qboolean CSQC_AddRenderEdict(prvm_edict_t *ed) else palcol = cl.scores[e->render.colormap-1].colors; - cbcolor = (unsigned char *) (&palette_pantscolormap[palcol & 0xF]); + cbcolor = palette_rgb_pantscolormap[palcol & 0xF]; e->render.colormap_pantscolor[0] = cbcolor[0] * (1.0f / 255.0f); e->render.colormap_pantscolor[1] = cbcolor[1] * (1.0f / 255.0f); e->render.colormap_pantscolor[2] = cbcolor[2] * (1.0f / 255.0f); - cbcolor = (unsigned char *) (&palette_shirtcolormap[(palcol & 0xF0) >> 4]); + cbcolor = palette_rgb_shirtcolormap[(palcol & 0xF0) >> 4]; e->render.colormap_shirtcolor[0] = cbcolor[0] * (1.0f / 255.0f); e->render.colormap_shirtcolor[1] = cbcolor[1] * (1.0f / 255.0f); e->render.colormap_shirtcolor[2] = cbcolor[2] * (1.0f / 255.0f); diff --git a/gl_draw.c b/gl_draw.c index 28239082..ad8e8ef7 100644 --- a/gl_draw.c +++ b/gl_draw.c @@ -54,50 +54,50 @@ static rtexture_t *draw_generateconchars(void) unsigned char buffer[65536][4], *data = NULL; double random; - data = LoadTGA (concharimage, FONT_FILESIZE, 256, 256); + data = LoadTGA_BGRA (concharimage, FONT_FILESIZE); // Gold numbers for (i = 0;i < 8192;i++) { random = lhrandom (0.0,1.0); - buffer[i][0] = 83 + (unsigned char)(random * 64); + buffer[i][2] = 83 + (unsigned char)(random * 64); buffer[i][1] = 71 + (unsigned char)(random * 32); - buffer[i][2] = 23 + (unsigned char)(random * 16); + buffer[i][0] = 23 + (unsigned char)(random * 16); buffer[i][3] = data[i*4+0]; } // White chars for (i = 8192;i < 32768;i++) { random = lhrandom (0.0,1.0); - buffer[i][0] = 95 + (unsigned char)(random * 64); - buffer[i][1] = 95 + (unsigned char)(random * 64); buffer[i][2] = 95 + (unsigned char)(random * 64); + buffer[i][1] = 95 + (unsigned char)(random * 64); + buffer[i][0] = 95 + (unsigned char)(random * 64); buffer[i][3] = data[i*4+0]; } // Gold numbers for (i = 32768;i < 40960;i++) { random = lhrandom (0.0,1.0); - buffer[i][0] = 83 + (unsigned char)(random * 64); + buffer[i][2] = 83 + (unsigned char)(random * 64); buffer[i][1] = 71 + (unsigned char)(random * 32); - buffer[i][2] = 23 + (unsigned char)(random * 16); + buffer[i][0] = 23 + (unsigned char)(random * 16); buffer[i][3] = data[i*4+0]; } // Red chars for (i = 40960;i < 65536;i++) { random = lhrandom (0.0,1.0); - buffer[i][0] = 96 + (unsigned char)(random * 64); + buffer[i][2] = 96 + (unsigned char)(random * 64); buffer[i][1] = 43 + (unsigned char)(random * 32); - buffer[i][2] = 27 + (unsigned char)(random * 32); + buffer[i][0] = 27 + (unsigned char)(random * 32); buffer[i][3] = data[i*4+0]; } #if 0 - Image_WriteTGARGBA ("gfx/generated_conchars.tga", 256, 256, &buffer[0][0]); + Image_WriteTGABGRA ("gfx/generated_conchars.tga", 256, 256, &buffer[0][0]); #endif Mem_Free(data); - return R_LoadTexture2D(drawtexturepool, "conchars", 256, 256, &buffer[0][0], TEXTYPE_RGBA, TEXF_ALPHA | TEXF_PRECACHE, NULL); + return R_LoadTexture2D(drawtexturepool, "conchars", 256, 256, &buffer[0][0], TEXTYPE_BGRA, TEXF_ALPHA | TEXF_PRECACHE, NULL); } static char *pointerimage = @@ -140,7 +140,7 @@ static rtexture_t *draw_generatemousepointer(void) buffer[i][3] = 255; } } - return R_LoadTexture2D(drawtexturepool, "mousepointer", 16, 16, &buffer[0][0], TEXTYPE_RGBA, TEXF_ALPHA | TEXF_PRECACHE, NULL); + return R_LoadTexture2D(drawtexturepool, "mousepointer", 16, 16, &buffer[0][0], TEXTYPE_BGRA, TEXF_ALPHA | TEXF_PRECACHE, NULL); } static char *crosshairtexdata[NUMCROSSHAIRS] = @@ -269,7 +269,7 @@ static rtexture_t *draw_generatecrosshair(int num) data[i][3] = 255; } } - return R_LoadTexture2D(drawtexturepool, va("crosshair%i", num+1), 16, 16, &data[0][0], TEXTYPE_RGBA, TEXF_ALPHA | TEXF_PRECACHE, NULL); + return R_LoadTexture2D(drawtexturepool, va("crosshair%i", num+1), 16, 16, &data[0][0], TEXTYPE_BGRA, TEXF_ALPHA | TEXF_PRECACHE, NULL); } static rtexture_t *draw_generateditherpattern(void) @@ -285,12 +285,12 @@ static rtexture_t *draw_generateditherpattern(void) data[(y*8+x)*4+3] = 255; } } - return R_LoadTexture2D(drawtexturepool, "ditherpattern", 8, 8, data, TEXTYPE_RGBA, TEXF_FORCENEAREST | TEXF_PRECACHE, NULL); + return R_LoadTexture2D(drawtexturepool, "ditherpattern", 8, 8, data, TEXTYPE_BGRA, TEXF_FORCENEAREST | TEXF_PRECACHE, NULL); #else unsigned char data[16]; memset(data, 255, sizeof(data)); data[0] = data[1] = data[2] = data[12] = data[13] = data[14] = 0; - return R_LoadTexture2D(drawtexturepool, "ditherpattern", 2, 2, data, TEXTYPE_RGBA, TEXF_FORCENEAREST | TEXF_PRECACHE, NULL); + return R_LoadTexture2D(drawtexturepool, "ditherpattern", 2, 2, data, TEXTYPE_BGRA, TEXF_FORCENEAREST | TEXF_PRECACHE, NULL); #endif } @@ -345,11 +345,11 @@ cachepic_t *Draw_CachePic (const char *path, qboolean persistent) flags |= TEXF_CLAMP; // load a high quality image from disk if possible - pic->tex = loadtextureimage(drawtexturepool, path, 0, 0, false, flags | (gl_texturecompression_2d.integer ? TEXF_COMPRESS : 0), true); + pic->tex = loadtextureimage(drawtexturepool, path, false, flags | (gl_texturecompression_2d.integer ? TEXF_COMPRESS : 0), true); if (pic->tex == NULL && !strncmp(path, "gfx/", 4)) { // compatibility with older versions which did not require gfx/ prefix - pic->tex = loadtextureimage(drawtexturepool, path + 4, 0, 0, false, flags | (gl_texturecompression_2d.integer ? TEXF_COMPRESS : 0), true); + pic->tex = loadtextureimage(drawtexturepool, path + 4, false, flags | (gl_texturecompression_2d.integer ? TEXF_COMPRESS : 0), true); } // if a high quality image was loaded, set the pic's size to match it, just // in case there's no low quality version to get the size from @@ -372,7 +372,7 @@ cachepic_t *Draw_CachePic (const char *path, qboolean persistent) pic->height = lmpdata[4] + lmpdata[5] * 256 + lmpdata[6] * 65536 + lmpdata[7] * 16777216; // if no high quality replacement image was found, upload the original low quality texture if (!pic->tex) - pic->tex = R_LoadTexture2D(drawtexturepool, path, pic->width, pic->height, lmpdata + 8, TEXTYPE_PALETTE, flags, palette_transparent); + pic->tex = R_LoadTexture2D(drawtexturepool, path, pic->width, pic->height, lmpdata + 8, TEXTYPE_PALETTE, flags, palette_bgra_transparent); } Mem_Free(lmpdata); } @@ -385,7 +385,7 @@ cachepic_t *Draw_CachePic (const char *path, qboolean persistent) pic->height = 128; // if no high quality replacement image was found, upload the original low quality texture if (!pic->tex) - pic->tex = R_LoadTexture2D(drawtexturepool, path, 128, 128, lmpdata, TEXTYPE_PALETTE, flags, palette_font); + pic->tex = R_LoadTexture2D(drawtexturepool, path, 128, 128, lmpdata, TEXTYPE_PALETTE, flags, palette_bgra_font); } else { @@ -393,7 +393,7 @@ cachepic_t *Draw_CachePic (const char *path, qboolean persistent) pic->height = lmpdata[4] + lmpdata[5] * 256 + lmpdata[6] * 65536 + lmpdata[7] * 16777216; // if no high quality replacement image was found, upload the original low quality texture if (!pic->tex) - pic->tex = R_LoadTexture2D(drawtexturepool, path, pic->width, pic->height, lmpdata + 8, TEXTYPE_PALETTE, flags, palette_transparent); + pic->tex = R_LoadTexture2D(drawtexturepool, path, pic->width, pic->height, lmpdata + 8, TEXTYPE_PALETTE, flags, palette_bgra_transparent); } } @@ -434,7 +434,7 @@ cachepic_t *Draw_CachePic (const char *path, qboolean persistent) return pic; } -cachepic_t *Draw_NewPic(const char *picname, int width, int height, int alpha, unsigned char *pixels) +cachepic_t *Draw_NewPic(const char *picname, int width, int height, int alpha, unsigned char *pixels_bgra) { int crc, hashkey; cachepic_t *pic; @@ -449,7 +449,7 @@ cachepic_t *Draw_NewPic(const char *picname, int width, int height, int alpha, u { if (pic->tex && pic->width == width && pic->height == height) { - R_UpdateTexture(pic->tex, pixels, 0, 0, width, height); + R_UpdateTexture(pic->tex, pixels_bgra, 0, 0, width, height); return pic; } } @@ -475,7 +475,7 @@ cachepic_t *Draw_NewPic(const char *picname, int width, int height, int alpha, u pic->height = height; if (pic->tex) R_FreeTexture(pic->tex); - pic->tex = R_LoadTexture2D(drawtexturepool, picname, width, height, pixels, TEXTYPE_RGBA, alpha ? TEXF_ALPHA : 0, NULL); + pic->tex = R_LoadTexture2D(drawtexturepool, picname, width, height, pixels_bgra, TEXTYPE_BGRA, alpha ? TEXF_ALPHA : 0, NULL); return pic; } diff --git a/gl_rmain.c b/gl_rmain.c index b36e648f..2755fd51 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -263,26 +263,26 @@ float FogPoint_Model(const vec3_t p) static void R_BuildBlankTextures(void) { unsigned char data[4]; - data[0] = 128; // normal X + data[2] = 128; // normal X data[1] = 128; // normal Y - data[2] = 255; // normal Z + data[0] = 255; // normal Z data[3] = 128; // height - r_texture_blanknormalmap = R_LoadTexture2D(r_main_texturepool, "blankbump", 1, 1, data, TEXTYPE_RGBA, TEXF_PRECACHE, NULL); + r_texture_blanknormalmap = R_LoadTexture2D(r_main_texturepool, "blankbump", 1, 1, data, TEXTYPE_BGRA, TEXF_PRECACHE, NULL); data[0] = 255; data[1] = 255; data[2] = 255; data[3] = 255; - r_texture_white = R_LoadTexture2D(r_main_texturepool, "blankwhite", 1, 1, data, TEXTYPE_RGBA, TEXF_PRECACHE, NULL); + r_texture_white = R_LoadTexture2D(r_main_texturepool, "blankwhite", 1, 1, data, TEXTYPE_BGRA, TEXF_PRECACHE, NULL); data[0] = 128; data[1] = 128; data[2] = 128; data[3] = 255; - r_texture_grey128 = R_LoadTexture2D(r_main_texturepool, "blankgrey128", 1, 1, data, TEXTYPE_RGBA, TEXF_PRECACHE, NULL); + r_texture_grey128 = R_LoadTexture2D(r_main_texturepool, "blankgrey128", 1, 1, data, TEXTYPE_BGRA, TEXF_PRECACHE, NULL); data[0] = 0; data[1] = 0; data[2] = 0; data[3] = 255; - r_texture_black = R_LoadTexture2D(r_main_texturepool, "blankblack", 1, 1, data, TEXTYPE_RGBA, TEXF_PRECACHE, NULL); + r_texture_black = R_LoadTexture2D(r_main_texturepool, "blankblack", 1, 1, data, TEXTYPE_BGRA, TEXF_PRECACHE, NULL); } static void R_BuildNoTexture(void) @@ -310,19 +310,14 @@ static void R_BuildNoTexture(void) } } } - r_texture_notexture = R_LoadTexture2D(r_main_texturepool, "notexture", 16, 16, &pix[0][0][0], TEXTYPE_RGBA, TEXF_MIPMAP, NULL); + r_texture_notexture = R_LoadTexture2D(r_main_texturepool, "notexture", 16, 16, &pix[0][0][0], TEXTYPE_BGRA, TEXF_MIPMAP, NULL); } static void R_BuildWhiteCube(void) { unsigned char data[6*1*1*4]; - data[ 0] = 255;data[ 1] = 255;data[ 2] = 255;data[ 3] = 255; - data[ 4] = 255;data[ 5] = 255;data[ 6] = 255;data[ 7] = 255; - data[ 8] = 255;data[ 9] = 255;data[10] = 255;data[11] = 255; - data[12] = 255;data[13] = 255;data[14] = 255;data[15] = 255; - data[16] = 255;data[17] = 255;data[18] = 255;data[19] = 255; - data[20] = 255;data[21] = 255;data[22] = 255;data[23] = 255; - r_texture_whitecube = R_LoadTextureCubeMap(r_main_texturepool, "whitecube", 1, data, TEXTYPE_RGBA, TEXF_PRECACHE | TEXF_CLAMP, NULL); + memset(data, 255, sizeof(data)); + r_texture_whitecube = R_LoadTextureCubeMap(r_main_texturepool, "whitecube", 1, data, TEXTYPE_BGRA, TEXF_PRECACHE | TEXF_CLAMP, NULL); } static void R_BuildNormalizationCube(void) @@ -375,14 +370,14 @@ static void R_BuildNormalizationCube(void) break; } intensity = 127.0f / sqrt(DotProduct(v, v)); - data[side][y][x][0] = (unsigned char)(128.0f + intensity * v[0]); + data[side][y][x][2] = (unsigned char)(128.0f + intensity * v[0]); data[side][y][x][1] = (unsigned char)(128.0f + intensity * v[1]); - data[side][y][x][2] = (unsigned char)(128.0f + intensity * v[2]); + data[side][y][x][0] = (unsigned char)(128.0f + intensity * v[2]); data[side][y][x][3] = 255; } } } - r_texture_normalizationcube = R_LoadTextureCubeMap(r_main_texturepool, "normalcube", NORMSIZE, &data[0][0][0][0], TEXTYPE_RGBA, TEXF_PRECACHE | TEXF_CLAMP, NULL); + r_texture_normalizationcube = R_LoadTextureCubeMap(r_main_texturepool, "normalcube", NORMSIZE, &data[0][0][0][0], TEXTYPE_BGRA, TEXF_PRECACHE | TEXF_CLAMP, NULL); } static void R_BuildFogTexture(void) @@ -403,8 +398,8 @@ static void R_BuildFogTexture(void) //data2[x][2] = 255 - b; //data2[x][3] = 255; } - r_texture_fogattenuation = R_LoadTexture2D(r_main_texturepool, "fogattenuation", FOGWIDTH, 1, &data1[0][0], TEXTYPE_RGBA, TEXF_PRECACHE | TEXF_FORCELINEAR | TEXF_CLAMP, NULL); - //r_texture_fogintensity = R_LoadTexture2D(r_main_texturepool, "fogintensity", FOGWIDTH, 1, &data2[0][0], TEXTYPE_RGBA, TEXF_PRECACHE | TEXF_FORCELINEAR | TEXF_CLAMP, NULL); + r_texture_fogattenuation = R_LoadTexture2D(r_main_texturepool, "fogattenuation", FOGWIDTH, 1, &data1[0][0], TEXTYPE_BGRA, TEXF_PRECACHE | TEXF_FORCELINEAR | TEXF_CLAMP, NULL); + //r_texture_fogintensity = R_LoadTexture2D(r_main_texturepool, "fogintensity", FOGWIDTH, 1, &data2[0][0], TEXTYPE_BGRA, TEXF_PRECACHE | TEXF_FORCELINEAR | TEXF_CLAMP, NULL); } static const char *builtinshaderstring = @@ -1579,7 +1574,7 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole if (skinframe && skinframe->base) return skinframe; - basepixels = loadimagepixels(name, complain, 0, 0, true); + basepixels = loadimagepixelsbgra(name, complain, true); if (basepixels == NULL) return NULL; @@ -1598,7 +1593,7 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole basepixels_width = image_width; basepixels_height = image_height; - skinframe->base = R_LoadTexture2D (r_main_texturepool, skinframe->basename, basepixels_width, basepixels_height, basepixels, TEXTYPE_RGBA, skinframe->textureflags & (gl_texturecompression_color.integer ? ~0 : ~TEXF_COMPRESS), NULL); + skinframe->base = R_LoadTexture2D (r_main_texturepool, skinframe->basename, basepixels_width, basepixels_height, basepixels, TEXTYPE_BGRA, skinframe->textureflags & (gl_texturecompression_color.integer ? ~0 : ~TEXF_COMPRESS), NULL); if (textureflags & TEXF_ALPHA) { @@ -1616,7 +1611,7 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole pixels[j+2] = 255; pixels[j+3] = basepixels[j+3]; } - skinframe->fog = R_LoadTexture2D (r_main_texturepool, va("%s_mask", skinframe->basename), image_width, image_height, pixels, TEXTYPE_RGBA, skinframe->textureflags & (gl_texturecompression_color.integer ? ~0 : ~TEXF_COMPRESS), NULL); + skinframe->fog = R_LoadTexture2D (r_main_texturepool, va("%s_mask", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, skinframe->textureflags & (gl_texturecompression_color.integer ? ~0 : ~TEXF_COMPRESS), NULL); Mem_Free(pixels); } } @@ -1624,35 +1619,35 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole // _norm is the name used by tenebrae and has been adopted as standard if (loadnormalmap) { - if ((pixels = loadimagepixels(va("%s_norm", skinframe->basename), false, 0, 0, false)) != NULL) + if ((pixels = loadimagepixelsbgra(va("%s_norm", skinframe->basename), false, false)) != NULL) { - skinframe->nmap = R_LoadTexture2D (r_main_texturepool, va("%s_nmap", skinframe->basename), image_width, image_height, pixels, TEXTYPE_RGBA, skinframe->textureflags & (gl_texturecompression_normal.integer ? ~0 : ~TEXF_COMPRESS), NULL); + skinframe->nmap = R_LoadTexture2D (r_main_texturepool, va("%s_nmap", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, skinframe->textureflags & (gl_texturecompression_normal.integer ? ~0 : ~TEXF_COMPRESS), NULL); Mem_Free(pixels); pixels = NULL; } - else if (r_shadow_bumpscale_bumpmap.value > 0 && (bumppixels = loadimagepixels(va("%s_bump", skinframe->basename), false, 0, 0, false)) != NULL) + else if (r_shadow_bumpscale_bumpmap.value > 0 && (bumppixels = loadimagepixelsbgra(va("%s_bump", skinframe->basename), false, false)) != NULL) { pixels = (unsigned char *)Mem_Alloc(tempmempool, image_width * image_height * 4); - Image_HeightmapToNormalmap(bumppixels, pixels, image_width, image_height, false, r_shadow_bumpscale_bumpmap.value); - skinframe->nmap = R_LoadTexture2D (r_main_texturepool, va("%s_nmap", skinframe->basename), image_width, image_height, pixels, TEXTYPE_RGBA, skinframe->textureflags & (gl_texturecompression_normal.integer ? ~0 : ~TEXF_COMPRESS), NULL); + Image_HeightmapToNormalmap_BGRA(bumppixels, pixels, image_width, image_height, false, r_shadow_bumpscale_bumpmap.value); + skinframe->nmap = R_LoadTexture2D (r_main_texturepool, va("%s_nmap", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, skinframe->textureflags & (gl_texturecompression_normal.integer ? ~0 : ~TEXF_COMPRESS), NULL); Mem_Free(pixels); Mem_Free(bumppixels); } else if (r_shadow_bumpscale_basetexture.value > 0) { pixels = (unsigned char *)Mem_Alloc(tempmempool, basepixels_width * basepixels_height * 4); - Image_HeightmapToNormalmap(basepixels, pixels, basepixels_width, basepixels_height, false, r_shadow_bumpscale_basetexture.value); - skinframe->nmap = R_LoadTexture2D (r_main_texturepool, va("%s_nmap", skinframe->basename), basepixels_width, basepixels_height, pixels, TEXTYPE_RGBA, skinframe->textureflags & (gl_texturecompression_normal.integer ? ~0 : ~TEXF_COMPRESS), NULL); + Image_HeightmapToNormalmap_BGRA(basepixels, pixels, basepixels_width, basepixels_height, false, r_shadow_bumpscale_basetexture.value); + skinframe->nmap = R_LoadTexture2D (r_main_texturepool, va("%s_nmap", skinframe->basename), basepixels_width, basepixels_height, pixels, TEXTYPE_BGRA, skinframe->textureflags & (gl_texturecompression_normal.integer ? ~0 : ~TEXF_COMPRESS), NULL); Mem_Free(pixels); } } // _luma is supported for tenebrae compatibility // (I think it's a very stupid name, but oh well) // _glow is the preferred name - if (loadglow && ((pixels = loadimagepixels(va("%s_glow", skinframe->basename), false, 0, 0, false)) != NULL || (pixels = loadimagepixels(va("%s_luma", skinframe->basename), false, 0, 0, false)) != NULL)) {skinframe->glow = R_LoadTexture2D (r_main_texturepool, va("%s_glow", skinframe->basename), image_width, image_height, pixels, TEXTYPE_RGBA, skinframe->textureflags & (gl_texturecompression_glow.integer ? ~0 : ~TEXF_COMPRESS), NULL);Mem_Free(pixels);pixels = NULL;} - if (loadgloss && (pixels = loadimagepixels(va("%s_gloss", skinframe->basename), false, 0, 0, false)) != NULL) {skinframe->gloss = R_LoadTexture2D (r_main_texturepool, va("%s_gloss", skinframe->basename), image_width, image_height, pixels, TEXTYPE_RGBA, skinframe->textureflags & (gl_texturecompression_gloss.integer ? ~0 : ~TEXF_COMPRESS), NULL);Mem_Free(pixels);pixels = NULL;} - if (loadpantsandshirt && (pixels = loadimagepixels(va("%s_pants", skinframe->basename), false, 0, 0, false)) != NULL) {skinframe->pants = R_LoadTexture2D (r_main_texturepool, va("%s_pants", skinframe->basename), image_width, image_height, pixels, TEXTYPE_RGBA, skinframe->textureflags & (gl_texturecompression_color.integer ? ~0 : ~TEXF_COMPRESS), NULL);Mem_Free(pixels);pixels = NULL;} - if (loadpantsandshirt && (pixels = loadimagepixels(va("%s_shirt", skinframe->basename), false, 0, 0, false)) != NULL) {skinframe->shirt = R_LoadTexture2D (r_main_texturepool, va("%s_shirt", skinframe->basename), image_width, image_height, pixels, TEXTYPE_RGBA, skinframe->textureflags & (gl_texturecompression_color.integer ? ~0 : ~TEXF_COMPRESS), NULL);Mem_Free(pixels);pixels = NULL;} + if (loadglow && ((pixels = loadimagepixelsbgra(va("%s_glow", skinframe->basename), false, false)) != NULL || (pixels = loadimagepixelsbgra(va("%s_luma", skinframe->basename), false, false)) != NULL)) {skinframe->glow = R_LoadTexture2D (r_main_texturepool, va("%s_glow", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, skinframe->textureflags & (gl_texturecompression_glow.integer ? ~0 : ~TEXF_COMPRESS), NULL);Mem_Free(pixels);pixels = NULL;} + if (loadgloss && (pixels = loadimagepixelsbgra(va("%s_gloss", skinframe->basename), false, false)) != NULL) {skinframe->gloss = R_LoadTexture2D (r_main_texturepool, va("%s_gloss", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, skinframe->textureflags & (gl_texturecompression_gloss.integer ? ~0 : ~TEXF_COMPRESS), NULL);Mem_Free(pixels);pixels = NULL;} + if (loadpantsandshirt && (pixels = loadimagepixelsbgra(va("%s_pants", skinframe->basename), false, false)) != NULL) {skinframe->pants = R_LoadTexture2D (r_main_texturepool, va("%s_pants", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, skinframe->textureflags & (gl_texturecompression_color.integer ? ~0 : ~TEXF_COMPRESS), NULL);Mem_Free(pixels);pixels = NULL;} + if (loadpantsandshirt && (pixels = loadimagepixelsbgra(va("%s_shirt", skinframe->basename), false, false)) != NULL) {skinframe->shirt = R_LoadTexture2D (r_main_texturepool, va("%s_shirt", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, skinframe->textureflags & (gl_texturecompression_color.integer ? ~0 : ~TEXF_COMPRESS), NULL);Mem_Free(pixels);pixels = NULL;} if (basepixels) Mem_Free(basepixels); @@ -1674,7 +1669,8 @@ static rtexture_t *R_SkinFrame_TextureForSkinLayer(const unsigned char *in, int return R_LoadTexture2D (r_main_texturepool, name, width, height, in, TEXTYPE_PALETTE, textureflags, palette); } -skinframe_t *R_SkinFrame_LoadInternal(const char *name, int textureflags, int loadpantsandshirt, int loadglowtexture, const unsigned char *skindata, int width, int height, int bitsperpixel, const unsigned int *palette, const unsigned int *alphapalette) +// this is only used by .spr32 sprites, HL .spr files, HL .bsp files +skinframe_t *R_SkinFrame_LoadInternalBGRA(const char *name, int textureflags, const unsigned char *skindata, int width, int height) { int i; unsigned char *temp1, *temp2; @@ -1684,7 +1680,7 @@ skinframe_t *R_SkinFrame_LoadInternal(const char *name, int textureflags, int lo return NULL; // if already loaded just return it, otherwise make a new skinframe - skinframe = R_SkinFrame_Find(name, textureflags, width, height, skindata ? CRC_Block(skindata, width*height*bitsperpixel/8) : 0, true); + skinframe = R_SkinFrame_Find(name, textureflags, width, height, skindata ? CRC_Block(skindata, width*height*4) : 0, true); if (skinframe && skinframe->base) return skinframe; @@ -1702,77 +1698,95 @@ skinframe_t *R_SkinFrame_LoadInternal(const char *name, int textureflags, int lo if (!skindata) return NULL; - if (bitsperpixel == 32) + if (r_shadow_bumpscale_basetexture.value > 0) { - if (r_shadow_bumpscale_basetexture.value > 0) - { - temp1 = (unsigned char *)Mem_Alloc(tempmempool, width * height * 8); - temp2 = temp1 + width * height * 4; - Image_HeightmapToNormalmap(skindata, temp2, width, height, false, r_shadow_bumpscale_basetexture.value); - skinframe->nmap = R_LoadTexture2D(r_main_texturepool, va("%s_nmap", skinframe->basename), width, height, temp2, TEXTYPE_RGBA, skinframe->textureflags | TEXF_ALPHA, NULL); - Mem_Free(temp1); - } - skinframe->base = skinframe->merged = R_LoadTexture2D(r_main_texturepool, skinframe->basename, width, height, skindata, TEXTYPE_RGBA, skinframe->textureflags, NULL); - if (textureflags & TEXF_ALPHA) - { - for (i = 3;i < width * height * 4;i += 4) - if (skindata[i] < 255) - break; - if (i < width * height * 4) - { - unsigned char *fogpixels = (unsigned char *)Mem_Alloc(tempmempool, width * height * 4); - memcpy(fogpixels, skindata, width * height * 4); - for (i = 0;i < width * height * 4;i += 4) - fogpixels[i] = fogpixels[i+1] = fogpixels[i+2] = 255; - skinframe->fog = R_LoadTexture2D(r_main_texturepool, va("%s_fog", skinframe->basename), width, height, fogpixels, TEXTYPE_RGBA, skinframe->textureflags, NULL); - Mem_Free(fogpixels); - } - } + temp1 = (unsigned char *)Mem_Alloc(tempmempool, width * height * 8); + temp2 = temp1 + width * height * 4; + Image_HeightmapToNormalmap_BGRA(skindata, temp2, width, height, false, r_shadow_bumpscale_basetexture.value); + skinframe->nmap = R_LoadTexture2D(r_main_texturepool, va("%s_nmap", skinframe->basename), width, height, temp2, TEXTYPE_BGRA, skinframe->textureflags | TEXF_ALPHA, NULL); + Mem_Free(temp1); } - else if (bitsperpixel == 8) + skinframe->base = skinframe->merged = R_LoadTexture2D(r_main_texturepool, skinframe->basename, width, height, skindata, TEXTYPE_BGRA, skinframe->textureflags, NULL); + if (textureflags & TEXF_ALPHA) { - if (r_shadow_bumpscale_basetexture.value > 0) - { - temp1 = (unsigned char *)Mem_Alloc(tempmempool, width * height * 8); - temp2 = temp1 + width * height * 4; - if (bitsperpixel == 32) - Image_HeightmapToNormalmap(skindata, temp2, width, height, false, r_shadow_bumpscale_basetexture.value); - else - { - // use either a custom palette or the quake palette - Image_Copy8bitRGBA(skindata, temp1, width * height, palette ? palette : palette_complete); - Image_HeightmapToNormalmap(temp1, temp2, width, height, false, r_shadow_bumpscale_basetexture.value); - } - skinframe->nmap = R_LoadTexture2D(r_main_texturepool, va("%s_nmap", skinframe->basename), width, height, temp2, TEXTYPE_RGBA, skinframe->textureflags | TEXF_ALPHA, NULL); - Mem_Free(temp1); - } - // use either a custom palette, or the quake palette - skinframe->base = skinframe->merged = R_SkinFrame_TextureForSkinLayer(skindata, width, height, va("%s_merged", skinframe->basename), palette ? palette : (loadglowtexture ? palette_nofullbrights : ((skinframe->textureflags & TEXF_ALPHA) ? palette_transparent : palette_complete)), skinframe->textureflags, true); // all - if (!palette && loadglowtexture) - skinframe->glow = R_SkinFrame_TextureForSkinLayer(skindata, width, height, va("%s_glow", skinframe->basename), palette_onlyfullbrights, skinframe->textureflags, false); // glow - if (!palette && loadpantsandshirt) - { - skinframe->pants = R_SkinFrame_TextureForSkinLayer(skindata, width, height, va("%s_pants", skinframe->basename), palette_pantsaswhite, skinframe->textureflags, false); // pants - skinframe->shirt = R_SkinFrame_TextureForSkinLayer(skindata, width, height, va("%s_shirt", skinframe->basename), palette_shirtaswhite, skinframe->textureflags, false); // shirt - } - if (skinframe->pants || skinframe->shirt) - skinframe->base = R_SkinFrame_TextureForSkinLayer(skindata, width, height, va("%s_nospecial", skinframe->basename),loadglowtexture ? palette_nocolormapnofullbrights : palette_nocolormap, skinframe->textureflags, false); // no special colors - if (textureflags & TEXF_ALPHA) + for (i = 3;i < width * height * 4;i += 4) + if (skindata[i] < 255) + break; + if (i < width * height * 4) { - // if not using a custom alphapalette, use the quake one - if (!alphapalette) - alphapalette = palette_alpha; - for (i = 0;i < width * height;i++) - if (((unsigned char *)alphapalette)[skindata[i]*4+3] < 255) - break; - if (i < width * height) - skinframe->fog = R_SkinFrame_TextureForSkinLayer(skindata, width, height, va("%s_fog", skinframe->basename), alphapalette, skinframe->textureflags, true); // fog mask + unsigned char *fogpixels = (unsigned char *)Mem_Alloc(tempmempool, width * height * 4); + memcpy(fogpixels, skindata, width * height * 4); + for (i = 0;i < width * height * 4;i += 4) + fogpixels[i] = fogpixels[i+1] = fogpixels[i+2] = 255; + skinframe->fog = R_LoadTexture2D(r_main_texturepool, va("%s_fog", skinframe->basename), width, height, fogpixels, TEXTYPE_BGRA, skinframe->textureflags, NULL); + Mem_Free(fogpixels); } } return skinframe; } +skinframe_t *R_SkinFrame_LoadInternalQuake(const char *name, int textureflags, int loadpantsandshirt, int loadglowtexture, const unsigned char *skindata, int width, int height) +{ + int i; + unsigned char *temp1, *temp2; + skinframe_t *skinframe; + + if (cls.state == ca_dedicated) + return NULL; + + // if already loaded just return it, otherwise make a new skinframe + skinframe = R_SkinFrame_Find(name, textureflags, width, height, skindata ? CRC_Block(skindata, width*height) : 0, true); + if (skinframe && skinframe->base) + return skinframe; + + skinframe->stain = NULL; + skinframe->merged = NULL; + skinframe->base = r_texture_notexture; + skinframe->pants = NULL; + skinframe->shirt = NULL; + skinframe->nmap = r_texture_blanknormalmap; + skinframe->gloss = NULL; + skinframe->glow = NULL; + skinframe->fog = NULL; + + // if no data was provided, then clearly the caller wanted to get a blank skinframe + if (!skindata) + return NULL; + + if (r_shadow_bumpscale_basetexture.value > 0) + { + temp1 = (unsigned char *)Mem_Alloc(tempmempool, width * height * 8); + temp2 = temp1 + width * height * 4; + // use either a custom palette or the quake palette + Image_Copy8bitBGRA(skindata, temp1, width * height, palette_bgra_complete); + Image_HeightmapToNormalmap_BGRA(temp1, temp2, width, height, false, r_shadow_bumpscale_basetexture.value); + skinframe->nmap = R_LoadTexture2D(r_main_texturepool, va("%s_nmap", skinframe->basename), width, height, temp2, TEXTYPE_BGRA, skinframe->textureflags | TEXF_ALPHA, NULL); + Mem_Free(temp1); + } + // use either a custom palette, or the quake palette + skinframe->base = skinframe->merged = R_SkinFrame_TextureForSkinLayer(skindata, width, height, va("%s_merged", skinframe->basename), (loadglowtexture ? palette_bgra_nofullbrights : ((skinframe->textureflags & TEXF_ALPHA) ? palette_bgra_transparent : palette_bgra_complete)), skinframe->textureflags, true); // all + if (loadglowtexture) + skinframe->glow = R_SkinFrame_TextureForSkinLayer(skindata, width, height, va("%s_glow", skinframe->basename), palette_bgra_onlyfullbrights, skinframe->textureflags, false); // glow + if (loadpantsandshirt) + { + skinframe->pants = R_SkinFrame_TextureForSkinLayer(skindata, width, height, va("%s_pants", skinframe->basename), palette_bgra_pantsaswhite, skinframe->textureflags, false); // pants + skinframe->shirt = R_SkinFrame_TextureForSkinLayer(skindata, width, height, va("%s_shirt", skinframe->basename), palette_bgra_shirtaswhite, skinframe->textureflags, false); // shirt + } + if (skinframe->pants || skinframe->shirt) + skinframe->base = R_SkinFrame_TextureForSkinLayer(skindata, width, height, va("%s_nospecial", skinframe->basename), loadglowtexture ? palette_bgra_nocolormapnofullbrights : palette_bgra_nocolormap, skinframe->textureflags, false); // no special colors + if (textureflags & TEXF_ALPHA) + { + for (i = 0;i < width * height;i++) + if (((unsigned char *)palette_bgra_alpha)[skindata[i]*4+3] < 255) + break; + if (i < width * height) + skinframe->fog = R_SkinFrame_TextureForSkinLayer(skindata, width, height, va("%s_fog", skinframe->basename), palette_bgra_alpha, skinframe->textureflags, true); // fog mask + } + + return skinframe; +} + skinframe_t *R_SkinFrame_LoadMissing(void) { skinframe_t *skinframe; @@ -2755,7 +2769,7 @@ static void R_Water_ProcessPlanes(void) if (p->materialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION)) { if (!p->texture_refraction) - p->texture_refraction = R_LoadTexture2D(r_main_texturepool, va("waterplane%i_refraction", planeindex), r_waterstate.texturewidth, r_waterstate.textureheight, NULL, TEXTYPE_RGBA, TEXF_FORCELINEAR | TEXF_CLAMP | TEXF_ALWAYSPRECACHE, NULL); + p->texture_refraction = R_LoadTexture2D(r_main_texturepool, va("waterplane%i_refraction", planeindex), r_waterstate.texturewidth, r_waterstate.textureheight, NULL, TEXTYPE_BGRA, TEXF_FORCELINEAR | TEXF_CLAMP | TEXF_ALWAYSPRECACHE, NULL); if (!p->texture_refraction) goto error; } @@ -2763,7 +2777,7 @@ static void R_Water_ProcessPlanes(void) if (p->materialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFLECTION)) { if (!p->texture_reflection) - p->texture_reflection = R_LoadTexture2D(r_main_texturepool, va("waterplane%i_reflection", planeindex), r_waterstate.texturewidth, r_waterstate.textureheight, NULL, TEXTYPE_RGBA, TEXF_FORCELINEAR | TEXF_CLAMP | TEXF_ALWAYSPRECACHE, NULL); + p->texture_reflection = R_LoadTexture2D(r_main_texturepool, va("waterplane%i_reflection", planeindex), r_waterstate.texturewidth, r_waterstate.textureheight, NULL, TEXTYPE_BGRA, TEXF_FORCELINEAR | TEXF_CLAMP | TEXF_ALWAYSPRECACHE, NULL); if (!p->texture_reflection) goto error; } @@ -2907,7 +2921,7 @@ void R_Bloom_StartFrame(void) r_bloomstate.screentexturewidth = screentexturewidth; r_bloomstate.screentextureheight = screentextureheight; if (r_bloomstate.screentexturewidth && r_bloomstate.screentextureheight) - r_bloomstate.texture_screen = R_LoadTexture2D(r_main_texturepool, "screen", r_bloomstate.screentexturewidth, r_bloomstate.screentextureheight, NULL, TEXTYPE_RGBA, TEXF_FORCENEAREST | TEXF_CLAMP | TEXF_ALWAYSPRECACHE, NULL); + r_bloomstate.texture_screen = R_LoadTexture2D(r_main_texturepool, "screen", r_bloomstate.screentexturewidth, r_bloomstate.screentextureheight, NULL, TEXTYPE_BGRA, TEXF_FORCENEAREST | TEXF_CLAMP | TEXF_ALWAYSPRECACHE, NULL); } if (r_bloomstate.bloomtexturewidth != bloomtexturewidth || r_bloomstate.bloomtextureheight != bloomtextureheight) { @@ -2917,7 +2931,7 @@ void R_Bloom_StartFrame(void) r_bloomstate.bloomtexturewidth = bloomtexturewidth; r_bloomstate.bloomtextureheight = bloomtextureheight; if (r_bloomstate.bloomtexturewidth && r_bloomstate.bloomtextureheight) - r_bloomstate.texture_bloom = R_LoadTexture2D(r_main_texturepool, "bloom", r_bloomstate.bloomtexturewidth, r_bloomstate.bloomtextureheight, NULL, TEXTYPE_RGBA, TEXF_FORCELINEAR | TEXF_CLAMP | TEXF_ALWAYSPRECACHE, NULL); + r_bloomstate.texture_bloom = R_LoadTexture2D(r_main_texturepool, "bloom", r_bloomstate.bloomtexturewidth, r_bloomstate.bloomtextureheight, NULL, TEXTYPE_BGRA, TEXF_FORCELINEAR | TEXF_CLAMP | TEXF_ALWAYSPRECACHE, NULL); } // set up a texcoord array for the full resolution screen image diff --git a/gl_rsurf.c b/gl_rsurf.c index 9bfa092d..fbf42ebf 100644 --- a/gl_rsurf.c +++ b/gl_rsurf.c @@ -96,12 +96,12 @@ void R_BuildLightMap (const entity_render_t *ent, msurface_t *surface) // scaling, and remaps the 0-65536 (2x overbright) to 0-256, it will // be doubled during rendering to achieve 2x overbright // (0 = 0.0, 128 = 1.0, 256 = 2.0) - for (i = 0;i < size;i++) + for (i = 0;i < size;i++, bl += 3, stain += 3, out += 4) { - l = (*bl++ * *stain++) >> 16;*out++ = min(l, 255); - l = (*bl++ * *stain++) >> 16;*out++ = min(l, 255); - l = (*bl++ * *stain++) >> 16;*out++ = min(l, 255); - *out++ = 255; + l = (bl[0] * stain[0]) >> 16;out[2] = min(l, 255); + l = (bl[1] * stain[1]) >> 16;out[1] = min(l, 255); + l = (bl[2] * stain[2]) >> 16;out[0] = min(l, 255); + out[3] = 255; } R_UpdateTexture(surface->lightmaptexture, templight, surface->lightmapinfo->lightmaporigin[0], surface->lightmapinfo->lightmaporigin[1], smax, tmax); @@ -133,14 +133,14 @@ void R_BuildLightMap (const entity_render_t *ent, msurface_t *surface) bl = intblocklights; out = templight; // we simply renormalize the weighted normals to get a valid deluxemap - for (i = 0;i < size;i++, bl += 3) + for (i = 0;i < size;i++, bl += 3, out += 4) { VectorCopy(bl, n); VectorNormalize(n); - l = (int)(n[0] * 128 + 128);*out++ = bound(0, l, 255); - l = (int)(n[1] * 128 + 128);*out++ = bound(0, l, 255); - l = (int)(n[2] * 128 + 128);*out++ = bound(0, l, 255); - *out++ = 255; + l = (int)(n[0] * 128 + 128);out[2] = bound(0, l, 255); + l = (int)(n[1] * 128 + 128);out[1] = bound(0, l, 255); + l = (int)(n[2] * 128 + 128);out[0] = bound(0, l, 255); + out[3] = 255; } R_UpdateTexture(surface->deluxemaptexture, templight, surface->lightmapinfo->lightmaporigin[0], surface->lightmapinfo->lightmaporigin[1], smax, tmax); } @@ -1191,6 +1191,7 @@ void R_ReplaceWorldTexture (void) if ((skinframe = R_SkinFrame_LoadExternal(newt, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE | TEXF_PICMIP, true))) { // t->skinframes[0] = skinframe; + t->currentskinframe = skinframe; t->currentskinframe = skinframe; Con_Printf("%s replaced with %s\n", r, newt); } diff --git a/gl_textures.c b/gl_textures.c index b8b904a5..f62d0243 100644 --- a/gl_textures.c +++ b/gl_textures.c @@ -38,7 +38,7 @@ static mempool_t *texturemempool; typedef struct textypeinfo_s { - int textype; + textype_t textype; int inputbytesperpixel; int internalbytesperpixel; float glinternalbytesperpixel; @@ -47,17 +47,17 @@ typedef struct textypeinfo_s } textypeinfo_t; -static textypeinfo_t textype_palette = {TEXTYPE_PALETTE, 1, 4, 4.0f, GL_RGBA , 3}; +static textypeinfo_t textype_palette = {TEXTYPE_PALETTE, 1, 4, 4.0f, GL_BGRA , 3}; +static textypeinfo_t textype_palette_alpha = {TEXTYPE_PALETTE, 1, 4, 4.0f, GL_BGRA , 4}; +static textypeinfo_t textype_palette_compress = {TEXTYPE_PALETTE, 1, 4, 0.5f, GL_BGRA , GL_COMPRESSED_RGB_ARB}; +static textypeinfo_t textype_palette_alpha_compress = {TEXTYPE_PALETTE, 1, 4, 1.0f, GL_BGRA , GL_COMPRESSED_RGBA_ARB}; static textypeinfo_t textype_rgba = {TEXTYPE_RGBA , 4, 4, 4.0f, GL_RGBA , 3}; -static textypeinfo_t textype_bgra = {TEXTYPE_BGRA , 4, 4, 4.0f, GL_BGRA , 3}; -static textypeinfo_t textype_palette_alpha = {TEXTYPE_PALETTE, 1, 4, 4.0f, GL_RGBA , 4}; static textypeinfo_t textype_rgba_alpha = {TEXTYPE_RGBA , 4, 4, 4.0f, GL_RGBA , 4}; -static textypeinfo_t textype_bgra_alpha = {TEXTYPE_BGRA , 4, 4, 4.0f, GL_BGRA , 4}; -static textypeinfo_t textype_palette_compress = {TEXTYPE_PALETTE, 1, 4, 0.5f, GL_RGBA , GL_COMPRESSED_RGB_ARB}; static textypeinfo_t textype_rgba_compress = {TEXTYPE_RGBA , 4, 4, 0.5f, GL_RGBA , GL_COMPRESSED_RGB_ARB}; -static textypeinfo_t textype_bgra_compress = {TEXTYPE_BGRA , 4, 4, 0.5f, GL_BGRA , GL_COMPRESSED_RGB_ARB}; -static textypeinfo_t textype_palette_alpha_compress = {TEXTYPE_PALETTE, 1, 4, 1.0f, GL_RGBA , GL_COMPRESSED_RGBA_ARB}; static textypeinfo_t textype_rgba_alpha_compress = {TEXTYPE_RGBA , 4, 4, 1.0f, GL_RGBA , GL_COMPRESSED_RGBA_ARB}; +static textypeinfo_t textype_bgra = {TEXTYPE_BGRA , 4, 4, 4.0f, GL_BGRA , 3}; +static textypeinfo_t textype_bgra_alpha = {TEXTYPE_BGRA , 4, 4, 4.0f, GL_BGRA , 4}; +static textypeinfo_t textype_bgra_compress = {TEXTYPE_BGRA , 4, 4, 0.5f, GL_BGRA , GL_COMPRESSED_RGB_ARB}; static textypeinfo_t textype_bgra_alpha_compress = {TEXTYPE_BGRA , 4, 4, 1.0f, GL_BGRA , GL_COMPRESSED_RGBA_ARB}; #define GLTEXTURETYPE_1D 0 @@ -144,7 +144,7 @@ static int resizebuffersize = 0; static unsigned char *texturebuffer; static int texturebuffersize = 0; -static textypeinfo_t *R_GetTexTypeInfo(int textype, int flags) +static textypeinfo_t *R_GetTexTypeInfo(textype_t textype, int flags) { if ((flags & TEXF_COMPRESS) && gl_texturecompression.integer >= 1 && gl_support_texture_compression) { @@ -801,9 +801,8 @@ static void R_Upload(gltexture_t *glt, const unsigned char *data, int fragx, int } else if (glt->textype->textype == TEXTYPE_PALETTE) { - // promote paletted to RGBA, so we only have to worry about RGB and - // RGBA in the rest of this code - Image_Copy8bitRGBA(prevbuffer, colorconvertbuffer, fragwidth * fragheight * fragdepth * glt->sides, glt->palette); + // promote paletted to BGRA, so we only have to worry about BGRA in the rest of this code + Image_Copy8bitBGRA(prevbuffer, colorconvertbuffer, fragwidth * fragheight * fragdepth * glt->sides, glt->palette); prevbuffer = colorconvertbuffer; } @@ -952,7 +951,7 @@ static void R_UploadTexture (gltexture_t *glt) Con_Printf("R_UploadTexture: Texture %s already uploaded and destroyed. Can not upload original image again. Uploaded blank texture.\n", glt->identifier); } -static rtexture_t *R_SetupTexture(rtexturepool_t *rtexturepool, const char *identifier, int width, int height, int depth, int sides, int flags, int textype, int texturetype, const unsigned char *data, const unsigned int *palette) +static rtexture_t *R_SetupTexture(rtexturepool_t *rtexturepool, const char *identifier, int width, int height, int depth, int sides, int flags, textype_t textype, int texturetype, const unsigned char *data, const unsigned int *palette) { int i, size; gltexture_t *glt; @@ -1061,22 +1060,22 @@ static rtexture_t *R_SetupTexture(rtexturepool_t *rtexturepool, const char *iden return (rtexture_t *)glt; } -rtexture_t *R_LoadTexture1D(rtexturepool_t *rtexturepool, const char *identifier, int width, const unsigned char *data, int textype, int flags, const unsigned int *palette) +rtexture_t *R_LoadTexture1D(rtexturepool_t *rtexturepool, const char *identifier, int width, const unsigned char *data, textype_t textype, int flags, const unsigned int *palette) { return R_SetupTexture(rtexturepool, identifier, width, 1, 1, 1, flags, textype, GLTEXTURETYPE_1D, data, palette); } -rtexture_t *R_LoadTexture2D(rtexturepool_t *rtexturepool, const char *identifier, int width, int height, const unsigned char *data, int textype, int flags, const unsigned int *palette) +rtexture_t *R_LoadTexture2D(rtexturepool_t *rtexturepool, const char *identifier, int width, int height, const unsigned char *data, textype_t textype, int flags, const unsigned int *palette) { return R_SetupTexture(rtexturepool, identifier, width, height, 1, 1, flags, textype, GLTEXTURETYPE_2D, data, palette); } -rtexture_t *R_LoadTexture3D(rtexturepool_t *rtexturepool, const char *identifier, int width, int height, int depth, const unsigned char *data, int textype, int flags, const unsigned int *palette) +rtexture_t *R_LoadTexture3D(rtexturepool_t *rtexturepool, const char *identifier, int width, int height, int depth, const unsigned char *data, textype_t textype, int flags, const unsigned int *palette) { return R_SetupTexture(rtexturepool, identifier, width, height, depth, 1, flags, textype, GLTEXTURETYPE_3D, data, palette); } -rtexture_t *R_LoadTextureCubeMap(rtexturepool_t *rtexturepool, const char *identifier, int width, const unsigned char *data, int textype, int flags, const unsigned int *palette) +rtexture_t *R_LoadTextureCubeMap(rtexturepool_t *rtexturepool, const char *identifier, int width, const unsigned char *data, textype_t textype, int flags, const unsigned int *palette) { return R_SetupTexture(rtexturepool, identifier, width, width, 1, 6, flags, textype, GLTEXTURETYPE_CUBEMAP, data, palette); } diff --git a/image.c b/image.c index 5059710e..b41f7801 100644 --- a/image.c +++ b/image.c @@ -115,7 +115,7 @@ void Image_GammaRemapRGB(const unsigned char *in, unsigned char *out, int pixels } // note: pal must be 32bit color -void Image_Copy8bitRGBA(const unsigned char *in, unsigned char *out, int pixels, const unsigned int *pal) +void Image_Copy8bitBGRA(const unsigned char *in, unsigned char *out, int pixels, const unsigned int *pal) { int *iout = (int *)out; while (pixels >= 8) @@ -181,10 +181,10 @@ typedef struct pcx_s LoadPCX ============ */ -unsigned char* LoadPCX (const unsigned char *f, int filesize, int matchwidth, int matchheight) +unsigned char* LoadPCX_BGRA (const unsigned char *f, int filesize) { pcx_t pcx; - unsigned char *a, *b, *image_rgba, *pbuf; + unsigned char *a, *b, *image_buffer, *pbuf; const unsigned char *palette, *fin, *enddata; int x, y, x2, dataByte; @@ -216,18 +216,16 @@ unsigned char* LoadPCX (const unsigned char *f, int filesize, int matchwidth, in Con_Print("Bad pcx file\n"); return NULL; } - if ((matchwidth && image_width != matchwidth) || (matchheight && image_height != matchheight)) - return NULL; palette = f + filesize - 768; - image_rgba = (unsigned char *)Mem_Alloc(tempmempool, image_width*image_height*4); - if (!image_rgba) + image_buffer = (unsigned char *)Mem_Alloc(tempmempool, image_width*image_height*4); + if (!image_buffer) { Con_Printf("LoadPCX: not enough memory for %i by %i image\n", image_width, image_height); return NULL; } - pbuf = image_rgba + image_width*image_height*3; + pbuf = image_buffer + image_width*image_height*3; enddata = palette; for (y = 0;y < image_height && fin < enddata;y++) @@ -255,19 +253,19 @@ unsigned char* LoadPCX (const unsigned char *f, int filesize, int matchwidth, in a[x++] = 0; } - a = image_rgba; + a = image_buffer; b = pbuf; for(x = 0;x < image_width*image_height;x++) { y = *b++ * 3; - *a++ = palette[y]; - *a++ = palette[y+1]; *a++ = palette[y+2]; + *a++ = palette[y+1]; + *a++ = palette[y]; *a++ = 255; } - return image_rgba; + return image_buffer; } /* @@ -298,14 +296,20 @@ void PrintTargaHeader(TargaHeader *t) LoadTGA ============= */ -unsigned char *LoadTGA (const unsigned char *f, int filesize, int matchwidth, int matchheight) +unsigned char *LoadTGA_BGRA (const unsigned char *f, int filesize) { - int x, y, pix_inc, row_inc, red, green, blue, alpha, runlen, alphabits; - unsigned char *pixbuf, *image_rgba; + int x, y, pix_inc, row_inci, runlen, alphabits; + unsigned char *image_buffer; + unsigned int *pixbufi; const unsigned char *fin, *enddata; - unsigned char *p; TargaHeader targa_header; - unsigned char palette[256*4]; + unsigned int palettei[256]; + union + { + unsigned int i; + unsigned char b[4]; + } + bgra; if (filesize < 19) return NULL; @@ -329,8 +333,6 @@ unsigned char *LoadTGA (const unsigned char *f, int filesize, int matchwidth, in PrintTargaHeader(&targa_header); return NULL; } - if ((matchwidth && image_width != matchwidth) || (matchheight && image_height != matchheight)) - return NULL; targa_header.pixel_size = f[16]; targa_header.attributes = f[17]; @@ -361,21 +363,17 @@ unsigned char *LoadTGA (const unsigned char *f, int filesize, int matchwidth, in { for (x = 0;x < targa_header.colormap_length;x++) { - palette[x*4+2] = *fin++; - palette[x*4+1] = *fin++; - palette[x*4+0] = *fin++; - palette[x*4+3] = 255; + bgra.b[0] = *fin++; + bgra.b[1] = *fin++; + bgra.b[2] = *fin++; + bgra.b[3] = 255; + palettei[x] = bgra.i; } } else if (targa_header.colormap_size == 32) { - for (x = 0;x < targa_header.colormap_length;x++) - { - palette[x*4+2] = *fin++; - palette[x*4+1] = *fin++; - palette[x*4+0] = *fin++; - palette[x*4+3] = *fin++; - } + memcpy(palettei, fin, targa_header.colormap_length*4); + fin += targa_header.colormap_length * 4; } else { @@ -400,10 +398,9 @@ unsigned char *LoadTGA (const unsigned char *f, int filesize, int matchwidth, in // set up a palette to make the loader easier for (x = 0;x < 256;x++) { - palette[x*4+2] = x; - palette[x*4+1] = x; - palette[x*4+0] = x; - palette[x*4+3] = 255; + bgra.b[0] = bgra.b[1] = bgra.b[2] = x; + bgra.b[3] = 255; + palettei[x] = bgra.i; } // fall through to colormap case case 1: @@ -434,8 +431,8 @@ unsigned char *LoadTGA (const unsigned char *f, int filesize, int matchwidth, in return NULL; } - image_rgba = (unsigned char *)Mem_Alloc(tempmempool, image_width * image_height * 4); - if (!image_rgba) + image_buffer = (unsigned char *)Mem_Alloc(tempmempool, image_width * image_height * 4); + if (!image_buffer) { Con_Printf("LoadTGA: not enough memory for %i by %i image\n", image_width, image_height); return NULL; @@ -444,38 +441,29 @@ unsigned char *LoadTGA (const unsigned char *f, int filesize, int matchwidth, in // If bit 5 of attributes isn't set, the image has been stored from bottom to top if ((targa_header.attributes & 0x20) == 0) { - pixbuf = image_rgba + (image_height - 1)*image_width*4; - row_inc = -image_width*4*2; + pixbufi = (unsigned int*)image_buffer + (image_height - 1)*image_width; + row_inci = -image_width*2; } else { - pixbuf = image_rgba; - row_inc = 0; + pixbufi = (unsigned int*)image_buffer; + row_inci = 0; } x = 0; y = 0; - red = green = blue = alpha = 255; pix_inc = 1; if ((targa_header.image_type & ~8) == 2) - pix_inc = targa_header.pixel_size / 8; + pix_inc = (targa_header.pixel_size + 7) / 8; switch (targa_header.image_type) { case 1: // colormapped, uncompressed case 3: // greyscale, uncompressed if (fin + image_width * image_height * pix_inc > enddata) break; - for (y = 0;y < image_height;y++, pixbuf += row_inc) - { + for (y = 0;y < image_height;y++, pixbufi += row_inci) for (x = 0;x < image_width;x++) - { - p = palette + *fin++ * 4; - *pixbuf++ = p[0]; - *pixbuf++ = p[1]; - *pixbuf++ = p[2]; - *pixbuf++ = p[3]; - } - } + *pixbufi++ = palettei[*fin++]; break; case 2: // BGR or BGRA, uncompressed @@ -483,34 +471,27 @@ unsigned char *LoadTGA (const unsigned char *f, int filesize, int matchwidth, in break; if (targa_header.pixel_size == 32 && alphabits) { - for (y = 0;y < image_height;y++, pixbuf += row_inc) - { - for (x = 0;x < image_width;x++, fin += pix_inc) - { - *pixbuf++ = fin[2]; - *pixbuf++ = fin[1]; - *pixbuf++ = fin[0]; - *pixbuf++ = fin[3]; - } - } + for (y = 0;y < image_height;y++) + memcpy(pixbufi + y * (image_width + row_inci), fin + y * image_width * pix_inc, image_width*4); } else { - for (y = 0;y < image_height;y++, pixbuf += row_inc) + for (y = 0;y < image_height;y++, pixbufi += row_inci) { for (x = 0;x < image_width;x++, fin += pix_inc) { - *pixbuf++ = fin[2]; - *pixbuf++ = fin[1]; - *pixbuf++ = fin[0]; - *pixbuf++ = 255; + bgra.b[0] = fin[0]; + bgra.b[1] = fin[1]; + bgra.b[2] = fin[2]; + bgra.b[3] = 255; + *pixbufi++ = bgra.i; } } } break; case 9: // colormapped, RLE case 11: // greyscale, RLE - for (y = 0;y < image_height;y++, pixbuf += row_inc) + for (y = 0;y < image_height;y++, pixbufi += row_inci) { for (x = 0;x < image_width;) { @@ -525,18 +506,9 @@ unsigned char *LoadTGA (const unsigned char *f, int filesize, int matchwidth, in break; // error - truncated file if (x + runlen > image_width) break; // error - line exceeds width - p = palette + *fin++ * 4; - red = p[0]; - green = p[1]; - blue = p[2]; - alpha = p[3]; + bgra.i = palettei[*fin++]; for (;runlen--;x++) - { - *pixbuf++ = red; - *pixbuf++ = green; - *pixbuf++ = blue; - *pixbuf++ = alpha; - } + *pixbufi++ = bgra.i; } else { @@ -547,13 +519,7 @@ unsigned char *LoadTGA (const unsigned char *f, int filesize, int matchwidth, in if (x + runlen > image_width) break; // error - line exceeds width for (;runlen--;x++) - { - p = palette + *fin++ * 4; - *pixbuf++ = p[0]; - *pixbuf++ = p[1]; - *pixbuf++ = p[2]; - *pixbuf++ = p[3]; - } + *pixbufi++ = palettei[*fin++]; } } } @@ -562,7 +528,7 @@ unsigned char *LoadTGA (const unsigned char *f, int filesize, int matchwidth, in // BGR or BGRA, RLE if (targa_header.pixel_size == 32 && alphabits) { - for (y = 0;y < image_height;y++, pixbuf += row_inc) + for (y = 0;y < image_height;y++, pixbufi += row_inci) { for (x = 0;x < image_width;) { @@ -577,18 +543,13 @@ unsigned char *LoadTGA (const unsigned char *f, int filesize, int matchwidth, in break; // error - truncated file if (x + runlen > image_width) break; // error - line exceeds width - red = fin[2]; - green = fin[1]; - blue = fin[0]; - alpha = fin[3]; + bgra.b[0] = fin[0]; + bgra.b[1] = fin[1]; + bgra.b[2] = fin[2]; + bgra.b[3] = fin[3]; fin += pix_inc; for (;runlen--;x++) - { - *pixbuf++ = red; - *pixbuf++ = green; - *pixbuf++ = blue; - *pixbuf++ = alpha; - } + *pixbufi++ = bgra.i; } else { @@ -598,12 +559,14 @@ unsigned char *LoadTGA (const unsigned char *f, int filesize, int matchwidth, in break; // error - truncated file if (x + runlen > image_width) break; // error - line exceeds width - for (;runlen--;x++, fin += pix_inc) + for (;runlen--;x++) { - *pixbuf++ = fin[2]; - *pixbuf++ = fin[1]; - *pixbuf++ = fin[0]; - *pixbuf++ = fin[3]; + bgra.b[0] = fin[0]; + bgra.b[1] = fin[1]; + bgra.b[2] = fin[2]; + bgra.b[3] = fin[3]; + fin += pix_inc; + *pixbufi++ = bgra.i; } } } @@ -611,7 +574,7 @@ unsigned char *LoadTGA (const unsigned char *f, int filesize, int matchwidth, in } else { - for (y = 0;y < image_height;y++, pixbuf += row_inc) + for (y = 0;y < image_height;y++, pixbufi += row_inci) { for (x = 0;x < image_width;) { @@ -626,18 +589,13 @@ unsigned char *LoadTGA (const unsigned char *f, int filesize, int matchwidth, in break; // error - truncated file if (x + runlen > image_width) break; // error - line exceeds width - red = fin[2]; - green = fin[1]; - blue = fin[0]; - alpha = 255; + bgra.b[0] = fin[0]; + bgra.b[1] = fin[1]; + bgra.b[2] = fin[2]; + bgra.b[3] = 255; fin += pix_inc; for (;runlen--;x++) - { - *pixbuf++ = red; - *pixbuf++ = green; - *pixbuf++ = blue; - *pixbuf++ = alpha; - } + *pixbufi++ = bgra.i; } else { @@ -647,12 +605,14 @@ unsigned char *LoadTGA (const unsigned char *f, int filesize, int matchwidth, in break; // error - truncated file if (x + runlen > image_width) break; // error - line exceeds width - for (;runlen--;x++, fin += pix_inc) + for (;runlen--;x++) { - *pixbuf++ = fin[2]; - *pixbuf++ = fin[1]; - *pixbuf++ = fin[0]; - *pixbuf++ = 255; + bgra.b[0] = fin[0]; + bgra.b[1] = fin[1]; + bgra.b[2] = fin[2]; + bgra.b[3] = 255; + fin += pix_inc; + *pixbufi++ = bgra.i; } } } @@ -664,55 +624,9 @@ unsigned char *LoadTGA (const unsigned char *f, int filesize, int matchwidth, in break; } - return image_rgba; -} - -/* -============ -LoadLMP -============ -*/ -unsigned char *LoadLMP (const unsigned char *f, int filesize, int matchwidth, int matchheight, qboolean loadAs8Bit) -{ - unsigned char *image_buffer; - - if (filesize < 9) - { - Con_Print("LoadLMP: invalid LMP file\n"); - return NULL; - } - - // parse the very complicated header *chuckle* - image_width = BuffLittleLong(f); - image_height = BuffLittleLong(f + 4); - if (image_width > 4096 || image_height > 4096 || image_width <= 0 || image_height <= 0) - { - Con_Printf("LoadLMP: invalid size %ix%i\n", image_width, image_height); - return NULL; - } - if ((matchwidth && image_width != matchwidth) || (matchheight && image_height != matchheight)) - return NULL; - - if (filesize < (8 + image_width * image_height)) - { - Con_Print("LoadLMP: invalid LMP file\n"); - return NULL; - } - - if (loadAs8Bit) - { - image_buffer = (unsigned char *)Mem_Alloc(tempmempool, image_width * image_height); - memcpy(image_buffer, f + 8, image_width * image_height); - } - else - { - image_buffer = (unsigned char *)Mem_Alloc(tempmempool, image_width * image_height * 4); - Image_Copy8bitRGBA(f + 8, image_buffer, image_width * image_height, palette_transparent); - } return image_buffer; } - typedef struct q2wal_s { char name[32]; @@ -724,9 +638,9 @@ typedef struct q2wal_s int value; } q2wal_t; -unsigned char *LoadWAL (const unsigned char *f, int filesize, int matchwidth, int matchheight) +unsigned char *LoadWAL_BGRA (const unsigned char *f, int filesize) { - unsigned char *image_rgba; + unsigned char *image_buffer; const q2wal_t *inwal = (const q2wal_t *)f; if (filesize < (int) sizeof(q2wal_t)) @@ -742,8 +656,6 @@ unsigned char *LoadWAL (const unsigned char *f, int filesize, int matchwidth, in Con_Printf("LoadWAL: invalid size %ix%i\n", image_width, image_height); return NULL; } - if ((matchwidth && image_width != matchwidth) || (matchheight && image_height != matchheight)) - return NULL; if (filesize < (int) sizeof(q2wal_t) + (int) LittleLong(inwal->offsets[0]) + image_width * image_height) { @@ -751,14 +663,14 @@ unsigned char *LoadWAL (const unsigned char *f, int filesize, int matchwidth, in return NULL; } - image_rgba = (unsigned char *)Mem_Alloc(tempmempool, image_width * image_height * 4); - if (!image_rgba) + image_buffer = (unsigned char *)Mem_Alloc(tempmempool, image_width * image_height * 4); + if (!image_buffer) { - Con_Printf("LoadLMP: not enough memory for %i by %i image\n", image_width, image_height); + Con_Printf("LoadWAL: not enough memory for %i by %i image\n", image_width, image_height); return NULL; } - Image_Copy8bitRGBA(f + LittleLong(inwal->offsets[0]), image_rgba, image_width * image_height, palette_complete); - return image_rgba; + Image_Copy8bitBGRA(f + LittleLong(inwal->offsets[0]), image_buffer, image_width * image_height, palette_bgra_complete); + return image_buffer; } @@ -779,65 +691,65 @@ void Image_StripImageExtension (const char *in, char *out, size_t size_out) typedef struct imageformat_s { const char *formatstring; - unsigned char *(*loadfunc)(const unsigned char *f, int filesize, int matchwidth, int matchheight); + unsigned char *(*loadfunc)(const unsigned char *f, int filesize); } imageformat_t; // GAME_TENEBRAE only imageformat_t imageformats_tenebrae[] = { - {"override/%s.tga", LoadTGA}, - {"override/%s.png", PNG_LoadImage}, - {"override/%s.jpg", JPEG_LoadImage}, - {"override/%s.pcx", LoadPCX}, + {"override/%s.tga", LoadTGA_BGRA}, + {"override/%s.png", PNG_LoadImage_BGRA}, + {"override/%s.jpg", JPEG_LoadImage_BGRA}, + {"override/%s.pcx", LoadPCX_BGRA}, {NULL, NULL} }; imageformat_t imageformats_nopath[] = { - {"override/%s.tga", LoadTGA}, - {"override/%s.png", PNG_LoadImage}, - {"override/%s.jpg", JPEG_LoadImage}, - {"textures/%s.tga", LoadTGA}, - {"textures/%s.png", PNG_LoadImage}, - {"textures/%s.jpg", JPEG_LoadImage}, - {"%s.tga", LoadTGA}, - {"%s.png", PNG_LoadImage}, - {"%s.jpg", JPEG_LoadImage}, - {"%s.pcx", LoadPCX}, + {"override/%s.tga", LoadTGA_BGRA}, + {"override/%s.png", PNG_LoadImage_BGRA}, + {"override/%s.jpg", JPEG_LoadImage_BGRA}, + {"textures/%s.tga", LoadTGA_BGRA}, + {"textures/%s.png", PNG_LoadImage_BGRA}, + {"textures/%s.jpg", JPEG_LoadImage_BGRA}, + {"%s.tga", LoadTGA_BGRA}, + {"%s.png", PNG_LoadImage_BGRA}, + {"%s.jpg", JPEG_LoadImage_BGRA}, + {"%s.pcx", LoadPCX_BGRA}, {NULL, NULL} }; imageformat_t imageformats_textures[] = { - {"%s.tga", LoadTGA}, - {"%s.png", PNG_LoadImage}, - {"%s.jpg", JPEG_LoadImage}, - {"%s.pcx", LoadPCX}, - {"%s.wal", LoadWAL}, + {"%s.tga", LoadTGA_BGRA}, + {"%s.png", PNG_LoadImage_BGRA}, + {"%s.jpg", JPEG_LoadImage_BGRA}, + {"%s.pcx", LoadPCX_BGRA}, + {"%s.wal", LoadWAL_BGRA}, {NULL, NULL} }; imageformat_t imageformats_gfx[] = { - {"%s.tga", LoadTGA}, - {"%s.png", PNG_LoadImage}, - {"%s.jpg", JPEG_LoadImage}, - {"%s.pcx", LoadPCX}, + {"%s.tga", LoadTGA_BGRA}, + {"%s.png", PNG_LoadImage_BGRA}, + {"%s.jpg", JPEG_LoadImage_BGRA}, + {"%s.pcx", LoadPCX_BGRA}, {NULL, NULL} }; imageformat_t imageformats_other[] = { - {"%s.tga", LoadTGA}, - {"%s.png", PNG_LoadImage}, - {"%s.jpg", JPEG_LoadImage}, - {"%s.pcx", LoadPCX}, + {"%s.tga", LoadTGA_BGRA}, + {"%s.png", PNG_LoadImage_BGRA}, + {"%s.jpg", JPEG_LoadImage_BGRA}, + {"%s.pcx", LoadPCX_BGRA}, {NULL, NULL} }; int fixtransparentpixels(unsigned char *data, int w, int h); -unsigned char *loadimagepixels (const char *filename, qboolean complain, int matchwidth, int matchheight, qboolean allowFixtrans) +unsigned char *loadimagepixelsbgra (const char *filename, qboolean complain, qboolean allowFixtrans) { fs_offset_t filesize; imageformat_t *firstformat, *format; @@ -877,7 +789,7 @@ unsigned char *loadimagepixels (const char *filename, qboolean complain, int mat f = FS_LoadFile(name, tempmempool, true, &filesize); if (f) { - data = format->loadfunc(f, filesize, matchwidth, matchheight); + data = format->loadfunc(f, filesize); Mem_Free(f); if (data) { @@ -896,7 +808,7 @@ unsigned char *loadimagepixels (const char *filename, qboolean complain, int mat char outfilename[MAX_QPATH], buf[MAX_QPATH]; Image_StripImageExtension(name, buf, sizeof(buf)); dpsnprintf(outfilename, sizeof(outfilename), "fixtrans/%s.tga", buf); - Image_WriteTGARGBA(outfilename, image_width, image_height, data); + Image_WriteTGABGRA(outfilename, image_width, image_height, data); Con_Printf("- %s written.\n", outfilename); } } @@ -924,13 +836,13 @@ unsigned char *loadimagepixels (const char *filename, qboolean complain, int mat return NULL; } -rtexture_t *loadtextureimage (rtexturepool_t *pool, const char *filename, int matchwidth, int matchheight, qboolean complain, int flags, qboolean allowFixtrans) +rtexture_t *loadtextureimage (rtexturepool_t *pool, const char *filename, qboolean complain, int flags, qboolean allowFixtrans) { unsigned char *data; rtexture_t *rt; - if (!(data = loadimagepixels (filename, complain, matchwidth, matchheight, allowFixtrans))) + if (!(data = loadimagepixelsbgra (filename, complain, allowFixtrans))) return 0; - rt = R_LoadTexture2D(pool, filename, image_width, image_height, data, TEXTYPE_RGBA, flags, NULL); + rt = R_LoadTexture2D(pool, filename, image_width, image_height, data, TEXTYPE_BGRA, flags, NULL); Mem_Free(data); return rt; } @@ -983,41 +895,41 @@ int fixtransparentpixels(unsigned char *data, int w, int h) unsigned char r, g, b, a, r0, g0, b0; if(fixMask[FIXTRANS_PIXEL] & FIXTRANS_HAS_U) { - r = data[FIXTRANS_PIXEL_U * 4 + 0]; + r = data[FIXTRANS_PIXEL_U * 4 + 2]; g = data[FIXTRANS_PIXEL_U * 4 + 1]; - b = data[FIXTRANS_PIXEL_U * 4 + 2]; + b = data[FIXTRANS_PIXEL_U * 4 + 0]; a = data[FIXTRANS_PIXEL_U * 4 + 3]; sumR += r; sumG += g; sumB += b; sumA += a; sumRA += r*a; sumGA += g*a; sumBA += b*a; ++cnt; } if(fixMask[FIXTRANS_PIXEL] & FIXTRANS_HAS_D) { - r = data[FIXTRANS_PIXEL_D * 4 + 0]; + r = data[FIXTRANS_PIXEL_D * 4 + 2]; g = data[FIXTRANS_PIXEL_D * 4 + 1]; - b = data[FIXTRANS_PIXEL_D * 4 + 2]; + b = data[FIXTRANS_PIXEL_D * 4 + 0]; a = data[FIXTRANS_PIXEL_D * 4 + 3]; sumR += r; sumG += g; sumB += b; sumA += a; sumRA += r*a; sumGA += g*a; sumBA += b*a; ++cnt; } if(fixMask[FIXTRANS_PIXEL] & FIXTRANS_HAS_L) { - r = data[FIXTRANS_PIXEL_L * 4 + 0]; + r = data[FIXTRANS_PIXEL_L * 4 + 2]; g = data[FIXTRANS_PIXEL_L * 4 + 1]; - b = data[FIXTRANS_PIXEL_L * 4 + 2]; + b = data[FIXTRANS_PIXEL_L * 4 + 0]; a = data[FIXTRANS_PIXEL_L * 4 + 3]; sumR += r; sumG += g; sumB += b; sumA += a; sumRA += r*a; sumGA += g*a; sumBA += b*a; ++cnt; } if(fixMask[FIXTRANS_PIXEL] & FIXTRANS_HAS_R) { - r = data[FIXTRANS_PIXEL_R * 4 + 0]; + r = data[FIXTRANS_PIXEL_R * 4 + 2]; g = data[FIXTRANS_PIXEL_R * 4 + 1]; - b = data[FIXTRANS_PIXEL_R * 4 + 2]; + b = data[FIXTRANS_PIXEL_R * 4 + 0]; a = data[FIXTRANS_PIXEL_R * 4 + 3]; sumR += r; sumG += g; sumB += b; sumA += a; sumRA += r*a; sumGA += g*a; sumBA += b*a; ++cnt; } if(!cnt) continue; - r0 = data[FIXTRANS_PIXEL * 4 + 0]; + r0 = data[FIXTRANS_PIXEL * 4 + 2]; g0 = data[FIXTRANS_PIXEL * 4 + 1]; - b0 = data[FIXTRANS_PIXEL * 4 + 2]; + b0 = data[FIXTRANS_PIXEL * 4 + 0]; if(sumA) { // there is a surrounding non-alpha pixel @@ -1034,9 +946,9 @@ int fixtransparentpixels(unsigned char *data, int w, int h) } if(r != r0 || g != g0 || b != b0) ++changedPixels; - data[FIXTRANS_PIXEL * 4 + 0] = r; + data[FIXTRANS_PIXEL * 4 + 2] = r; data[FIXTRANS_PIXEL * 4 + 1] = g; - data[FIXTRANS_PIXEL * 4 + 2] = b; + data[FIXTRANS_PIXEL * 4 + 0] = b; fixMask[FIXTRANS_PIXEL] |= FIXTRANS_FIXED; } for(y = 0; y < h; ++y) @@ -1076,11 +988,11 @@ void Image_FixTransparentPixels_f(void) Con_Printf("Processing %s... ", filename); Image_StripImageExtension(filename, buf, sizeof(buf)); dpsnprintf(outfilename, sizeof(outfilename), "fixtrans/%s.tga", buf); - if(!(data = loadimagepixels(filename, true, 0, 0, false))) + if(!(data = loadimagepixelsbgra(filename, true, false))) return; if((n = fixtransparentpixels(data, image_width, image_height))) { - Image_WriteTGARGBA(outfilename, image_width, image_height, data); + Image_WriteTGABGRA(outfilename, image_width, image_height, data); Con_Printf("%s written (%d pixels changed).\n", outfilename, n); } else @@ -1089,11 +1001,9 @@ void Image_FixTransparentPixels_f(void) } } -qboolean Image_WriteTGARGB_preflipped (const char *filename, int width, int height, const unsigned char *data, unsigned char *buffer) +qboolean Image_WriteTGABGR_preflipped (const char *filename, int width, int height, const unsigned char *data, unsigned char *buffer) { qboolean ret; - unsigned char *out; - const unsigned char *in, *end; memset (buffer, 0, 18); buffer[2] = 2; // uncompressed type @@ -1104,21 +1014,13 @@ qboolean Image_WriteTGARGB_preflipped (const char *filename, int width, int heig buffer[16] = 24; // pixel size // swap rgb to bgr - in = data; - out = buffer + 18; - end = in + width*height*3; - for (;in < end;in += 3) - { - *out++ = in[2]; - *out++ = in[1]; - *out++ = in[0]; - } + memcpy(buffer + 18, data, width*height*3); ret = FS_WriteFile (filename, buffer, width*height*3 + 18 ); return ret; } -void Image_WriteTGARGBA (const char *filename, int width, int height, const unsigned char *data) +void Image_WriteTGABGRA (const char *filename, int width, int height, const unsigned char *data) { int y; unsigned char *buffer, *out; @@ -1143,21 +1045,13 @@ void Image_WriteTGARGBA (const char *filename, int width, int height, const unsi buffer[16] = 32; // pixel size buffer[17] = 8; // 8 bits of alpha - // swap rgba to bgra and flip upside down + // flip upside down out = buffer + 18; for (y = height - 1;y >= 0;y--) { - in = data + y * width * 4; - end = in + width * 4; - for (;in < end;in += 4) - { - *out++ = in[2]; - *out++ = in[1]; - *out++ = in[0]; - *out++ = in[3]; - } + memcpy(out, data + y * width * 4, width * 4); + out += width*4; } - FS_WriteFile (filename, buffer, width*height*4 + 18 ); } else { @@ -1165,7 +1059,7 @@ void Image_WriteTGARGBA (const char *filename, int width, int height, const unsi buffer[16] = 24; // pixel size buffer[17] = 0; // 8 bits of alpha - // swap rgba to bgr and flip upside down + // truncate bgra to bgr and flip upside down out = buffer + 18; for (y = height - 1;y >= 0;y--) { @@ -1173,13 +1067,13 @@ void Image_WriteTGARGBA (const char *filename, int width, int height, const unsi end = in + width * 4; for (;in < end;in += 4) { - *out++ = in[2]; - *out++ = in[1]; *out++ = in[0]; + *out++ = in[1]; + *out++ = in[2]; } } - FS_WriteFile (filename, buffer, width*height*3 + 18 ); } + FS_WriteFile (filename, buffer, out - buffer); Mem_Free(buffer); } @@ -1456,7 +1350,7 @@ void Image_MipReduce32(const unsigned char *in, unsigned char *out, int *width, } } -void Image_HeightmapToNormalmap(const unsigned char *inpixels, unsigned char *outpixels, int width, int height, int clamp, float bumpscale) +void Image_HeightmapToNormalmap_BGRA(const unsigned char *inpixels, unsigned char *outpixels, int width, int height, int clamp, float bumpscale) { int x, y, x1, x2, y1, y2; const unsigned char *b, *row[3]; @@ -1490,9 +1384,9 @@ void Image_HeightmapToNormalmap(const unsigned char *inpixels, unsigned char *ou n[2] = ibumpscale; VectorNormalize(n); // turn it into a dot3 rgb vector texture - out[0] = (int)(128.0f + n[0] * 127.0f); + out[2] = (int)(128.0f + n[0] * 127.0f); out[1] = (int)(128.0f + n[1] * 127.0f); - out[2] = (int)(128.0f + n[2] * 127.0f); + out[0] = (int)(128.0f + n[2] * 127.0f); out[3] = (p[4]) / 3; out += 4; } diff --git a/image.h b/image.h index 24152f90..98358124 100644 --- a/image.h +++ b/image.h @@ -15,24 +15,25 @@ void Image_CopyMux(unsigned char *outpixels, const unsigned char *inpixels, int // applies gamma correction to RGB pixels, in can be the same as out void Image_GammaRemapRGB(const unsigned char *in, unsigned char *out, int pixels, const unsigned char *gammar, const unsigned char *gammag, const unsigned char *gammab); -// converts 8bit image data to RGBA, in can not be the same as out -void Image_Copy8bitRGBA(const unsigned char *in, unsigned char *out, int pixels, const unsigned int *pal); +// converts 8bit image data to BGRA, in can not be the same as out +void Image_Copy8bitBGRA(const unsigned char *in, unsigned char *out, int pixels, const unsigned int *pal); void Image_StripImageExtension (const char *in, char *out, size_t size_out); -unsigned char *LoadTGA (const unsigned char *f, int filesize, int matchwidth, int matchheight); +// called by conchars.tga loader in gl_draw.c, otherwise private +unsigned char *LoadTGA_BGRA (const unsigned char *f, int filesize); // loads a texture, as pixel data -unsigned char *loadimagepixels (const char *filename, qboolean complain, int matchwidth, int matchheight, qboolean allowFixtrans); +unsigned char *loadimagepixelsbgra (const char *filename, qboolean complain, qboolean allowFixtrans); // loads a texture, as a texture -rtexture_t *loadtextureimage (rtexturepool_t *pool, const char *filename, int matchwidth, int matchheight, qboolean complain, int flags, qboolean allowFixtrans); +rtexture_t *loadtextureimage (rtexturepool_t *pool, const char *filename, qboolean complain, int flags, qboolean allowFixtrans); -// writes a RGB TGA that is already upside down (which TGA wants) -qboolean Image_WriteTGARGB_preflipped (const char *filename, int width, int height, const unsigned char *data, unsigned char *buffer); +// writes an upside down BGR image into a TGA +qboolean Image_WriteTGABGR_preflipped (const char *filename, int width, int height, const unsigned char *data, unsigned char *buffer); -// writes a RGBA TGA -void Image_WriteTGARGBA (const char *filename, int width, int height, const unsigned char *data); +// writes a BGRA image into a TGA file +void Image_WriteTGABGRA (const char *filename, int width, int height, const unsigned char *data); // resizes the image (in can not be the same as out) void Image_Resample32(const void *indata, int inwidth, int inheight, int indepth, void *outdata, int outwidth, int outheight, int outdepth, int quality); @@ -40,10 +41,7 @@ void Image_Resample32(const void *indata, int inwidth, int inheight, int indepth // scales the image down by a power of 2 (in can be the same as out) void Image_MipReduce32(const unsigned char *in, unsigned char *out, int *width, int *height, int *depth, int destwidth, int destheight, int destdepth); -// only used by menuplyr coloring -unsigned char *LoadLMP (const unsigned char *f, int filesize, int matchwidth, int matchheight, qboolean loadAs8Bit); - -void Image_HeightmapToNormalmap(const unsigned char *inpixels, unsigned char *outpixels, int width, int height, int clamp, float bumpscale); +void Image_HeightmapToNormalmap_BGRA(const unsigned char *inpixels, unsigned char *outpixels, int width, int height, int clamp, float bumpscale); // console command to fix the colors of transparent pixels (to prevent weird borders) void Image_FixTransparentPixels_f(void); diff --git a/image_png.c b/image_png.c index 6cf182a1..b53aee42 100644 --- a/image_png.c +++ b/image_png.c @@ -229,7 +229,7 @@ void PNG_warning_fn(void *png, const char *message) extern int image_width; extern int image_height; -unsigned char *PNG_LoadImage (const unsigned char *raw, int filesize, int matchwidth, int matchheight) +unsigned char *PNG_LoadImage_BGRA (const unsigned char *raw, int filesize) { unsigned int y; void *png, *pnginfo; @@ -311,11 +311,6 @@ unsigned char *PNG_LoadImage (const unsigned char *raw, int filesize, int matchw } #endif - if ((matchwidth && my_png.Width != (unsigned long)matchwidth) || (matchheight && my_png.Height != (unsigned long)matchheight)) - { - qpng_destroy_read_struct(&png, &pnginfo, 0); - return NULL; - } if (my_png.ColorType == PNG_COLOR_TYPE_PALETTE) qpng_set_palette_to_rgb(png); if (my_png.ColorType == PNG_COLOR_TYPE_GRAY || my_png.ColorType == PNG_COLOR_TYPE_GRAY_ALPHA) diff --git a/image_png.h b/image_png.h index 7862c845..045b1cb6 100644 --- a/image_png.h +++ b/image_png.h @@ -26,7 +26,7 @@ qboolean PNG_OpenLibrary (void); void PNG_CloseLibrary (void); -unsigned char* PNG_LoadImage (const unsigned char *f, int filesize, int matchwidth, int matchheight); +unsigned char* PNG_LoadImage_BGRA (const unsigned char *f, int filesize); #endif diff --git a/jpeg.c b/jpeg.c index c85c90a6..b803c8d0 100644 --- a/jpeg.c +++ b/jpeg.c @@ -495,14 +495,14 @@ static void JPEG_ErrorExit (j_common_ptr cinfo) ==================== JPEG_LoadImage -Load a JPEG image into a RGBA buffer +Load a JPEG image into a BGRA buffer ==================== */ -unsigned char* JPEG_LoadImage (const unsigned char *f, int filesize, int matchwidth, int matchheight) +unsigned char* JPEG_LoadImage_BGRA (const unsigned char *f, int filesize) { struct jpeg_decompress_struct cinfo; struct jpeg_error_mgr jerr; - unsigned char *image_rgba, *scanline; + unsigned char *image_buffer, *scanline; unsigned int line; // No DLL = no JPEGs @@ -518,24 +518,18 @@ unsigned char* JPEG_LoadImage (const unsigned char *f, int filesize, int matchwi image_width = cinfo.image_width; image_height = cinfo.image_height; - if ((matchwidth && image_width != matchwidth) || (matchheight && image_height != matchheight)) - { - qjpeg_finish_decompress (&cinfo); - qjpeg_destroy_decompress (&cinfo); - return NULL; - } if (image_width > 4096 || image_height > 4096 || image_width <= 0 || image_height <= 0) { Con_Printf("JPEG_LoadImage: invalid image size %ix%i\n", image_width, image_height); return NULL; } - image_rgba = (unsigned char *)Mem_Alloc(tempmempool, image_width * image_height * 4); + image_buffer = (unsigned char *)Mem_Alloc(tempmempool, image_width * image_height * 4); scanline = (unsigned char *)Mem_Alloc(tempmempool, image_width * cinfo.output_components); - if (!image_rgba || !scanline) + if (!image_buffer || !scanline) { - if (image_rgba) - Mem_Free (image_rgba); + if (image_buffer) + Mem_Free (image_buffer); if (scanline) Mem_Free (scanline); @@ -554,17 +548,17 @@ unsigned char* JPEG_LoadImage (const unsigned char *f, int filesize, int matchwi qjpeg_read_scanlines (&cinfo, &scanline, 1); - // Convert the image to RGBA + // Convert the image to BGRA switch (cinfo.output_components) { // RGB images case 3: - buffer_ptr = &image_rgba[image_width * line * 4]; + buffer_ptr = &image_buffer[image_width * line * 4]; for (ind = 0; ind < image_width * 3; ind += 3, buffer_ptr += 4) { - buffer_ptr[0] = scanline[ind]; + buffer_ptr[2] = scanline[ind]; buffer_ptr[1] = scanline[ind + 1]; - buffer_ptr[2] = scanline[ind + 2]; + buffer_ptr[0] = scanline[ind + 2]; buffer_ptr[3] = 255; } break; @@ -572,7 +566,7 @@ unsigned char* JPEG_LoadImage (const unsigned char *f, int filesize, int matchwi // Greyscale images (default to it, just in case) case 1: default: - buffer_ptr = &image_rgba[image_width * line * 4]; + buffer_ptr = &image_buffer[image_width * line * 4]; for (ind = 0; ind < image_width; ind++, buffer_ptr += 4) { buffer_ptr[0] = scanline[ind]; @@ -589,7 +583,7 @@ unsigned char* JPEG_LoadImage (const unsigned char *f, int filesize, int matchwi qjpeg_finish_decompress (&cinfo); qjpeg_destroy_decompress (&cinfo); - return image_rgba; + return image_buffer; } diff --git a/jpeg.h b/jpeg.h index a657e7c3..ccc86b8a 100644 --- a/jpeg.h +++ b/jpeg.h @@ -27,7 +27,7 @@ qboolean JPEG_OpenLibrary (void); void JPEG_CloseLibrary (void); -unsigned char* JPEG_LoadImage (const unsigned char *f, int filesize, int matchwidth, int matchheight); +unsigned char* JPEG_LoadImage_BGRA (const unsigned char *f, int filesize); qboolean JPEG_SaveImage_preflipped (const char *filename, int width, int height, unsigned char *data); diff --git a/menu.c b/menu.c index 54e2e520..7bde1b9d 100644 --- a/menu.c +++ b/menu.c @@ -218,35 +218,6 @@ static void M_DrawPic(float cx, float cy, const char *picname) DrawQ_Pic(menu_x + cx, menu_y + cy, Draw_CachePic(picname, true), 0, 0, 1, 1, 1, 1, 0); } -static unsigned char identityTable[256]; -static unsigned char translationTable[256]; - -static void M_BuildTranslationTable(int top, int bottom) -{ - int j; - unsigned char *dest, *source; - - for (j = 0; j < 256; j++) - identityTable[j] = j; - dest = translationTable; - source = identityTable; - memcpy (dest, source, 256); - - // LordHavoc: corrected skin color ranges - if (top < 128 || (top >= 224 && top < 240)) // the artists made some backwards ranges. sigh. - memcpy (dest + TOP_RANGE, source + top, 16); - else - for (j=0 ; j<16 ; j++) - dest[TOP_RANGE+j] = source[top+15-j]; - - // LordHavoc: corrected skin color ranges - if (bottom < 128 || (bottom >= 224 && bottom < 240)) - memcpy (dest + BOTTOM_RANGE, source + bottom, 16); - else - for (j=0 ; j<16 ; j++) - dest[BOTTOM_RANGE+j] = source[bottom+15-j]; -} - static void M_DrawTextBox(float x, float y, float width, float height) { int n; @@ -1350,7 +1321,7 @@ static int setup_rateindex(int rate) static void M_Setup_Draw (void) { - int i; + int i, j; cachepic_t *p; M_Background(320, 200); @@ -1378,22 +1349,28 @@ static void M_Setup_Draw (void) // LordHavoc: rewrote this code greatly if (menuplyr_load) { - unsigned char *data, *f; + unsigned char *f; fs_offset_t filesize; menuplyr_load = false; menuplyr_top = -1; menuplyr_bottom = -1; - if ((f = FS_LoadFile("gfx/menuplyr.lmp", tempmempool, true, &filesize))) + f = FS_LoadFile("gfx/menuplyr.lmp", tempmempool, true, &filesize); + if (f && filesize >= 9) { - data = LoadLMP (f, filesize, 0, 0, true); - menuplyr_width = image_width; - menuplyr_height = image_height; - Mem_Free(f); - menuplyr_pixels = (unsigned char *)Mem_Alloc(cls.permanentmempool, menuplyr_width * menuplyr_height); - menuplyr_translated = (unsigned int *)Mem_Alloc(cls.permanentmempool, menuplyr_width * menuplyr_height * 4); - memcpy(menuplyr_pixels, data, menuplyr_width * menuplyr_height); - Mem_Free(data); + int width, height; + width = f[0] + f[1] * 256 + f[2] * 65536 + f[3] * 16777216; + height = f[4] + f[5] * 256 + f[6] * 65536 + f[7] * 16777216; + if (filesize >= 8 + width * height) + { + menuplyr_width = width; + menuplyr_height = height; + menuplyr_pixels = (unsigned char *)Mem_Alloc(cls.permanentmempool, width * height); + menuplyr_translated = (unsigned int *)Mem_Alloc(cls.permanentmempool, width * height * 4); + memcpy(menuplyr_pixels, f + 8, width * height); + } } + if (f) + Mem_Free(f); } if (menuplyr_pixels) @@ -1402,9 +1379,26 @@ static void M_Setup_Draw (void) { menuplyr_top = setup_top; menuplyr_bottom = setup_bottom; - M_BuildTranslationTable(menuplyr_top*16, menuplyr_bottom*16); + for (i = 0;i < menuplyr_width * menuplyr_height;i++) - menuplyr_translated[i] = palette_transparent[translationTable[menuplyr_pixels[i]]]; + { + j = menuplyr_pixels[i]; + if (j >= TOP_RANGE && j < TOP_RANGE + 16) + { + if (menuplyr_top < 8 || menuplyr_top == 14) + j = menuplyr_top * 16 + (j - TOP_RANGE); + else + j = menuplyr_top * 16 + 15-(j - TOP_RANGE); + } + else if (j >= BOTTOM_RANGE && j < BOTTOM_RANGE + 16) + { + if (menuplyr_bottom < 8 || menuplyr_bottom == 14) + j = menuplyr_bottom * 16 + (j - BOTTOM_RANGE); + else + j = menuplyr_bottom * 16 + 15-(j - BOTTOM_RANGE); + } + menuplyr_translated[i] = palette_bgra_transparent[j]; + } Draw_NewPic("gfx/menuplyr", menuplyr_width, menuplyr_height, true, (unsigned char *)menuplyr_translated); } M_DrawPic(160, 48, "gfx/bigbox"); diff --git a/model_alias.c b/model_alias.c index 11a1f507..0179e821 100644 --- a/model_alias.c +++ b/model_alias.c @@ -1022,7 +1022,7 @@ void Mod_IDP0_Load(model_t *mod, void *buffer, void *bufferend) { tempskinframe = R_SkinFrame_LoadExternal(name, (r_mipskins.integer ? TEXF_MIPMAP : 0) | TEXF_ALPHA | TEXF_PICMIP | TEXF_COMPRESS, false); if (!tempskinframe) - tempskinframe = R_SkinFrame_LoadInternal(name, (r_mipskins.integer ? TEXF_MIPMAP : 0) | TEXF_PICMIP, true, r_fullbrights.integer, (unsigned char *)datapointer, skinwidth, skinheight, 8, NULL, NULL); + tempskinframe = R_SkinFrame_LoadInternalQuake(name, (r_mipskins.integer ? TEXF_MIPMAP : 0) | TEXF_PICMIP, true, r_fullbrights.integer, (unsigned char *)datapointer, skinwidth, skinheight); Mod_BuildAliasSkinFromSkinFrame(loadmodel->data_textures + totalskins * loadmodel->num_surfaces, tempskinframe); } datapointer += skinwidth * skinheight; diff --git a/model_brush.c b/model_brush.c index 055dd106..23264b20 100644 --- a/model_brush.c +++ b/model_brush.c @@ -1272,14 +1272,6 @@ void R_Q1BSP_LoadSplitSky (unsigned char *src, int width, int height, int bytesp if (loadmodel->texturepool == NULL && cls.state != ca_dedicated) loadmodel->texturepool = R_AllocTexturePool(); - // if sky isn't the right size, just use it as a solid layer - if (width != 256 || height != 128) - { - loadmodel->brush.solidskytexture = R_LoadTexture2D(loadmodel->texturepool, "sky_solidtexture", width, height, src, bytesperpixel == 4 ? TEXTYPE_RGBA : TEXTYPE_PALETTE, TEXF_PRECACHE, bytesperpixel == 1 ? palette_complete : NULL); - loadmodel->brush.alphaskytexture = NULL; - return; - } - if (bytesperpixel == 4) { for (i = 0;i < 128;i++) @@ -1301,34 +1293,35 @@ void R_Q1BSP_LoadSplitSky (unsigned char *src, int width, int height, int bytesp unsigned int i; unsigned char b[4]; } - rgba; + bgra; r = g = b = 0; for (i = 0;i < 128;i++) { for (j = 0;j < 128;j++) { - rgba.i = palette_complete[src[i*256 + j + 128]]; - r += rgba.b[0]; - g += rgba.b[1]; - b += rgba.b[2]; + p = src[i*256 + j + 128]; + r += palette_rgb[p][0]; + g += palette_rgb[p][1]; + b += palette_rgb[p][2]; } } - rgba.b[0] = r/(128*128); - rgba.b[1] = g/(128*128); - rgba.b[2] = b/(128*128); - rgba.b[3] = 0; + bgra.b[2] = r/(128*128); + bgra.b[1] = g/(128*128); + bgra.b[0] = b/(128*128); + bgra.b[3] = 0; for (i = 0;i < 128;i++) { for (j = 0;j < 128;j++) { - solidpixels[(i*128) + j] = palette_complete[src[i*256 + j + 128]]; - alphapixels[(i*128) + j] = (p = src[i*256 + j]) ? palette_complete[p] : rgba.i; + solidpixels[(i*128) + j] = palette_bgra_complete[src[i*256 + j + 128]]; + p = src[i*256 + j]; + alphapixels[(i*128) + j] = p ? palette_bgra_complete[p] : bgra.i; } } } - loadmodel->brush.solidskytexture = R_LoadTexture2D(loadmodel->texturepool, "sky_solidtexture", 128, 128, (unsigned char *) solidpixels, TEXTYPE_RGBA, TEXF_PRECACHE, NULL); - loadmodel->brush.alphaskytexture = R_LoadTexture2D(loadmodel->texturepool, "sky_alphatexture", 128, 128, (unsigned char *) alphapixels, TEXTYPE_RGBA, TEXF_ALPHA | TEXF_PRECACHE, NULL); + loadmodel->brush.solidskytexture = R_LoadTexture2D(loadmodel->texturepool, "sky_solidtexture", 128, 128, (unsigned char *) solidpixels, TEXTYPE_BGRA, TEXF_PRECACHE, NULL); + loadmodel->brush.alphaskytexture = R_LoadTexture2D(loadmodel->texturepool, "sky_alphatexture", 128, 128, (unsigned char *) alphapixels, TEXTYPE_BGRA, TEXF_ALPHA | TEXF_PRECACHE, NULL); } static void Mod_Q1BSP_LoadTextures(lump_t *l) @@ -1508,8 +1501,8 @@ static void Mod_Q1BSP_LoadTextures(lump_t *l) { if (loadmodel->isworldmodel) { - data = loadimagepixels(tx->name, false, 0, 0, false); - if (data) + data = loadimagepixelsbgra(tx->name, false, false); + if (data && image_width == 256 && image_height == 128) { R_Q1BSP_LoadSplitSky(data, image_width, image_height, 4); Mem_Free(data); @@ -1532,20 +1525,20 @@ static void Mod_Q1BSP_LoadTextures(lump_t *l) unsigned char *pixels, *freepixels; pixels = freepixels = NULL; if (mtdata) - pixels = W_ConvertWAD3Texture(dmiptex); + pixels = W_ConvertWAD3TextureBGRA(dmiptex); if (pixels == NULL) - pixels = freepixels = W_GetTexture(tx->name); + pixels = freepixels = W_GetTextureBGRA(tx->name); if (pixels != NULL) { tx->width = image_width; tx->height = image_height; - skinframe = R_SkinFrame_LoadInternal(tx->name, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE | (r_picmipworld.integer ? TEXF_PICMIP : 0), false, false, pixels, image_width, image_height, 32, NULL, NULL); + skinframe = R_SkinFrame_LoadInternalBGRA(tx->name, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE | (r_picmipworld.integer ? TEXF_PICMIP : 0), pixels, image_width, image_height); } if (freepixels) Mem_Free(freepixels); } else if (mtdata) // texture included - skinframe = R_SkinFrame_LoadInternal(tx->name, TEXF_MIPMAP | TEXF_PRECACHE | (r_picmipworld.integer ? TEXF_PICMIP : 0), false, r_fullbrights.integer, mtdata, tx->width, tx->height, 8, NULL, NULL); + skinframe = R_SkinFrame_LoadInternalQuake(tx->name, TEXF_MIPMAP | TEXF_PRECACHE | (r_picmipworld.integer ? TEXF_PICMIP : 0), false, r_fullbrights.integer, mtdata, tx->width, tx->height); } // if skinframe is still NULL the "missing" texture will be used if (skinframe) @@ -2400,9 +2393,9 @@ static void Mod_Q1BSP_LoadFaces(lump_t *l) if (loadmodel->texturepool == NULL) loadmodel->texturepool = R_AllocTexturePool(); // could not find room, make a new lightmap - lightmaptexture = R_LoadTexture2D(loadmodel->texturepool, va("lightmap%i", lightmapnumber), lightmapsize, lightmapsize, NULL, TEXTYPE_RGBA, TEXF_FORCELINEAR | TEXF_PRECACHE, NULL); + lightmaptexture = R_LoadTexture2D(loadmodel->texturepool, va("lightmap%i", lightmapnumber), lightmapsize, lightmapsize, NULL, TEXTYPE_BGRA, TEXF_FORCELINEAR | TEXF_PRECACHE, NULL); if (loadmodel->brushq1.nmaplightdata) - deluxemaptexture = R_LoadTexture2D(loadmodel->texturepool, va("deluxemap%i", lightmapnumber), lightmapsize, lightmapsize, NULL, TEXTYPE_RGBA, TEXF_FORCELINEAR | TEXF_PRECACHE, NULL); + deluxemaptexture = R_LoadTexture2D(loadmodel->texturepool, va("deluxemap%i", lightmapnumber), lightmapsize, lightmapsize, NULL, TEXTYPE_BGRA, TEXF_FORCELINEAR | TEXF_PRECACHE, NULL); lightmapnumber++; memset(lightmap_lineused, 0, sizeof(lightmap_lineused)); Mod_Q1BSP_AllocLightmapBlock(lightmap_lineused, lightmapsize, lightmapsize, ssize, tsize, &lightmapx, &lightmapy); @@ -4535,9 +4528,9 @@ static void Mod_Q3BSP_LoadLightmaps(lump_t *l, lump_t *faceslump) int lightmapindex = i >> (loadmodel->brushq3.deluxemapping + power2); for (k = 0;k < 128*128;k++) { - convertedpixels[k*4+0] = in[i].rgb[k*3+0]; + convertedpixels[k*4+2] = in[i].rgb[k*3+0]; convertedpixels[k*4+1] = in[i].rgb[k*3+1]; - convertedpixels[k*4+2] = in[i].rgb[k*3+2]; + convertedpixels[k*4+0] = in[i].rgb[k*3+2]; convertedpixels[k*4+3] = 255; } if (loadmodel->brushq3.num_lightmapmergepower > 0) @@ -4557,9 +4550,9 @@ static void Mod_Q3BSP_LoadLightmaps(lump_t *l, lump_t *faceslump) for (mergeheight = 1;mergewidth*mergeheight < j && mergeheight < (1 << power);mergeheight *= 2) ; Con_DPrintf("lightmap merge texture #%i is %ix%i (%i of %i used)\n", lightmapindex, mergewidth*128, mergeheight*128, min(j, mergewidth*mergeheight), mergewidth*mergeheight); - loadmodel->brushq3.data_lightmaps[lightmapindex] = R_LoadTexture2D(loadmodel->texturepool, va("lightmap%04i", lightmapindex), mergewidth * 128, mergeheight * 128, NULL, TEXTYPE_RGBA, TEXF_FORCELINEAR | TEXF_PRECACHE | (gl_texturecompression_q3bsplightmaps.integer ? TEXF_COMPRESS : 0), NULL); + loadmodel->brushq3.data_lightmaps[lightmapindex] = R_LoadTexture2D(loadmodel->texturepool, va("lightmap%04i", lightmapindex), mergewidth * 128, mergeheight * 128, NULL, TEXTYPE_BGRA, TEXF_FORCELINEAR | TEXF_PRECACHE | (gl_texturecompression_q3bsplightmaps.integer ? TEXF_COMPRESS : 0), NULL); if (loadmodel->brushq3.data_deluxemaps) - loadmodel->brushq3.data_deluxemaps[lightmapindex] = R_LoadTexture2D(loadmodel->texturepool, va("deluxemap%04i", lightmapindex), mergewidth * 128, mergeheight * 128, NULL, TEXTYPE_RGBA, TEXF_FORCELINEAR | TEXF_PRECACHE | (gl_texturecompression_q3bspdeluxemaps.integer ? TEXF_COMPRESS : 0), NULL); + loadmodel->brushq3.data_deluxemaps[lightmapindex] = R_LoadTexture2D(loadmodel->texturepool, va("deluxemap%04i", lightmapindex), mergewidth * 128, mergeheight * 128, NULL, TEXTYPE_BGRA, TEXF_FORCELINEAR | TEXF_PRECACHE | (gl_texturecompression_q3bspdeluxemaps.integer ? TEXF_COMPRESS : 0), NULL); } mergewidth = R_TextureWidth(loadmodel->brushq3.data_lightmaps[lightmapindex]) / 128; mergeheight = R_TextureHeight(loadmodel->brushq3.data_lightmaps[lightmapindex]) / 128; @@ -4573,9 +4566,9 @@ static void Mod_Q3BSP_LoadLightmaps(lump_t *l, lump_t *faceslump) { // figure out which merged lightmap texture this fits into if (loadmodel->brushq3.deluxemapping && (i & 1)) - loadmodel->brushq3.data_deluxemaps[lightmapindex] = R_LoadTexture2D(loadmodel->texturepool, va("deluxemap%04i", lightmapindex), 128, 128, convertedpixels, TEXTYPE_RGBA, TEXF_FORCELINEAR | TEXF_PRECACHE | (gl_texturecompression_q3bspdeluxemaps.integer ? TEXF_COMPRESS : 0), NULL); + loadmodel->brushq3.data_deluxemaps[lightmapindex] = R_LoadTexture2D(loadmodel->texturepool, va("deluxemap%04i", lightmapindex), 128, 128, convertedpixels, TEXTYPE_BGRA, TEXF_FORCELINEAR | TEXF_PRECACHE | (gl_texturecompression_q3bspdeluxemaps.integer ? TEXF_COMPRESS : 0), NULL); else - loadmodel->brushq3.data_lightmaps [lightmapindex] = R_LoadTexture2D(loadmodel->texturepool, va("lightmap%04i", lightmapindex), 128, 128, convertedpixels, TEXTYPE_RGBA, TEXF_FORCELINEAR | TEXF_PRECACHE | (gl_texturecompression_q3bsplightmaps.integer ? TEXF_COMPRESS : 0), NULL); + loadmodel->brushq3.data_lightmaps [lightmapindex] = R_LoadTexture2D(loadmodel->texturepool, va("lightmap%04i", lightmapindex), 128, 128, convertedpixels, TEXTYPE_BGRA, TEXF_FORCELINEAR | TEXF_PRECACHE | (gl_texturecompression_q3bsplightmaps.integer ? TEXF_COMPRESS : 0), NULL); } } } diff --git a/model_shared.c b/model_shared.c index 4db8ee98..17671105 100644 --- a/model_shared.c +++ b/model_shared.c @@ -1030,7 +1030,7 @@ void Mod_ShadowMesh_Free(shadowmesh_t *mesh) } } -void Mod_GetTerrainVertex3fTexCoord2fFromRGBA(const unsigned char *imagepixels, int imagewidth, int imageheight, int ix, int iy, float *vertex3f, float *texcoord2f, matrix4x4_t *pixelstepmatrix, matrix4x4_t *pixeltexturestepmatrix) +void Mod_GetTerrainVertex3fTexCoord2fFromBGRA(const unsigned char *imagepixels, int imagewidth, int imageheight, int ix, int iy, float *vertex3f, float *texcoord2f, matrix4x4_t *pixelstepmatrix, matrix4x4_t *pixeltexturestepmatrix) { float v[3], tc[3]; v[0] = ix; @@ -1045,16 +1045,16 @@ void Mod_GetTerrainVertex3fTexCoord2fFromRGBA(const unsigned char *imagepixels, texcoord2f[1] = tc[1]; } -void Mod_GetTerrainVertexFromRGBA(const unsigned char *imagepixels, int imagewidth, int imageheight, int ix, int iy, float *vertex3f, float *svector3f, float *tvector3f, float *normal3f, float *texcoord2f, matrix4x4_t *pixelstepmatrix, matrix4x4_t *pixeltexturestepmatrix) +void Mod_GetTerrainVertexFromBGRA(const unsigned char *imagepixels, int imagewidth, int imageheight, int ix, int iy, float *vertex3f, float *svector3f, float *tvector3f, float *normal3f, float *texcoord2f, matrix4x4_t *pixelstepmatrix, matrix4x4_t *pixeltexturestepmatrix) { float vup[3], vdown[3], vleft[3], vright[3]; float tcup[3], tcdown[3], tcleft[3], tcright[3]; float sv[3], tv[3], nl[3]; - Mod_GetTerrainVertex3fTexCoord2fFromRGBA(imagepixels, imagewidth, imageheight, ix, iy, vertex3f, texcoord2f, pixelstepmatrix, pixeltexturestepmatrix); - Mod_GetTerrainVertex3fTexCoord2fFromRGBA(imagepixels, imagewidth, imageheight, ix, iy - 1, vup, tcup, pixelstepmatrix, pixeltexturestepmatrix); - Mod_GetTerrainVertex3fTexCoord2fFromRGBA(imagepixels, imagewidth, imageheight, ix, iy + 1, vdown, tcdown, pixelstepmatrix, pixeltexturestepmatrix); - Mod_GetTerrainVertex3fTexCoord2fFromRGBA(imagepixels, imagewidth, imageheight, ix - 1, iy, vleft, tcleft, pixelstepmatrix, pixeltexturestepmatrix); - Mod_GetTerrainVertex3fTexCoord2fFromRGBA(imagepixels, imagewidth, imageheight, ix + 1, iy, vright, tcright, pixelstepmatrix, pixeltexturestepmatrix); + Mod_GetTerrainVertex3fTexCoord2fFromBGRA(imagepixels, imagewidth, imageheight, ix, iy, vertex3f, texcoord2f, pixelstepmatrix, pixeltexturestepmatrix); + Mod_GetTerrainVertex3fTexCoord2fFromBGRA(imagepixels, imagewidth, imageheight, ix, iy - 1, vup, tcup, pixelstepmatrix, pixeltexturestepmatrix); + Mod_GetTerrainVertex3fTexCoord2fFromBGRA(imagepixels, imagewidth, imageheight, ix, iy + 1, vdown, tcdown, pixelstepmatrix, pixeltexturestepmatrix); + Mod_GetTerrainVertex3fTexCoord2fFromBGRA(imagepixels, imagewidth, imageheight, ix - 1, iy, vleft, tcleft, pixelstepmatrix, pixeltexturestepmatrix); + Mod_GetTerrainVertex3fTexCoord2fFromBGRA(imagepixels, imagewidth, imageheight, ix + 1, iy, vright, tcright, pixelstepmatrix, pixeltexturestepmatrix); Mod_BuildBumpVectors(vertex3f, vup, vright, texcoord2f, tcup, tcright, svector3f, tvector3f, normal3f); Mod_BuildBumpVectors(vertex3f, vright, vdown, texcoord2f, tcright, tcdown, sv, tv, nl); VectorAdd(svector3f, sv, svector3f); @@ -1070,7 +1070,7 @@ void Mod_GetTerrainVertexFromRGBA(const unsigned char *imagepixels, int imagewid VectorAdd(normal3f, nl, normal3f); } -void Mod_ConstructTerrainPatchFromRGBA(const unsigned char *imagepixels, int imagewidth, int imageheight, int x1, int y1, int width, int height, int *element3i, int *neighbor3i, float *vertex3f, float *svector3f, float *tvector3f, float *normal3f, float *texcoord2f, matrix4x4_t *pixelstepmatrix, matrix4x4_t *pixeltexturestepmatrix) +void Mod_ConstructTerrainPatchFromBGRA(const unsigned char *imagepixels, int imagewidth, int imageheight, int x1, int y1, int width, int height, int *element3i, int *neighbor3i, float *vertex3f, float *svector3f, float *tvector3f, float *normal3f, float *texcoord2f, matrix4x4_t *pixelstepmatrix, matrix4x4_t *pixeltexturestepmatrix) { int x, y, ix, iy, *e; e = element3i; @@ -1090,7 +1090,7 @@ void Mod_ConstructTerrainPatchFromRGBA(const unsigned char *imagepixels, int ima Mod_BuildTriangleNeighbors(neighbor3i, element3i, width*height*2); for (y = 0, iy = y1;y < height + 1;y++, iy++) for (x = 0, ix = x1;x < width + 1;x++, ix++, vertex3f += 3, texcoord2f += 2, svector3f += 3, tvector3f += 3, normal3f += 3) - Mod_GetTerrainVertexFromRGBA(imagepixels, imagewidth, imageheight, ix, iy, vertex3f, texcoord2f, svector3f, tvector3f, normal3f, pixelstepmatrix, pixeltexturestepmatrix); + Mod_GetTerrainVertexFromBGRA(imagepixels, imagewidth, imageheight, ix, iy, vertex3f, texcoord2f, svector3f, tvector3f, normal3f, pixelstepmatrix, pixeltexturestepmatrix); } q3wavefunc_t Mod_LoadQ3Shaders_EnumerateWaveFunc(const char *s) diff --git a/model_sprite.c b/model_sprite.c index 8fec8a66..ed618b53 100644 --- a/model_sprite.c +++ b/model_sprite.c @@ -59,7 +59,7 @@ static void Mod_SpriteSetupTexture(texture_t *texture, skinframe_t *skinframe, q texture->currentskinframe = texture->skinframes[0] = skinframe; } -static void Mod_Sprite_SharedSetup(const unsigned char *datapointer, int version, const unsigned int *palette, const unsigned int *alphapalette, qboolean additive) +static void Mod_Sprite_SharedSetup(const unsigned char *datapointer, int version, const unsigned int *palette, qboolean additive) { int i, j, groupframes, realframes, x, y, origin[2], width, height, fullbright; dspriteframetype_t *pinframetype; @@ -181,19 +181,32 @@ static void Mod_Sprite_SharedSetup(const unsigned char *datapointer, int version if (width > 0 && height > 0) { if (groupframes > 1) + { sprintf (name, "%s_%i_%i", loadmodel->name, i, j); + sprintf (fogname, "%s_%i_%ifog", loadmodel->name, i, j); + } else + { sprintf (name, "%s_%i", loadmodel->name, i); + sprintf (fogname, "%s_%ifog", loadmodel->name, i); + } if (!(skinframe = R_SkinFrame_LoadExternal(name, texflags | TEXF_COMPRESS, false))) { - if (groupframes > 1) - sprintf (fogname, "%s_%i_%ifog", loadmodel->name, i, j); - else - sprintf (fogname, "%s_%ifog", loadmodel->name, i); + unsigned char *pixels = Mem_Alloc(loadmodel->mempool, width*height*4); if (version == SPRITE32_VERSION) - skinframe = R_SkinFrame_LoadInternal(name, texflags, false, false, datapointer, width, height, 32, NULL, NULL); - else //if (version == SPRITE_VERSION || version == SPRITEHL_VERSION) - skinframe = R_SkinFrame_LoadInternal(name, texflags, false, false, datapointer, width, height, 8, palette, alphapalette); + { + for (x = 0;x < width*height;x++) + { + pixels[i*4+2] = datapointer[i*4+0]; + pixels[i*4+1] = datapointer[i*4+1]; + pixels[i*4+0] = datapointer[i*4+2]; + pixels[i*4+3] = datapointer[i*4+3]; + } + } + else //if (version == SPRITEHL_VERSION || version == SPRITE_VERSION) + Image_Copy8bitBGRA(datapointer, pixels, width*height, palette ? palette : palette_bgra_transparent); + skinframe = R_SkinFrame_LoadInternalBGRA(name, texflags, pixels, width, height); + Mem_Free(pixels); } } if (skinframe == NULL) @@ -251,12 +264,12 @@ void Mod_IDSP_Load(model_t *mod, void *buffer, void *bufferend) loadmodel->sprite.sprnum_type = LittleLong (pinqsprite->type); loadmodel->synctype = (synctype_t)LittleLong (pinqsprite->synctype); - Mod_Sprite_SharedSetup(datapointer, LittleLong (pinqsprite->version), NULL, NULL, false); + Mod_Sprite_SharedSetup(datapointer, LittleLong (pinqsprite->version), NULL, false); } else if (version == SPRITEHL_VERSION) { int i, rendermode; - unsigned char palette[256][4], alphapalette[256][4]; + unsigned char palette[256][4]; const unsigned char *in; dspritehl_t *pinhlsprite; @@ -280,18 +293,18 @@ void Mod_IDSP_Load(model_t *mod, void *buffer, void *bufferend) case SPRHL_OPAQUE: for (i = 0;i < 256;i++) { - palette[i][0] = *in++; - palette[i][1] = *in++; - palette[i][2] = *in++; + palette[i][2] = in[i*3+0]; + palette[i][1] = in[i*3+1]; + palette[i][0] = in[i*3+2]; palette[i][3] = 255; } break; case SPRHL_ADDITIVE: for (i = 0;i < 256;i++) { - palette[i][0] = *in++; - palette[i][1] = *in++; - palette[i][2] = *in++; + palette[i][2] = in[i*3+0]; + palette[i][1] = in[i*3+1]; + palette[i][0] = in[i*3+2]; palette[i][3] = 255; } // also passes additive == true to Mod_Sprite_SharedSetup @@ -299,9 +312,9 @@ void Mod_IDSP_Load(model_t *mod, void *buffer, void *bufferend) case SPRHL_INDEXALPHA: for (i = 0;i < 256;i++) { - palette[i][0] = in[765]; + palette[i][2] = in[765]; palette[i][1] = in[766]; - palette[i][2] = in[767]; + palette[i][0] = in[767]; palette[i][3] = i; in += 3; } @@ -309,9 +322,9 @@ void Mod_IDSP_Load(model_t *mod, void *buffer, void *bufferend) case SPRHL_ALPHATEST: for (i = 0;i < 256;i++) { - palette[i][0] = *in++; - palette[i][1] = *in++; - palette[i][2] = *in++; + palette[i][2] = in[i*3+0]; + palette[i][1] = in[i*3+1]; + palette[i][0] = in[i*3+2]; palette[i][3] = 255; } palette[255][0] = palette[255][1] = palette[255][2] = palette[255][3] = 0; @@ -322,15 +335,7 @@ void Mod_IDSP_Load(model_t *mod, void *buffer, void *bufferend) return; } - for (i = 0;i < 256;i++) - { - alphapalette[i][0] = 255; - alphapalette[i][1] = 255; - alphapalette[i][2] = 255; - alphapalette[i][3] = palette[i][3]; - } - - Mod_Sprite_SharedSetup(datapointer, LittleLong (pinhlsprite->version), (unsigned int *)(&palette[0][0]), (unsigned int *)(&alphapalette[0][0]), rendermode == SPRHL_ADDITIVE); + Mod_Sprite_SharedSetup(datapointer, LittleLong (pinhlsprite->version), (unsigned int *)(&palette[0][0]), rendermode == SPRHL_ADDITIVE); } else Host_Error("Mod_IDSP_Load: %s has wrong version number (%i). Only %i (quake), %i (HalfLife), and %i (sprite32) supported", diff --git a/palette.c b/palette.c index 266a992a..e73e8192 100644 --- a/palette.c +++ b/palette.c @@ -3,20 +3,22 @@ cvar_t r_colormap_palette = {0, "r_colormap_palette", "gfx/colormap_palette.lmp", "name of a palette lmp file to override the shirt/pants colors of player models. It consists of 16 shirt colors, 16 scoreboard shirt colors, 16 pants colors and 16 scoreboard pants colors"}; -unsigned int palette_complete[256]; -unsigned int palette_font[256]; -unsigned int palette_alpha[256]; -unsigned int palette_nocolormap[256]; -unsigned int palette_nocolormapnofullbrights[256]; -unsigned int palette_nofullbrights[256]; -unsigned int palette_onlyfullbrights[256]; -unsigned int palette_pantsaswhite[256]; -unsigned int palette_shirtaswhite[256]; -unsigned int palette_transparent[256]; -unsigned int palette_pantscolormap[16]; -unsigned int palette_shirtcolormap[16]; -unsigned int palette_pantsscoreboard[16]; -unsigned int palette_shirtscoreboard[16]; +unsigned char palette_rgb[256][3]; +unsigned char palette_rgb_pantscolormap[16][3]; +unsigned char palette_rgb_shirtcolormap[16][3]; +unsigned char palette_rgb_pantsscoreboard[16][3]; +unsigned char palette_rgb_shirtscoreboard[16][3]; + +unsigned int palette_bgra_complete[256]; +unsigned int palette_bgra_font[256]; +unsigned int palette_bgra_alpha[256]; +unsigned int palette_bgra_nocolormap[256]; +unsigned int palette_bgra_nocolormapnofullbrights[256]; +unsigned int palette_bgra_nofullbrights[256]; +unsigned int palette_bgra_onlyfullbrights[256]; +unsigned int palette_bgra_pantsaswhite[256]; +unsigned int palette_bgra_shirtaswhite[256]; +unsigned int palette_bgra_transparent[256]; // John Carmack said the quake palette.lmp can be considered public domain because it is not an important asset to id, so I include it here as a fallback if no external palette file is found. unsigned char host_quakepal[768] = @@ -100,62 +102,62 @@ void Palette_SetupSpecialPalettes(void) transparentcolor = 255; for (i = 0;i < 256;i++) - palette_transparent[i] = palette_complete[i]; - palette_transparent[transparentcolor] = 0; + palette_bgra_transparent[i] = palette_bgra_complete[i]; + palette_bgra_transparent[transparentcolor] = 0; for (i = 0;i < fullbright_start;i++) - palette_nofullbrights[i] = palette_complete[i]; + palette_bgra_nofullbrights[i] = palette_bgra_complete[i]; for (i = fullbright_start;i < fullbright_end;i++) - palette_nofullbrights[i] = palette_complete[0]; + palette_bgra_nofullbrights[i] = palette_bgra_complete[0]; for (i = 0;i < 256;i++) - palette_onlyfullbrights[i] = 0; + palette_bgra_onlyfullbrights[i] = 0; for (i = fullbright_start;i < fullbright_end;i++) - palette_onlyfullbrights[i] = palette_complete[i]; + palette_bgra_onlyfullbrights[i] = palette_bgra_complete[i]; for (i = 0;i < 256;i++) - palette_nocolormapnofullbrights[i] = palette_complete[i]; + palette_bgra_nocolormapnofullbrights[i] = palette_bgra_complete[i]; for (i = pants_start;i < pants_end;i++) - palette_nocolormapnofullbrights[i] = 0; + palette_bgra_nocolormapnofullbrights[i] = 0; for (i = shirt_start;i < shirt_end;i++) - palette_nocolormapnofullbrights[i] = 0; + palette_bgra_nocolormapnofullbrights[i] = 0; for (i = fullbright_start;i < fullbright_end;i++) - palette_nocolormapnofullbrights[i] = 0; + palette_bgra_nocolormapnofullbrights[i] = 0; for (i = 0;i < 256;i++) - palette_nocolormap[i] = palette_complete[i]; + palette_bgra_nocolormap[i] = palette_bgra_complete[i]; for (i = pants_start;i < pants_end;i++) - palette_nocolormap[i] = 0; + palette_bgra_nocolormap[i] = 0; for (i = shirt_start;i < shirt_end;i++) - palette_nocolormap[i] = 0; + palette_bgra_nocolormap[i] = 0; for (i = 0;i < 256;i++) - palette_pantsaswhite[i] = 0; + palette_bgra_pantsaswhite[i] = 0; for (i = pants_start;i < pants_end;i++) { if (i >= reversed_start && i < reversed_end) - palette_pantsaswhite[i] = palette_complete[15 - (i - pants_start)]; + palette_bgra_pantsaswhite[i] = palette_bgra_complete[15 - (i - pants_start)]; else - palette_pantsaswhite[i] = palette_complete[i - pants_start]; + palette_bgra_pantsaswhite[i] = palette_bgra_complete[i - pants_start]; } for (i = 0;i < 256;i++) - palette_shirtaswhite[i] = 0; + palette_bgra_shirtaswhite[i] = 0; for (i = shirt_start;i < shirt_end;i++) { if (i >= reversed_start && i < reversed_end) - palette_shirtaswhite[i] = palette_complete[15 - (i - shirt_start)]; + palette_bgra_shirtaswhite[i] = palette_bgra_complete[15 - (i - shirt_start)]; else - palette_shirtaswhite[i] = palette_complete[i - shirt_start]; + palette_bgra_shirtaswhite[i] = palette_bgra_complete[i - shirt_start]; } for (i = 0;i < 256;i++) - palette_alpha[i] = 0xFFFFFFFF; - palette_alpha[transparentcolor] = 0; + palette_bgra_alpha[i] = 0xFFFFFFFF; + palette_bgra_alpha[transparentcolor] = 0; for (i = 0;i < 256;i++) - palette_font[i] = palette_complete[i]; - palette_font[0] = 0; + palette_bgra_font[i] = palette_bgra_complete[i]; + palette_bgra_font[0] = 0; } void BuildGammaTable8(float prescale, float gamma, float scale, float base, unsigned char *out, int rampsize) @@ -197,9 +199,10 @@ void Palette_NewMap(void) void Palette_Load(void) { int i; + unsigned char *out; float gamma, scale, base; fs_offset_t filesize; - unsigned char *in, *out, *palfile; + unsigned char *palfile; unsigned char texturegammaramp[256]; gamma = 1; @@ -225,89 +228,56 @@ void Palette_Load(void) palfile = (unsigned char *)FS_LoadFile ("gfx/palette.lmp", tempmempool, false, &filesize); if (palfile && filesize >= 768) - in = palfile; + memcpy(palette_rgb, palfile, 768); else { Con_DPrint("Couldn't load gfx/palette.lmp, falling back on internal palette\n"); - in = host_quakepal; + memcpy(palette_rgb, host_quakepal, 768); } - out = (unsigned char *) palette_complete; // palette is accessed as 32bit for speed reasons, but is created as 8bit bytes + if (palfile) + Mem_Free(palfile); + + out = (unsigned char *) palette_bgra_complete; // palette is accessed as 32bit for speed reasons, but is created as 8bit bytes for (i = 0;i < 256;i++) { - *out++ = texturegammaramp[*in++]; - *out++ = texturegammaramp[*in++]; - *out++ = texturegammaramp[*in++]; - *out++ = 255; + out[i*4+2] = texturegammaramp[palette_rgb[i][0]]; + out[i*4+1] = texturegammaramp[palette_rgb[i][1]]; + out[i*4+0] = texturegammaramp[palette_rgb[i][2]]; + out[i*4+3] = 255; } - if (palfile) - Mem_Free(palfile); -if(*r_colormap_palette.string) - palfile = (unsigned char *)FS_LoadFile (r_colormap_palette.string, tempmempool, false, &filesize); -else - palfile = NULL; + if(*r_colormap_palette.string) + palfile = (unsigned char *)FS_LoadFile (r_colormap_palette.string, tempmempool, false, &filesize); + else + palfile = NULL; -in = palfile; -if (palfile && filesize >= 48) -{ - out = (unsigned char *) palette_shirtcolormap; - for (i = 0;i < 16;i++) + if (palfile && filesize >= 48*2) { - *out++ = texturegammaramp[*in++]; - *out++ = texturegammaramp[*in++]; - *out++ = texturegammaramp[*in++]; - *out++ = 255; + memcpy(palette_rgb_shirtcolormap[0], palfile, 48); + memcpy(palette_rgb_shirtscoreboard[0], palfile + 48, 48); } -} -else - for(i = 0; i < 16; ++i) - palette_shirtcolormap[i] = palette_complete[(i << 4) | ((i >= 8 && i <= 13) ? 0x04 : 0x0C)]; - -if(palfile && filesize >= 48 + 48) -{ - out = (unsigned char *) palette_shirtscoreboard; - for (i = 0;i < 16;i++) + else { - *out++ = texturegammaramp[*in++]; - *out++ = texturegammaramp[*in++]; - *out++ = texturegammaramp[*in++]; - *out++ = 255; + for(i = 0;i < 16;i++) + { + VectorCopy(palette_rgb[(i << 4) | ((i >= 8 && i <= 13) ? 0x04 : 0x0C)], palette_rgb_shirtcolormap[i]); + VectorCopy(palette_rgb[(i << 4) | 0x08], palette_rgb_shirtscoreboard[i]); + } } -} -else - for(i = 0; i < 16; ++i) - palette_shirtscoreboard[i] = palette_complete[(i << 4) | 0x08]; -if (palfile && filesize >= 48 + 48 + 48) -{ - out = (unsigned char *) palette_pantscolormap; - for (i = 0;i < 16;i++) + if (palfile && filesize >= 48*4) { - *out++ = texturegammaramp[*in++]; - *out++ = texturegammaramp[*in++]; - *out++ = texturegammaramp[*in++]; - *out++ = 255; + memcpy(palette_rgb_pantscolormap[0], palfile + 48*2, 48); + memcpy(palette_rgb_pantsscoreboard[0], palfile + 48*3, 48); } -} -else - memcpy(palette_pantscolormap, palette_shirtcolormap, sizeof(palette_pantscolormap)); - -if (palfile && filesize >= 48 + 48 + 48 + 48) -{ - out = (unsigned char *) palette_pantsscoreboard; - for (i = 0;i < 16;i++) + else { - *out++ = texturegammaramp[*in++]; - *out++ = texturegammaramp[*in++]; - *out++ = texturegammaramp[*in++]; - *out++ = 255; + memcpy(palette_rgb_pantscolormap, palette_rgb_shirtcolormap, sizeof(palette_rgb_pantscolormap)); + memcpy(palette_rgb_pantsscoreboard, palette_rgb_shirtscoreboard, sizeof(palette_rgb_pantsscoreboard)); } -} -else - memcpy(palette_pantsscoreboard, palette_shirtscoreboard, sizeof(palette_pantsscoreboard)); -if(palfile) - Mem_Free(palfile); + if(palfile) + Mem_Free(palfile); Palette_SetupSpecialPalettes(); } diff --git a/palette.h b/palette.h index 4a8fc0a3..e7603bb9 100644 --- a/palette.h +++ b/palette.h @@ -2,20 +2,22 @@ #ifndef PALLETE_H #define PALLETE_H -extern unsigned int palette_complete[256]; -extern unsigned int palette_font[256]; -extern unsigned int palette_alpha[256]; -extern unsigned int palette_nocolormap[256]; -extern unsigned int palette_nocolormapnofullbrights[256]; -extern unsigned int palette_nofullbrights[256]; -extern unsigned int palette_onlyfullbrights[256]; -extern unsigned int palette_pantsaswhite[256]; -extern unsigned int palette_shirtaswhite[256]; -extern unsigned int palette_transparent[256]; -extern unsigned int palette_pantscolormap[16]; -extern unsigned int palette_shirtcolormap[16]; -extern unsigned int palette_pantsscoreboard[16]; -extern unsigned int palette_shirtscoreboard[16]; +extern unsigned char palette_rgb[256][3]; +extern unsigned char palette_rgb_pantscolormap[16][3]; +extern unsigned char palette_rgb_shirtcolormap[16][3]; +extern unsigned char palette_rgb_pantsscoreboard[16][3]; +extern unsigned char palette_rgb_shirtscoreboard[16][3]; + +extern unsigned int palette_bgra_complete[256]; +extern unsigned int palette_bgra_font[256]; +extern unsigned int palette_bgra_alpha[256]; +extern unsigned int palette_bgra_nocolormap[256]; +extern unsigned int palette_bgra_nocolormapnofullbrights[256]; +extern unsigned int palette_bgra_nofullbrights[256]; +extern unsigned int palette_bgra_onlyfullbrights[256]; +extern unsigned int palette_bgra_pantsaswhite[256]; +extern unsigned int palette_bgra_shirtaswhite[256]; +extern unsigned int palette_bgra_transparent[256]; // used by hardware gamma functions in vid_* files void BuildGammaTable8(float prescale, float gamma, float scale, float base, unsigned char *out, int rampsize); diff --git a/r_explosion.c b/r_explosion.c index 9f5888dc..90a5fcf5 100644 --- a/r_explosion.c +++ b/r_explosion.c @@ -73,17 +73,17 @@ static void r_explosion_start(void) g = (j * 256) / 256; b = (j * 128) / 256; a = noise3[y][x] * 3 - 128; - data[y][x][0] = bound(0, r, 255); + data[y][x][2] = bound(0, r, 255); data[y][x][1] = bound(0, g, 255); - data[y][x][2] = bound(0, b, 255); + data[y][x][0] = bound(0, b, 255); data[y][x][3] = bound(0, a, 255); } } - explosiontexture = R_LoadTexture2D(explosiontexturepool, "explosiontexture", 128, 128, &data[0][0][0], TEXTYPE_RGBA, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE, NULL); + explosiontexture = R_LoadTexture2D(explosiontexturepool, "explosiontexture", 128, 128, &data[0][0][0], TEXTYPE_BGRA, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE, NULL); for (y = 0;y < 128;y++) for (x = 0;x < 128;x++) data[y][x][0] = data[y][x][1] = data[y][x][2] = 255; - explosiontexturefog = R_LoadTexture2D(explosiontexturepool, "explosiontexturefog", 128, 128, &data[0][0][0], TEXTYPE_RGBA, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE, NULL); + explosiontexturefog = R_LoadTexture2D(explosiontexturepool, "explosiontexturefog", 128, 128, &data[0][0][0], TEXTYPE_BGRA, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE, NULL); // note that explosions survive the restart } diff --git a/r_light.c b/r_light.c index 2452e9a6..8fd4a01d 100644 --- a/r_light.c +++ b/r_light.c @@ -49,7 +49,7 @@ void r_light_start(void) pixels[y][x][3] = 255; } } - lightcorona = R_LoadTexture2D(lighttexturepool, "lightcorona", 32, 32, &pixels[0][0][0], TEXTYPE_RGBA, TEXF_PRECACHE, NULL); + lightcorona = R_LoadTexture2D(lighttexturepool, "lightcorona", 32, 32, &pixels[0][0][0], TEXTYPE_BGRA, TEXF_PRECACHE, NULL); } void r_light_shutdown(void) diff --git a/r_lightning.c b/r_lightning.c index 0b924920..dae55398 100644 --- a/r_lightning.c +++ b/r_lightning.c @@ -25,7 +25,7 @@ void r_lightningbeams_start(void) void r_lightningbeams_setupqmbtexture(void) { - r_lightningbeamqmbtexture = loadtextureimage(r_lightningbeamtexturepool, "textures/particles/lightning.pcx", 0, 0, false, TEXF_ALPHA | TEXF_PRECACHE, false); + r_lightningbeamqmbtexture = loadtextureimage(r_lightningbeamtexturepool, "textures/particles/lightning.pcx", false, TEXF_ALPHA | TEXF_PRECACHE, false); if (r_lightningbeamqmbtexture == NULL) Cvar_SetValueQuick(&r_lightningbeam_qmbtexture, false); } @@ -51,63 +51,63 @@ void r_lightningbeams_setuptexture(void) for (imagenumber = 0, maxpathstrength = 0.0339476;maxpathstrength < 0.5;imagenumber++, maxpathstrength += 0.01) { - for (i = 0;i < PATHPOINTS;i++) - { - path[i].x = lhrandom(0, 1); - path[i].y = lhrandom(0.2, 0.8); - path[i].strength = lhrandom(0, 1); - } - for (i = 0;i < PATHPOINTS;i++) - { - for (j = i + 1;j < PATHPOINTS;j++) + for (i = 0;i < PATHPOINTS;i++) + { + path[i].x = lhrandom(0, 1); + path[i].y = lhrandom(0.2, 0.8); + path[i].strength = lhrandom(0, 1); + } + for (i = 0;i < PATHPOINTS;i++) { - if (path[j].x < path[i].x) + for (j = i + 1;j < PATHPOINTS;j++) { - temppath = path[j]; - path[j] = path[i]; - path[i] = temppath; + if (path[j].x < path[i].x) + { + temppath = path[j]; + path[j] = path[i]; + path[i] = temppath; + } } } - } - particlex = path[0].x; - particley = path[0].y; - particlexv = lhrandom(0, 0.02); - particlexv = lhrandom(-0.02, 0.02); - memset(image, 0, BEAMWIDTH * BEAMHEIGHT * sizeof(int)); - for (i = 0;i < 65536;i++) - { - for (nearestpathindex = 0;nearestpathindex < PATHPOINTS;nearestpathindex++) - if (path[nearestpathindex].x > particlex) - break; - nearestpathindex %= PATHPOINTS; - dx = path[nearestpathindex].x + lhrandom(-0.01, 0.01);dx = bound(0, dx, 1) - particlex;if (dx < 0) dx += 1; - dy = path[nearestpathindex].y + lhrandom(-0.01, 0.01);dy = bound(0, dy, 1) - particley; - s = path[nearestpathindex].strength / sqrt(dx*dx+dy*dy); - particlexv = particlexv /* (1 - lhrandom(0.08, 0.12))*/ + dx * s; - particleyv = particleyv /* (1 - lhrandom(0.08, 0.12))*/ + dy * s; - particlex += particlexv * maxpathstrength;particlex -= (int) particlex; - particley += particleyv * maxpathstrength;particley = bound(0, particley, 1); - px = particlex * BEAMWIDTH; - py = particley * BEAMHEIGHT; - if (px >= 0 && py >= 0 && px < BEAMWIDTH && py < BEAMHEIGHT) - image[py*BEAMWIDTH+px] += 16; - } - - for (py = 0;py < BEAMHEIGHT;py++) - { - for (px = 0;px < BEAMWIDTH;px++) + particlex = path[0].x; + particley = path[0].y; + particlexv = lhrandom(0, 0.02); + particlexv = lhrandom(-0.02, 0.02); + memset(image, 0, BEAMWIDTH * BEAMHEIGHT * sizeof(int)); + for (i = 0;i < 65536;i++) { - pixels[(py*BEAMWIDTH+px)*4+0] = bound(0, image[py*BEAMWIDTH+px] * 1.0f, 255.0f); - pixels[(py*BEAMWIDTH+px)*4+1] = bound(0, image[py*BEAMWIDTH+px] * 1.0f, 255.0f); - pixels[(py*BEAMWIDTH+px)*4+2] = bound(0, image[py*BEAMWIDTH+px] * 1.0f, 255.0f); - pixels[(py*BEAMWIDTH+px)*4+3] = 255; + for (nearestpathindex = 0;nearestpathindex < PATHPOINTS;nearestpathindex++) + if (path[nearestpathindex].x > particlex) + break; + nearestpathindex %= PATHPOINTS; + dx = path[nearestpathindex].x + lhrandom(-0.01, 0.01);dx = bound(0, dx, 1) - particlex;if (dx < 0) dx += 1; + dy = path[nearestpathindex].y + lhrandom(-0.01, 0.01);dy = bound(0, dy, 1) - particley; + s = path[nearestpathindex].strength / sqrt(dx*dx+dy*dy); + particlexv = particlexv /* (1 - lhrandom(0.08, 0.12))*/ + dx * s; + particleyv = particleyv /* (1 - lhrandom(0.08, 0.12))*/ + dy * s; + particlex += particlexv * maxpathstrength;particlex -= (int) particlex; + particley += particleyv * maxpathstrength;particley = bound(0, particley, 1); + px = particlex * BEAMWIDTH; + py = particley * BEAMHEIGHT; + if (px >= 0 && py >= 0 && px < BEAMWIDTH && py < BEAMHEIGHT) + image[py*BEAMWIDTH+px] += 16; } + + for (py = 0;py < BEAMHEIGHT;py++) + { + for (px = 0;px < BEAMWIDTH;px++) + { + pixels[(py*BEAMWIDTH+px)*4+2] = bound(0, image[py*BEAMWIDTH+px] * 1.0f, 255.0f); + pixels[(py*BEAMWIDTH+px)*4+1] = bound(0, image[py*BEAMWIDTH+px] * 1.0f, 255.0f); + pixels[(py*BEAMWIDTH+px)*4+0] = bound(0, image[py*BEAMWIDTH+px] * 1.0f, 255.0f); + pixels[(py*BEAMWIDTH+px)*4+3] = 255; + } + } + + Image_WriteTGABGRA(va("lightningbeam%i.tga", imagenumber), BEAMWIDTH, BEAMHEIGHT, pixels); } - Image_WriteTGARGBA(va("lightningbeam%i.tga", imagenumber), BEAMWIDTH, BEAMHEIGHT, pixels); - } - - r_lightningbeamtexture = R_LoadTexture2D(r_lightningbeamtexturepool, "lightningbeam", BEAMWIDTH, BEAMHEIGHT, pixels, TEXTYPE_RGBA, TEXF_PRECACHE, NULL); + r_lightningbeamtexture = R_LoadTexture2D(r_lightningbeamtexturepool, "lightningbeam", BEAMWIDTH, BEAMHEIGHT, pixels, TEXTYPE_BGRA, TEXF_PRECACHE, NULL); Mem_Free(pixels); Mem_Free(image); @@ -138,14 +138,14 @@ void r_lightningbeams_setuptexture(void) r = intensity * 1.0f; g = intensity * 1.0f; b = intensity * 1.0f; - data[(y * BEAMWIDTH + x) * 4 + 0] = (unsigned char)(bound(0, r, 1) * 255.0f); + data[(y * BEAMWIDTH + x) * 4 + 2] = (unsigned char)(bound(0, r, 1) * 255.0f); data[(y * BEAMWIDTH + x) * 4 + 1] = (unsigned char)(bound(0, g, 1) * 255.0f); - data[(y * BEAMWIDTH + x) * 4 + 2] = (unsigned char)(bound(0, b, 1) * 255.0f); + data[(y * BEAMWIDTH + x) * 4 + 0] = (unsigned char)(bound(0, b, 1) * 255.0f); data[(y * BEAMWIDTH + x) * 4 + 3] = (unsigned char)255; } } - r_lightningbeamtexture = R_LoadTexture2D(r_lightningbeamtexturepool, "lightningbeam", BEAMWIDTH, BEAMHEIGHT, data, TEXTYPE_RGBA, TEXF_PRECACHE, NULL); + r_lightningbeamtexture = R_LoadTexture2D(r_lightningbeamtexturepool, "lightningbeam", BEAMWIDTH, BEAMHEIGHT, data, TEXTYPE_BGRA, TEXF_PRECACHE, NULL); Mem_Free(noise1); Mem_Free(noise2); Mem_Free(data); diff --git a/r_shadow.c b/r_shadow.c index 4230cbf5..ff081609 100644 --- a/r_shadow.c +++ b/r_shadow.c @@ -907,27 +907,24 @@ void R_Shadow_RenderVolume(int numvertices, int numtriangles, const float *verte CHECKGLERROR } -static unsigned char R_Shadow_MakeTextures_SamplePoint(float x, float y, float z) +static unsigned int R_Shadow_MakeTextures_SamplePoint(float x, float y, float z) { float dist = sqrt(x*x+y*y+z*z); float intensity = dist < 1 ? ((1.0f - dist) * r_shadow_lightattenuationlinearscale.value / (r_shadow_lightattenuationdividebias.value + dist*dist)) : 0; - return (unsigned char)bound(0, intensity * 256.0f, 255); + // note this code could suffer byte order issues except that it is multiplying by an integer that reads the same both ways + return (unsigned char)bound(0, intensity * 256.0f, 255) * 0x01010101; } static void R_Shadow_MakeTextures(void) { int x, y, z; float intensity, dist; - unsigned char *data; - unsigned int palette[256]; + unsigned int *data; R_FreeTexturePool(&r_shadow_texturepool); r_shadow_texturepool = R_AllocTexturePool(); r_shadow_attenlinearscale = r_shadow_lightattenuationlinearscale.value; r_shadow_attendividebias = r_shadow_lightattenuationdividebias.value; - // note this code could suffer byte order issues except that it is multiplying by an integer that reads the same both ways - for (x = 0;x < 256;x++) - palette[x] = x * 0x01010101; - data = (unsigned char *)Mem_Alloc(tempmempool, max(max(ATTEN3DSIZE*ATTEN3DSIZE*ATTEN3DSIZE, ATTEN2DSIZE*ATTEN2DSIZE), ATTEN1DSIZE)); + data = (unsigned int *)Mem_Alloc(tempmempool, max(max(ATTEN3DSIZE*ATTEN3DSIZE*ATTEN3DSIZE, ATTEN2DSIZE*ATTEN2DSIZE), ATTEN1DSIZE) * 4); // the table includes one additional value to avoid the need to clamp indexing due to minor math errors for (x = 0;x <= ATTENTABLESIZE;x++) { @@ -938,12 +935,12 @@ static void R_Shadow_MakeTextures(void) // 1D gradient texture for (x = 0;x < ATTEN1DSIZE;x++) data[x] = R_Shadow_MakeTextures_SamplePoint((x + 0.5f) * (1.0f / ATTEN1DSIZE) * (1.0f / 0.9375), 0, 0); - r_shadow_attenuationgradienttexture = R_LoadTexture2D(r_shadow_texturepool, "attenuation1d", ATTEN1DSIZE, 1, data, TEXTYPE_PALETTE, TEXF_PRECACHE | TEXF_CLAMP | TEXF_ALPHA, palette); + r_shadow_attenuationgradienttexture = R_LoadTexture2D(r_shadow_texturepool, "attenuation1d", ATTEN1DSIZE, 1, (unsigned char *)data, TEXTYPE_BGRA, TEXF_PRECACHE | TEXF_CLAMP | TEXF_ALPHA, NULL); // 2D circle texture for (y = 0;y < ATTEN2DSIZE;y++) for (x = 0;x < ATTEN2DSIZE;x++) data[y*ATTEN2DSIZE+x] = R_Shadow_MakeTextures_SamplePoint(((x + 0.5f) * (2.0f / ATTEN2DSIZE) - 1.0f) * (1.0f / 0.9375), ((y + 0.5f) * (2.0f / ATTEN2DSIZE) - 1.0f) * (1.0f / 0.9375), 0); - r_shadow_attenuation2dtexture = R_LoadTexture2D(r_shadow_texturepool, "attenuation2d", ATTEN2DSIZE, ATTEN2DSIZE, data, TEXTYPE_PALETTE, TEXF_PRECACHE | TEXF_CLAMP | TEXF_ALPHA, palette); + r_shadow_attenuation2dtexture = R_LoadTexture2D(r_shadow_texturepool, "attenuation2d", ATTEN2DSIZE, ATTEN2DSIZE, (unsigned char *)data, TEXTYPE_BGRA, TEXF_PRECACHE | TEXF_CLAMP | TEXF_ALPHA, NULL); // 3D sphere texture if (r_shadow_texture3d.integer && gl_texture3d) { @@ -951,7 +948,7 @@ static void R_Shadow_MakeTextures(void) for (y = 0;y < ATTEN3DSIZE;y++) for (x = 0;x < ATTEN3DSIZE;x++) data[(z*ATTEN3DSIZE+y)*ATTEN3DSIZE+x] = R_Shadow_MakeTextures_SamplePoint(((x + 0.5f) * (2.0f / ATTEN3DSIZE) - 1.0f) * (1.0f / 0.9375), ((y + 0.5f) * (2.0f / ATTEN3DSIZE) - 1.0f) * (1.0f / 0.9375), ((z + 0.5f) * (2.0f / ATTEN3DSIZE) - 1.0f) * (1.0f / 0.9375)); - r_shadow_attenuation3dtexture = R_LoadTexture3D(r_shadow_texturepool, "attenuation3d", ATTEN3DSIZE, ATTEN3DSIZE, ATTEN3DSIZE, data, TEXTYPE_PALETTE, TEXF_PRECACHE | TEXF_CLAMP | TEXF_ALPHA, palette); + r_shadow_attenuation3dtexture = R_LoadTexture3D(r_shadow_texturepool, "attenuation3d", ATTEN3DSIZE, ATTEN3DSIZE, ATTEN3DSIZE, (unsigned char *)data, TEXTYPE_BGRA, TEXF_PRECACHE | TEXF_CLAMP | TEXF_ALPHA, NULL); } else r_shadow_attenuation3dtexture = NULL; @@ -3199,7 +3196,7 @@ static int componentorder[4] = {0, 1, 2, 3}; rtexture_t *R_Shadow_LoadCubemap(const char *basename) { int i, j, cubemapsize; - unsigned char *cubemappixels, *image_rgba; + unsigned char *cubemappixels, *image_buffer; rtexture_t *cubemaptexture; char name[256]; // must start 0 so the first loadimagepixels has no requested width/height @@ -3215,10 +3212,10 @@ rtexture_t *R_Shadow_LoadCubemap(const char *basename) // generate an image name based on the base and and suffix dpsnprintf(name, sizeof(name), "%s%s", basename, suffix[j][i].suffix); // load it - if ((image_rgba = loadimagepixels(name, false, cubemapsize, cubemapsize, false))) + if ((image_buffer = loadimagepixelsbgra(name, false, false))) { // an image loaded, make sure width and height are equal - if (image_width == image_height) + if (image_width == image_height && (!cubemappixels || image_width == cubemapsize)) { // if this is the first image to load successfully, allocate the cubemap memory if (!cubemappixels && image_width >= 1) @@ -3229,12 +3226,12 @@ rtexture_t *R_Shadow_LoadCubemap(const char *basename) } // copy the image with any flipping needed by the suffix (px and posx types don't need flipping) if (cubemappixels) - Image_CopyMux(cubemappixels+i*cubemapsize*cubemapsize*4, image_rgba, cubemapsize, cubemapsize, suffix[j][i].flipx, suffix[j][i].flipy, suffix[j][i].flipdiagonal, 4, 4, componentorder); + Image_CopyMux(cubemappixels+i*cubemapsize*cubemapsize*4, image_buffer, cubemapsize, cubemapsize, suffix[j][i].flipx, suffix[j][i].flipy, suffix[j][i].flipdiagonal, 4, 4, componentorder); } else Con_Printf("Cubemap image \"%s\" (%ix%i) is not square, OpenGL requires square cubemaps.\n", name, image_width, image_height); // free the image - Mem_Free(image_rgba); + Mem_Free(image_buffer); } } } @@ -3243,7 +3240,7 @@ rtexture_t *R_Shadow_LoadCubemap(const char *basename) { if (!r_shadow_filters_texturepool) r_shadow_filters_texturepool = R_AllocTexturePool(); - cubemaptexture = R_LoadTextureCubeMap(r_shadow_filters_texturepool, basename, cubemapsize, cubemappixels, TEXTYPE_RGBA, TEXF_PRECACHE | (gl_texturecompression_lightcubemaps.integer ? TEXF_COMPRESS : 0), NULL); + cubemaptexture = R_LoadTextureCubeMap(r_shadow_filters_texturepool, basename, cubemapsize, cubemappixels, TEXTYPE_BGRA, TEXF_PRECACHE | (gl_texturecompression_lightcubemaps.integer ? TEXF_COMPRESS : 0), NULL); Mem_Free(cubemappixels); } else diff --git a/r_sky.c b/r_sky.c index a33b5346..5d6362f8 100644 --- a/r_sky.c +++ b/r_sky.c @@ -89,7 +89,7 @@ int R_LoadSkyBox(void) int i, j, success; int indices[4] = {0,1,2,3}; char name[MAX_INPUTLINE]; - unsigned char *image_rgba; + unsigned char *image_buffer; unsigned char *temp; R_UnloadSkyBox(); @@ -102,21 +102,21 @@ int R_LoadSkyBox(void) success = 0; for (i=0; i<6; i++) { - if (dpsnprintf(name, sizeof(name), "%s_%s", skyname, suffix[j][i].suffix) < 0 || !(image_rgba = loadimagepixels(name, false, 0, 0, false))) + if (dpsnprintf(name, sizeof(name), "%s_%s", skyname, suffix[j][i].suffix) < 0 || !(image_buffer = loadimagepixelsbgra(name, false, false))) { - if (dpsnprintf(name, sizeof(name), "%s%s", skyname, suffix[j][i].suffix) < 0 || !(image_rgba = loadimagepixels(name, false, 0, 0, false))) + if (dpsnprintf(name, sizeof(name), "%s%s", skyname, suffix[j][i].suffix) < 0 || !(image_buffer = loadimagepixelsbgra(name, false, false))) { - if (dpsnprintf(name, sizeof(name), "env/%s%s", skyname, suffix[j][i].suffix) < 0 || !(image_rgba = loadimagepixels(name, false, 0, 0, false))) + if (dpsnprintf(name, sizeof(name), "env/%s%s", skyname, suffix[j][i].suffix) < 0 || !(image_buffer = loadimagepixelsbgra(name, false, false))) { - if (dpsnprintf(name, sizeof(name), "gfx/env/%s%s", skyname, suffix[j][i].suffix) < 0 || !(image_rgba = loadimagepixels(name, false, 0, 0, false))) + if (dpsnprintf(name, sizeof(name), "gfx/env/%s%s", skyname, suffix[j][i].suffix) < 0 || !(image_buffer = loadimagepixelsbgra(name, false, false))) continue; } } } temp = (unsigned char *)Mem_Alloc(tempmempool, image_width*image_height*4); - Image_CopyMux (temp, image_rgba, image_width, image_height, suffix[j][i].flipx, suffix[j][i].flipy, suffix[j][i].flipdiagonal, 4, 4, indices); - skyboxside[i] = R_LoadTexture2D(skytexturepool, va("skyboxside%d", i), image_width, image_height, temp, TEXTYPE_RGBA, TEXF_CLAMP | TEXF_PRECACHE | (gl_texturecompression_sky.integer ? TEXF_COMPRESS : 0), NULL); - Mem_Free(image_rgba); + Image_CopyMux (temp, image_buffer, image_width, image_height, suffix[j][i].flipx, suffix[j][i].flipy, suffix[j][i].flipdiagonal, 4, 4, indices); + skyboxside[i] = R_LoadTexture2D(skytexturepool, va("skyboxside%d", i), image_width, image_height, temp, TEXTYPE_BGRA, TEXF_CLAMP | TEXF_PRECACHE | (gl_texturecompression_sky.integer ? TEXF_COMPRESS : 0), NULL); + Mem_Free(image_buffer); Mem_Free(temp); success++; } diff --git a/r_textures.h b/r_textures.h index f7cb02f9..f83aba32 100644 --- a/r_textures.h +++ b/r_textures.h @@ -23,12 +23,16 @@ // used for checking if textures mismatch #define TEXF_IMPORTANTBITS (TEXF_ALPHA | TEXF_MIPMAP | TEXF_CLAMP | TEXF_FORCENEAREST | TEXF_FORCELINEAR | TEXF_PICMIP | TEXF_COMPRESS) -// 8bit paletted -#define TEXTYPE_PALETTE 1 -// 32bit RGBA -#define TEXTYPE_RGBA 3 -// 32bit BGRA (preferred format due to faster uploads on most hardware) -#define TEXTYPE_BGRA 4 +typedef enum textype_e +{ + // 8bit paletted + TEXTYPE_PALETTE, + // 32bit RGBA + TEXTYPE_RGBA, + // 32bit BGRA (preferred format due to faster uploads on most hardware) + TEXTYPE_BGRA, +} +textype_t; // contents of this structure are mostly private to gl_textures.c typedef struct rtexture_s @@ -67,10 +71,10 @@ extern cvar_t gl_texturecompression_lightcubemaps; // add a texture to a pool and optionally precache (upload) it // (note: data == NULL is perfectly acceptable) // (note: palette must not be NULL if using TEXTYPE_PALETTE) -rtexture_t *R_LoadTexture1D(rtexturepool_t *rtexturepool, const char *identifier, int width, const unsigned char *data, int textype, int flags, const unsigned int *palette); -rtexture_t *R_LoadTexture2D(rtexturepool_t *rtexturepool, const char *identifier, int width, int height, const unsigned char *data, int textype, int flags, const unsigned int *palette); -rtexture_t *R_LoadTexture3D(rtexturepool_t *rtexturepool, const char *identifier, int width, int height, int depth, const unsigned char *data, int textype, int flags, const unsigned int *palette); -rtexture_t *R_LoadTextureCubeMap(rtexturepool_t *rtexturepool, const char *identifier, int width, const unsigned char *data, int textype, int flags, const unsigned int *palette); +rtexture_t *R_LoadTexture1D(rtexturepool_t *rtexturepool, const char *identifier, int width, const unsigned char *data, textype_t textype, int flags, const unsigned int *palette); +rtexture_t *R_LoadTexture2D(rtexturepool_t *rtexturepool, const char *identifier, int width, int height, const unsigned char *data, textype_t textype, int flags, const unsigned int *palette); +rtexture_t *R_LoadTexture3D(rtexturepool_t *rtexturepool, const char *identifier, int width, int height, int depth, const unsigned char *data, textype_t textype, int flags, const unsigned int *palette); +rtexture_t *R_LoadTextureCubeMap(rtexturepool_t *rtexturepool, const char *identifier, int width, const unsigned char *data, textype_t textype, int flags, const unsigned int *palette); // free a texture void R_FreeTexture(rtexture_t *rt); diff --git a/render.h b/render.h index 2baf0ea1..2d0b9925 100644 --- a/render.h +++ b/render.h @@ -134,7 +134,8 @@ void R_SkinFrame_Purge(void); skinframe_t *R_SkinFrame_FindNextByName( skinframe_t *last, const char *name ); skinframe_t *R_SkinFrame_Find(const char *name, int textureflags, int comparewidth, int compareheight, int comparecrc, qboolean add); skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboolean complain); -skinframe_t *R_SkinFrame_LoadInternal(const char *name, int textureflags, int loadpantsandshirt, int loadglowtexture, const unsigned char *skindata, int width, int height, int bitsperpixel, const unsigned int *palette, const unsigned int *alphapalette); +skinframe_t *R_SkinFrame_LoadInternalBGRA(const char *name, int textureflags, const unsigned char *skindata, int width, int height); +skinframe_t *R_SkinFrame_LoadInternalQuake(const char *name, int textureflags, int loadpantsandshirt, int loadglowtexture, const unsigned char *skindata, int width, int height); skinframe_t *R_SkinFrame_LoadMissing(void); void R_View_WorldVisibility(qboolean forcenovis); diff --git a/sbar.c b/sbar.c index 4b63ab8a..21cdd6ca 100644 --- a/sbar.c +++ b/sbar.c @@ -943,9 +943,9 @@ void Sbar_DrawFrags (void) s = &cl.scores[k]; // draw background - c = (unsigned char *)&palette_pantsscoreboard[(s->colors & 0xf0) >> 4]; + c = palette_rgb_pantsscoreboard[(s->colors & 0xf0) >> 4]; DrawQ_Fill (sbar_x + x + 10, sbar_y - 23, 28, 4, c[0] * (1.0f / 255.0f), c[1] * (1.0f / 255.0f), c[2] * (1.0f / 255.0f), c[3] * (1.0f / 255.0f) * sbar_alpha_fg.value, 0); - c = (unsigned char *)&palette_shirtscoreboard[s->colors & 0xf]; + c = palette_rgb_shirtscoreboard[s->colors & 0xf]; DrawQ_Fill (sbar_x + x + 10, sbar_y + 4 - 23, 28, 3, c[0] * (1.0f / 255.0f), c[1] * (1.0f / 255.0f), c[2] * (1.0f / 255.0f), c[3] * (1.0f / 255.0f) * sbar_alpha_fg.value, 0); // draw number @@ -987,9 +987,9 @@ void Sbar_DrawFace (void) s = &cl.scores[cl.viewentity - 1]; // draw background Sbar_DrawPic (112, 0, rsb_teambord); - c = (unsigned char *)&palette_pantsscoreboard[(s->colors & 0xf0) >> 4]; + c = palette_rgb_pantsscoreboard[(s->colors & 0xf0) >> 4]; DrawQ_Fill (sbar_x + 113, vid_conheight.integer-SBAR_HEIGHT+3, 22, 9, c[0] * (1.0f / 255.0f), c[1] * (1.0f / 255.0f), c[2] * (1.0f / 255.0f), c[3] * (1.0f / 255.0f) * sbar_alpha_fg.value, 0); - c = (unsigned char *)&palette_shirtscoreboard[s->colors & 0xf]; + c = palette_rgb_shirtscoreboard[s->colors & 0xf]; DrawQ_Fill (sbar_x + 113, vid_conheight.integer-SBAR_HEIGHT+12, 22, 9, c[0] * (1.0f / 255.0f), c[1] * (1.0f / 255.0f), c[2] * (1.0f / 255.0f), c[3] * (1.0f / 255.0f) * sbar_alpha_fg.value, 0); // draw number @@ -1624,9 +1624,9 @@ float Sbar_PrintScoreboardItem(scoreboard_t *s, float x, float y) // // // - c = (unsigned char *)&palette_pantsscoreboard[(s->colors & 0xf0) >> 4]; + c = palette_rgb_pantsscoreboard[(s->colors & 0xf0) >> 4]; DrawQ_Fill(x + 14*8, y+1, 40, 3, c[0] * (1.0f / 255.0f), c[1] * (1.0f / 255.0f), c[2] * (1.0f / 255.0f), c[3] * (1.0f / 255.0f) * sbar_alpha_fg.value, 0); - c = (unsigned char *)&palette_shirtscoreboard[s->colors & 0xf]; + c = palette_rgb_shirtscoreboard[s->colors & 0xf]; DrawQ_Fill(x + 14*8, y+4, 40, 3, c[0] * (1.0f / 255.0f), c[1] * (1.0f / 255.0f), c[2] * (1.0f / 255.0f), c[3] * (1.0f / 255.0f) * sbar_alpha_fg.value, 0); // print the text //DrawQ_String(x, y, va("%c%4i %s", myself ? 13 : ' ', (int) s->frags, s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, true); @@ -1648,9 +1648,9 @@ float Sbar_PrintScoreboardItem(scoreboard_t *s, float x, float y) else { // draw colors behind score - c = (unsigned char *)&palette_pantsscoreboard[(s->colors & 0xf0) >> 4]; + c = palette_rgb_pantsscoreboard[(s->colors & 0xf0) >> 4]; DrawQ_Fill(x + 9*8, y+1, 40, 3, c[0] * (1.0f / 255.0f), c[1] * (1.0f / 255.0f), c[2] * (1.0f / 255.0f), c[3] * (1.0f / 255.0f) * sbar_alpha_fg.value, 0); - c = (unsigned char *)&palette_shirtscoreboard[s->colors & 0xf]; + c = palette_rgb_shirtscoreboard[s->colors & 0xf]; DrawQ_Fill(x + 9*8, y+4, 40, 3, c[0] * (1.0f / 255.0f), c[1] * (1.0f / 255.0f), c[2] * (1.0f / 255.0f), c[3] * (1.0f / 255.0f) * sbar_alpha_fg.value, 0); // print the text //DrawQ_String(x, y, va("%c%4i %s", myself ? 13 : ' ', (int) s->frags, s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, true); @@ -1881,7 +1881,7 @@ void Sbar_Score (int margin) for(i = 0; i < teamlines; ++i) { int cindex = teamcolorsort[i]->colors & 15; - unsigned char *c = (unsigned char *)&palette_shirtscoreboard[cindex]; + unsigned char *c = palette_rgb_shirtscoreboard[cindex]; float cm = max(max(c[0], c[1]), c[2]); float cr = c[0] / cm; float cg = c[1] / cm; diff --git a/wad.c b/wad.c index 60cabff9..8e4c767b 100644 --- a/wad.c +++ b/wad.c @@ -222,7 +222,7 @@ void W_LoadTextureWadFile (char *filename, int complain) // leaves the file open } -unsigned char *W_ConvertWAD3Texture(miptex_t *tex) +unsigned char *W_ConvertWAD3TextureBGRA(miptex_t *tex) { unsigned char *in, *data, *out, *pal; int d, p; @@ -243,9 +243,9 @@ unsigned char *W_ConvertWAD3Texture(miptex_t *tex) else { p *= 3; - out[0] = pal[p]; + out[2] = pal[p]; out[1] = pal[p+1]; - out[2] = pal[p+2]; + out[0] = pal[p+2]; out[3] = 255; } out += 4; @@ -253,7 +253,7 @@ unsigned char *W_ConvertWAD3Texture(miptex_t *tex) return data; } -unsigned char *W_GetTexture(char *name) +unsigned char *W_GetTextureBGRA(char *name) { unsigned int i, j, k; miptex_t *tex; @@ -287,7 +287,7 @@ unsigned char *W_GetTexture(char *name) tex->height = LittleLong(tex->height); for (j = 0;j < MIPLEVELS;j++) tex->offsets[j] = LittleLong(tex->offsets[j]); - data = W_ConvertWAD3Texture(tex); + data = W_ConvertWAD3TextureBGRA(tex); Mem_Free(tex); return data; } diff --git a/wad.h b/wad.h index 9b3a3a4f..b5ab8dba 100644 --- a/wad.h +++ b/wad.h @@ -69,9 +69,9 @@ void W_UnloadAll(void); unsigned char *W_GetLumpName(const char *name); // halflife texture wads -void W_LoadTextureWadFile (char *filename, int complain); -unsigned char *W_GetTexture (char *name); // returns tempmempool allocated image data, width and height are in image_width and image_height -unsigned char *W_ConvertWAD3Texture(miptex_t *tex); // returns tempmempool allocated image data, width and height are in image_width and image_height +void W_LoadTextureWadFile(char *filename, int complain); +unsigned char *W_GetTextureBGRA(char *name); // returns tempmempool allocated image data, width and height are in image_width and image_height +unsigned char *W_ConvertWAD3TextureBGRA(miptex_t *tex); // returns tempmempool allocated image data, width and height are in image_width and image_height #endif -- 2.39.2