#include "wad.h"
#include "cl_video.h"
+#include "cl_dyntexture.h"
cvar_t r_textshadow = {CVAR_SAVE, "r_textshadow", "0", "draws a shadow on all text to improve readability (note: value controls offset, 1 = 1 pixel, 1.5 = 1.5 pixels, etc)"};
+cvar_t r_textbrightness = {CVAR_SAVE, "r_textbrightness", "0", "additional brightness for text color codes (0 keeps colors as is, 1 makes them all white)"};
static rtexture_t *char_texture;
cachepic_t *r_crosshairs[NUMCROSSHAIRS+1];
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 =
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] =
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)
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
}
unsigned char *lmpdata;
char lmpname[MAX_QPATH];
- if (!strncmp(CLVIDEOPREFIX, path, sizeof(CLVIDEOPREFIX) - 1))
- {
- clvideo_t *video;
-
- video = CL_GetVideoByName(path);
- if( video )
- return &video->cpif;
- }
-
+ // check whether the picture has already been cached
crc = CRC_Block((unsigned char *)path, strlen(path));
hashkey = ((crc >> 8) ^ crc) % CACHEPICHASHSIZE;
for (pic = cachepichash[hashkey];pic;pic = pic->chain)
pic->chain = cachepichash[hashkey];
cachepichash[hashkey] = pic;
+ // check whether it is an dynamic texture (if so, we can directly use its texture handler)
+ pic->tex = CL_GetDynTexture( path );
+ // if so, set the width/height, too
+ if( pic->tex ) {
+ pic->width = R_TextureWidth(pic->tex);
+ pic->height = R_TextureHeight(pic->tex);
+ // we're done now (early-out)
+ return pic;
+ }
+
flags = TEXF_ALPHA;
if (persistent)
flags |= TEXF_PRECACHE;
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));
+ 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));
+ 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
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);
}
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
{
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);
}
}
pic->tex = draw_generatecrosshair(5);
if (pic->tex == NULL && !strcmp(path, "gfx/colorcontrol/ditherpattern"))
pic->tex = draw_generateditherpattern();
+ // default textures for light sprites
+ // todo: improve them
+ if (pic->tex == NULL && !strcmp(path, "gfx/editlights/cursor"))
+ pic->tex = draw_generatecrosshair(0);
+ if (pic->tex == NULL && !strcmp(path, "gfx/editlights/light"))
+ pic->tex = draw_generatecrosshair(0);
+ if (pic->tex == NULL && !strcmp(path, "gfx/editlights/noshadow"))
+ pic->tex = draw_generatecrosshair(0);
+ if (pic->tex == NULL && !strcmp(path, "gfx/editlights/cubemap"))
+ pic->tex = draw_generatecrosshair(0);
+ if (pic->tex == NULL && !strcmp(path, "gfx/editlights/selection"))
+ pic->tex = draw_generatecrosshair(0);
if (pic->tex == NULL)
{
// don't complain about missing gfx/crosshair images
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;
{
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;
}
}
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;
}
void GL_Draw_Init (void)
{
Cvar_RegisterVariable(&r_textshadow);
+ Cvar_RegisterVariable(&r_textbrightness);
R_RegisterModule("GL_Draw", gl_draw_start, gl_draw_shutdown, gl_draw_newmap);
}
height = pic->height;
R_Mesh_TexBind(0, R_GetTexture(pic->tex));
R_Mesh_TexCoordPointer(0, 2, floats + 12, 0, 0);
- floats[12] = 0;floats[13] = 0;
- floats[14] = 1;floats[15] = 0;
- floats[16] = 1;floats[17] = 1;
- floats[18] = 0;floats[19] = 1;
+
+ // AK07: lets be texel correct on the corners
+ {
+ float horz_offset = 0.5f / pic->width;
+ float vert_offset = 0.5f / pic->height;
+
+ floats[12] = 0.0f + horz_offset;floats[13] = 0.0f + vert_offset;
+ floats[14] = 1.0f - horz_offset;floats[15] = 0.0f + vert_offset;
+ floats[16] = 1.0f - horz_offset;floats[17] = 1.0f - vert_offset;
+ floats[18] = 0.0f + horz_offset;floats[19] = 1.0f - vert_offset;
+ }
}
floats[2] = floats[5] = floats[8] = floats[11] = 0;
static void DrawQ_GetTextColor(float color[4], int colorindex, float r, float g, float b, float a, qboolean shadow)
{
+ float v = r_textbrightness.value;
Vector4Copy(string_colors[colorindex], color);
- Vector4Set(color, color[0] * r, color[1] * g, color[2] * b, color[3] * a);
+ Vector4Set(color, (color[0] * (1-v) + v) * r, (color[1] * (1-v) + v) * g, (color[2] * (1-v) + v) * b, color[3] * a);
if (shadow)
{
float shadowalpha = color[0]+color[1]+color[2] * 0.8;