the light has been defeated by the shadow (r_light moved into r_shadow)
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Mon, 3 Dec 2007 10:47:57 +0000 (10:47 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Mon, 3 Dec 2007 10:47:57 +0000 (10:47 +0000)
overhauled gl_draw.c draw_generate* code and embedded images
cleaned up and improved r_editlights light sprite handling

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@7756 d7cf8633-e32d-0410-b094-e92efae38249

15 files changed:
client.h
darkplaces-dedicated.dsp
darkplaces-sdl.dsp
darkplaces.dsp
gl_draw.c
gl_rmain.c
makefile.inc
palette.c
palette.h
r_light.c [deleted file]
r_light.h [deleted file]
r_shadow.c
r_shadow.h
render.h
sbar.c

index 8fe6d94..2628dce 100644 (file)
--- a/client.h
+++ b/client.h
@@ -1313,9 +1313,6 @@ void Debug_PolygonEnd(void);
 
 extern qboolean sb_showscores;
 
-#define NUMCROSSHAIRS 32
-extern cachepic_t *r_crosshairs[NUMCROSSHAIRS+1];
-
 float FogPoint_World(const vec3_t p);
 float FogPoint_Model(const vec3_t p);
 
index c8323ca..28068dd 100644 (file)
@@ -322,10 +322,6 @@ SOURCE=.\r_lerpanim.c
 # End Source File\r
 # Begin Source File\r
 \r
-SOURCE=.\r_light.c\r
-# End Source File\r
-# Begin Source File\r
-\r
 SOURCE=.\r_lightning.c\r
 # End Source File\r
 # Begin Source File\r
@@ -642,10 +638,6 @@ SOURCE=.\r_lerpanim.h
 # End Source File\r
 # Begin Source File\r
 \r
-SOURCE=.\r_light.h\r
-# End Source File\r
-# Begin Source File\r
-\r
 SOURCE=.\r_modules.h\r
 # End Source File\r
 # Begin Source File\r
index 102013b..0aa1f65 100644 (file)
@@ -318,10 +318,6 @@ SOURCE=.\r_lerpanim.c
 # End Source File\r
 # Begin Source File\r
 \r
-SOURCE=.\r_light.c\r
-# End Source File\r
-# Begin Source File\r
-\r
 SOURCE=.\r_lightning.c\r
 # End Source File\r
 # Begin Source File\r
@@ -662,10 +658,6 @@ SOURCE=.\r_lerpanim.h
 # End Source File\r
 # Begin Source File\r
 \r
-SOURCE=.\r_light.h\r
-# End Source File\r
-# Begin Source File\r
-\r
 SOURCE=.\r_modules.h\r
 # End Source File\r
 # Begin Source File\r
index 7f279dd..cb5ce85 100644 (file)
@@ -330,10 +330,6 @@ SOURCE=.\r_lerpanim.c
 # End Source File\r
 # Begin Source File\r
 \r
-SOURCE=.\r_light.c\r
-# End Source File\r
-# Begin Source File\r
-\r
 SOURCE=.\r_lightning.c\r
 # End Source File\r
 # Begin Source File\r
@@ -682,10 +678,6 @@ SOURCE=.\r_lerpanim.h
 # End Source File\r
 # Begin Source File\r
 \r
-SOURCE=.\r_light.h\r
-# End Source File\r
-# Begin Source File\r
-\r
 SOURCE=.\r_modules.h\r
 # End Source File\r
 # Begin Source File\r
index cfdb61e..a6b9868 100644 (file)
--- a/gl_draw.c
+++ b/gl_draw.c
@@ -30,8 +30,6 @@ dp_font_t dp_fonts[MAX_FONTS] = {{0}};
 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)"};
 
-cachepic_t *r_crosshairs[NUMCROSSHAIRS+1];
-
 //=============================================================================
 /* Support Routines */
 
@@ -101,51 +99,67 @@ static rtexture_t *draw_generateconchars(void)
        return R_LoadTexture2D(drawtexturepool, "conchars", 256, 256, &buffer[0][0], TEXTYPE_BGRA, TEXF_ALPHA | TEXF_PRECACHE, NULL);
 }
 
-static char *pointerimage =
-       "333333332......."
-       "26777761........"
-       "2655541........."
-       "265541.........."
-       "2654561........."
-       "26414561........"
-       "251.14561......."
-       "21...14561......"
-       "1.....141......."
-       ".......1........"
+static rtexture_t *draw_generateditherpattern(void)
+{
+       int x, y;
+       unsigned char pixels[8][8];
+       for (y = 0;y < 8;y++)
+               for (x = 0;x < 8;x++)
+                       pixels[y][x] = ((x^y) & 4) ? 254 : 0;
+       return R_LoadTexture2D(drawtexturepool, "ditherpattern", 8, 8, pixels[0], TEXTYPE_PALETTE, TEXF_FORCENEAREST | TEXF_PRECACHE, NULL);
+}
+
+typedef struct embeddedpic_s
+{
+       const char *name;
+       int width;
+       int height;
+       const char *pixels;
+}
+embeddedpic_t;
+
+static embeddedpic_t embeddedpics[] =
+{
+       {
+       "gfx/prydoncursor001", 16, 16,
+       "477777774......."
+       "77.....6........"
+       "7.....6........."
+       "7....6.........."
+       "7.....6........."
+       "7..6...6........"
+       "7.6.6...6......."
+       "76...6...6......"
+       "4.....6.6......."
+       ".......6........"
        "................"
        "................"
        "................"
        "................"
        "................"
        "................"
-;
-
-static rtexture_t *draw_generatemousepointer(void)
-{
-       int i;
-       unsigned char buffer[256][4];
-       for (i = 0;i < 256;i++)
+       },
        {
-               if (pointerimage[i] == '.')
-               {
-                       buffer[i][0] = 0;
-                       buffer[i][1] = 0;
-                       buffer[i][2] = 0;
-                       buffer[i][3] = 0;
-               }
-               else
-               {
-                       buffer[i][0] = (pointerimage[i] - '0') * 16;
-                       buffer[i][1] = (pointerimage[i] - '0') * 16;
-                       buffer[i][2] = (pointerimage[i] - '0') * 16;
-                       buffer[i][3] = 255;
-               }
-       }
-       return R_LoadTexture2D(drawtexturepool, "mousepointer", 16, 16, &buffer[0][0], TEXTYPE_BGRA, TEXF_ALPHA | TEXF_PRECACHE, NULL);
-}
-
-static char *crosshairtexdata[NUMCROSSHAIRS] =
-{
+       "ui/mousepointer", 16, 16,
+       "477777774......."
+       "77.....6........"
+       "7.....6........."
+       "7....6.........."
+       "7.....6........."
+       "7..6...6........"
+       "7.6.6...6......."
+       "76...6...6......"
+       "4.....6.6......."
+       ".......6........"
+       "................"
+       "................"
+       "................"
+       "................"
+       "................"
+       "................"
+       },
+       {
+       "gfx/crosshair1", 16, 16,
        "................"
        "................"
        "................"
@@ -162,7 +176,9 @@ static char *crosshairtexdata[NUMCROSSHAIRS] =
        "................"
        "................"
        "................"
-       ,
+       },
+       {
+       "gfx/crosshair2", 16, 16,
        "................"
        "................"
        "................"
@@ -179,7 +195,9 @@ static char *crosshairtexdata[NUMCROSSHAIRS] =
        "................"
        "................"
        "................"
-       ,
+       },
+       {
+       "gfx/crosshair3", 16, 16,
        "................"
        ".......77......."
        ".......77......."
@@ -196,7 +214,9 @@ static char *crosshairtexdata[NUMCROSSHAIRS] =
        ".......77......."
        ".......77......."
        "................"
-       ,
+       },
+       {
+       "gfx/crosshair4", 16, 16,
        "................"
        "................"
        "................"
@@ -213,87 +233,173 @@ static char *crosshairtexdata[NUMCROSSHAIRS] =
        "........7......."
        "........7......."
        "................"
-       ,
-       "................"
+       },
+       {
+       "gfx/crosshair5", 8, 8,
+       "........"
+       "........"
+       "....7..."
+       "........"
+       "..7.7.7."
+       "........"
+       "....7..."
+       "........"
+       },
+       {
+       "gfx/crosshair6", 2, 2,
+       "77"
+       "77"
+       },
+       {
+       "gfx/crosshair7", 16, 16,
        "................"
+       ".3............3."
+       "..5...2332...5.."
+       "...7.3....3.7..."
+       "....7......7...."
+       "...3.7....7.3..."
+       "..2...7..7...2.."
+       "..3..........3.."
+       "..3..........3.."
+       "..2...7..7...2.."
+       "...3.7....7.3..."
+       "....7......7...."
+       "...7.3....3.7..."
+       "..5...2332...5.."
+       ".3............3."
        "................"
+       },
+       {
+       "gfx/editlights/cursor", 16, 16,
        "................"
+       ".3............3."
+       "..5...2332...5.."
+       "...7.3....3.7..."
+       "....7......7...."
+       "...3.7....7.3..."
+       "..2...7..7...2.."
+       "..3..........3.."
+       "..3..........3.."
+       "..2...7..7...2.."
+       "...3.7....7.3..."
+       "....7......7...."
+       "...7.3....3.7..."
+       "..5...2332...5.."
+       ".3............3."
        "................"
-       "........7......."
+       },
+       {
+       "gfx/editlights/light", 16, 16,
        "................"
-       "........4......."
-       ".....7.4.4.7...."
-       "........4......."
        "................"
-       "........7......."
+       "......1111......"
+       "....11233211...."
+       "...1234554321..."
+       "...1356776531..."
+       "..124677776421.."
+       "..135777777531.."
+       "..135777777531.."
+       "..124677776421.."
+       "...1356776531..."
+       "...1234554321..."
+       "....11233211...."
+       "......1111......"
        "................"
        "................"
+       },
+       {
+       "gfx/editlights/noshadow", 16, 16,
        "................"
        "................"
-       ,
+       "......1111......"
+       "....11233211...."
+       "...1234554321..."
+       "...1356226531..."
+       "..12462..26421.."
+       "..1352....2531.."
+       "..1352....2531.."
+       "..12462..26421.."
+       "...1356226531..."
+       "...1234554321..."
+       "....11233211...."
+       "......1111......"
        "................"
        "................"
+       },
+       {
+       "gfx/editlights/selection", 16, 16,
        "................"
+       ".777752..257777."
+       ".742........247."
+       ".72..........27."
+       ".7............7."
+       ".5............5."
+       ".2............2."
        "................"
        "................"
+       ".2............2."
+       ".5............5."
+       ".7............7."
+       ".72..........27."
+       ".742........247."
+       ".777752..257777."
        "................"
+       },
+       {
+       "gfx/editlights/cubemaplight", 16, 16,
        "................"
-       ".......55......."
-       ".......55......."
        "................"
+       "......2772......"
+       "....27755772...."
+       "..277533335772.."
+       "..753333333357.."
+       "..777533335777.."
+       "..735775577537.."
+       "..733357753337.."
+       "..733337733337.."
+       "..753337733357.."
+       "..277537735772.."
+       "....27777772...."
+       "......2772......"
        "................"
        "................"
+       },
+       {
+       "gfx/editlights/cubemapnoshadowlight", 16, 16,
        "................"
        "................"
+       "......2772......"
+       "....27722772...."
+       "..2772....2772.."
+       "..72........27.."
+       "..7772....2777.."
+       "..7.27722772.7.."
+       "..7...2772...7.."
+       "..7....77....7.."
+       "..72...77...27.."
+       "..2772.77.2772.."
+       "....27777772...."
+       "......2772......"
        "................"
        "................"
+       },
+       {NULL, 0, 0, NULL}
 };
 
-static rtexture_t *draw_generatecrosshair(int num)
+static rtexture_t *draw_generatepic(const char *name)
 {
-       int i;
-       char *in;
-       unsigned char data[16*16][4];
-       in = crosshairtexdata[num];
-       for (i = 0;i < 16*16;i++)
-       {
-               if (in[i] == '.')
-               {
-                       data[i][0] = 255;
-                       data[i][1] = 255;
-                       data[i][2] = 255;
-                       data[i][3] = 0;
-               }
-               else
-               {
-                       data[i][0] = data[i][1] = data[i][2] = (unsigned char) ((int) (in[i] - '0') * 127 / 7 + 128);
-                       data[i][3] = 255;
-               }
-       }
-       return R_LoadTexture2D(drawtexturepool, va("crosshair%i", num+1), 16, 16, &data[0][0], TEXTYPE_BGRA, TEXF_ALPHA | TEXF_PRECACHE, NULL);
+       embeddedpic_t *p;
+       for (p = embeddedpics;p->name;p++)
+               if (!strcmp(name, p->name))
+                       return R_LoadTexture2D(drawtexturepool, p->name, p->width, p->height, (const unsigned char *)p->pixels, TEXTYPE_PALETTE, TEXF_ALPHA | TEXF_PRECACHE, palette_bgra_embeddedpic);
+       if (!strcmp(name, "gfx/conchars"))
+               return draw_generateconchars();
+       if (!strcmp(name, "gfx/colorcontrol/ditherpattern"))
+               return draw_generateditherpattern();
+       Con_Printf("Draw_CachePic: failed to load %s\n", name);
+       return r_texture_notexture;
 }
 
-static rtexture_t *draw_generateditherpattern(void)
-{
-#if 1
-       int x, y;
-       unsigned char data[8*8*4];
-       for (y = 0;y < 8;y++)
-       {
-               for (x = 0;x < 8;x++)
-               {
-                       data[(y*8+x)*4+0] = data[(y*8+x)*4+1] = data[(y*8+x)*4+2] = ((x^y) & 4) ? 255 : 0;
-                       data[(y*8+x)*4+3] = 255;
-               }
-       }
-       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_BGRA, TEXF_FORCENEAREST | TEXF_PRECACHE, NULL);
-#endif
-}
 
 /*
 ================
@@ -342,7 +448,7 @@ static cachepic_t   *Draw_CachePic_Compression (const char *path, qboolean persist
        flags = TEXF_ALPHA;
        if (persistent)
                flags |= TEXF_PRECACHE;
-       if (!strcmp(path, "gfx/colorcontrol/ditherpattern"))
+       if (strcmp(path, "gfx/colorcontrol/ditherpattern"))
                flags |= TEXF_CLAMP;
        if(allow_compression && gl_texturecompression_2d.integer)
                flags |= TEXF_COMPRESS;
@@ -400,48 +506,10 @@ static cachepic_t *Draw_CachePic_Compression (const char *path, qboolean persist
                }
        }
 
-       // if it's not found on disk, check if it's one of the builtin images
+       // if it's not found on disk, generate an image
        if (pic->tex == NULL)
        {
-               if (pic->tex == NULL && !strcmp(path, "gfx/conchars"))
-                       pic->tex = draw_generateconchars();
-               if (pic->tex == NULL && !strcmp(path, "ui/mousepointer"))
-                       pic->tex = draw_generatemousepointer();
-               if (pic->tex == NULL && !strcmp(path, "gfx/prydoncursor001"))
-                       pic->tex = draw_generatemousepointer();
-               if (pic->tex == NULL && !strcmp(path, "gfx/crosshair1"))
-                       pic->tex = draw_generatecrosshair(0);
-               if (pic->tex == NULL && !strcmp(path, "gfx/crosshair2"))
-                       pic->tex = draw_generatecrosshair(1);
-               if (pic->tex == NULL && !strcmp(path, "gfx/crosshair3"))
-                       pic->tex = draw_generatecrosshair(2);
-               if (pic->tex == NULL && !strcmp(path, "gfx/crosshair4"))
-                       pic->tex = draw_generatecrosshair(3);
-               if (pic->tex == NULL && !strcmp(path, "gfx/crosshair5"))
-                       pic->tex = draw_generatecrosshair(4);
-               if (pic->tex == NULL && !strcmp(path, "gfx/crosshair6"))
-                       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
-                       if (strncmp(path, "gfx/crosshair", 13))
-                               Con_Printf("Draw_CachePic: failed to load %s\n", path);
-                       pic->tex = r_texture_notexture;
-               }
+               pic->tex = draw_generatepic(path);
                pic->width = R_TextureWidth(pic->tex);
                pic->height = R_TextureHeight(pic->tex);
        }
@@ -625,9 +693,6 @@ static void gl_draw_start(void)
        for(i = 0; i < MAX_FONTS; ++i)
                LoadFont(false, va("gfx/font_%s", dp_fonts[i].title), &dp_fonts[i]);
 
-       for (i = 1;i <= NUMCROSSHAIRS;i++)
-               r_crosshairs[i] = Draw_CachePic(va("gfx/crosshair%i", i), true);
-
        // draw the loading screen so people have something to see in the newly opened window
        SCR_UpdateLoadingScreen(true);
 }
index 376e233..57b9538 100644 (file)
@@ -1998,7 +1998,6 @@ extern void GL_Main_Init(void);
 extern void R_Shadow_Init(void);
 extern void R_Sky_Init(void);
 extern void GL_Surf_Init(void);
-extern void R_Light_Init(void);
 extern void R_Particles_Init(void);
 extern void R_Explosion_Init(void);
 extern void gl_backend_init(void);
@@ -2016,7 +2015,6 @@ void Render_Init(void)
        R_Sky_Init();
        GL_Surf_Init();
        Sbar_Init();
-       R_Light_Init();
        R_Particles_Init();
        R_Explosion_Init();
        R_LightningBeams_Init();
index 36aa783..1b6a950 100644 (file)
@@ -118,7 +118,6 @@ OBJ_COMMON= \
        prvm_exec.o \
        r_explosion.o \
        r_lerpanim.o \
-       r_light.o \
        r_lightning.o \
        r_modules.o \
        r_shadow.o \
index e73e819..89193b8 100644 (file)
--- a/palette.c
+++ b/palette.c
@@ -19,6 +19,7 @@ unsigned int palette_bgra_onlyfullbrights[256];
 unsigned int palette_bgra_pantsaswhite[256];
 unsigned int palette_bgra_shirtaswhite[256];
 unsigned int palette_bgra_transparent[256];
+unsigned int palette_bgra_embeddedpic[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] =
@@ -204,6 +205,12 @@ void Palette_Load(void)
        fs_offset_t filesize;
        unsigned char *palfile;
        unsigned char texturegammaramp[256];
+       union
+       {
+               unsigned char b[4];
+               unsigned int i;
+       }
+       bgra;
 
        gamma = 1;
        scale = 1;
@@ -279,6 +286,13 @@ void Palette_Load(void)
        if(palfile)
                Mem_Free(palfile);
 
+       memset(palette_bgra_embeddedpic, 0, sizeof(palette_bgra_embeddedpic));
+       for (i = '1';i <= '7';i++)
+       {
+               Vector4Set(bgra.b, 255, 255, 255, (i - '0') * 255 / 7);
+               palette_bgra_embeddedpic[i] = bgra.i;
+       }
+
        Palette_SetupSpecialPalettes();
 }
 
index e7603bb..1105877 100644 (file)
--- a/palette.h
+++ b/palette.h
@@ -18,6 +18,7 @@ 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];
+extern unsigned int palette_bgra_embeddedpic[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_light.c b/r_light.c
deleted file mode 100644 (file)
index 8fd4a01..0000000
--- a/r_light.c
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
-Copyright (C) 1996-1997 Id Software, Inc.
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
-See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-
-*/
-// r_light.c
-
-#include "quakedef.h"
-#include "cl_collision.h"
-#include "r_shadow.h"
-
-cvar_t r_coronas = {CVAR_SAVE, "r_coronas", "1", "brightness of corona flare effects around certain lights, 0 disables corona effects"};
-cvar_t gl_flashblend = {CVAR_SAVE, "gl_flashblend", "0", "render bright coronas for dynamic lights instead of actual lighting, fast but ugly"};
-
-static rtexture_t *lightcorona;
-static rtexturepool_t *lighttexturepool;
-
-void r_light_start(void)
-{
-       float dx, dy;
-       int x, y, a;
-       unsigned char pixels[32][32][4];
-       lighttexturepool = R_AllocTexturePool();
-       for (y = 0;y < 32;y++)
-       {
-               dy = (y - 15.5f) * (1.0f / 16.0f);
-               for (x = 0;x < 32;x++)
-               {
-                       dx = (x - 15.5f) * (1.0f / 16.0f);
-                       a = (int)(((1.0f / (dx * dx + dy * dy + 0.2f)) - (1.0f / (1.0f + 0.2))) * 32.0f / (1.0f / (1.0f + 0.2)));
-                       a = bound(0, a, 255);
-                       pixels[y][x][0] = a;
-                       pixels[y][x][1] = a;
-                       pixels[y][x][2] = a;
-                       pixels[y][x][3] = 255;
-               }
-       }
-       lightcorona = R_LoadTexture2D(lighttexturepool, "lightcorona", 32, 32, &pixels[0][0][0], TEXTYPE_BGRA, TEXF_PRECACHE, NULL);
-}
-
-void r_light_shutdown(void)
-{
-       lighttexturepool = NULL;
-       lightcorona = NULL;
-}
-
-void r_light_newmap(void)
-{
-       int i;
-       for (i = 0;i < MAX_LIGHTSTYLES;i++)
-               r_refdef.lightstylevalue[i] = 256;              // normal light value
-}
-
-void R_Light_Init(void)
-{
-       Cvar_RegisterVariable(&r_coronas);
-       Cvar_RegisterVariable(&gl_flashblend);
-       R_RegisterModule("R_Light", r_light_start, r_light_shutdown, r_light_newmap);
-}
-
-void R_DrawCoronas(void)
-{
-       int i, lnum, flag;
-       float cscale, scale;
-       dlight_t *light;
-       rtlight_t *rtlight;
-       if (r_coronas.value < (1.0f / 256.0f) && !gl_flashblend.integer)
-               return;
-       R_Mesh_Matrix(&identitymatrix);
-       flag = r_refdef.rtworld ? LIGHTFLAG_REALTIMEMODE : LIGHTFLAG_NORMALMODE;
-       // FIXME: these traces should scan all render entities instead of cl.world
-       for (lnum = 0, light = r_shadow_worldlightchain;light;light = light->next, lnum++)
-       {
-               rtlight = &light->rtlight;
-               if (!(rtlight->flags & flag))
-                       continue;
-               if (rtlight->corona * r_coronas.value <= 0)
-                       continue;
-               if (r_shadow_debuglight.integer >= 0 && r_shadow_debuglight.integer != lnum)
-                       continue;
-               cscale = rtlight->corona * r_coronas.value* 0.25f;
-               scale = rtlight->radius * rtlight->coronasizescale;
-               if (VectorDistance2(rtlight->shadoworigin, r_view.origin) < 16.0f * 16.0f)
-                       continue;
-               if (CL_Move(r_view.origin, vec3_origin, vec3_origin, rtlight->shadoworigin, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, true, false, NULL, false).fraction < 1)
-                       continue;
-               R_DrawSprite(GL_ONE, GL_ONE, lightcorona, NULL, true, false, rtlight->shadoworigin, r_view.right, r_view.up, scale, -scale, -scale, scale, rtlight->color[0] * cscale, rtlight->color[1] * cscale, rtlight->color[2] * cscale, 1);
-       }
-       for (i = 0;i < r_refdef.numlights;i++)
-       {
-               rtlight = &r_refdef.lights[i];
-               if (!(rtlight->flags & flag))
-                       continue;
-               if (rtlight->corona <= 0)
-                       continue;
-               if (VectorDistance2(rtlight->shadoworigin, r_view.origin) < 32.0f * 32.0f)
-                       continue;
-               if (gl_flashblend.integer)
-               {
-                       cscale = rtlight->corona * 1.0f;
-                       scale = rtlight->radius * rtlight->coronasizescale * 2.0f;
-               }
-               else
-               {
-                       cscale = rtlight->corona * r_coronas.value* 0.25f;
-                       scale = rtlight->radius * rtlight->coronasizescale;
-               }
-               if (VectorLength(rtlight->color) * cscale < (1.0f / 256.0f))
-                       continue;
-               if (CL_Move(r_view.origin, vec3_origin, vec3_origin, rtlight->shadoworigin, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, true, false, NULL, false).fraction < 1)
-                       continue;
-               R_DrawSprite(GL_ONE, GL_ONE, lightcorona, NULL, true, false, rtlight->shadoworigin, r_view.right, r_view.up, scale, -scale, -scale, scale, rtlight->color[0] * cscale, rtlight->color[1] * cscale, rtlight->color[2] * cscale, 1);
-       }
-}
-
-/*
-=============================================================================
-
-LIGHT SAMPLING
-
-=============================================================================
-*/
-
-void R_CompleteLightPoint(vec3_t ambientcolor, vec3_t diffusecolor, vec3_t diffusenormal, const vec3_t p, int dynamic)
-{
-       VectorClear(diffusecolor);
-       VectorClear(diffusenormal);
-
-       if (!r_fullbright.integer && r_refdef.worldmodel && r_refdef.worldmodel->brush.LightPoint)
-       {
-               ambientcolor[0] = ambientcolor[1] = ambientcolor[2] = r_ambient.value * (2.0f / 128.0f);
-               r_refdef.worldmodel->brush.LightPoint(r_refdef.worldmodel, p, ambientcolor, diffusecolor, diffusenormal);
-       }
-       else
-               VectorSet(ambientcolor, 1, 1, 1);
-
-       if (dynamic)
-       {
-               int i;
-               float f, v[3];
-               rtlight_t *light;
-               for (i = 0;i < r_refdef.numlights;i++)
-               {
-                       light = &r_refdef.lights[i];
-                       Matrix4x4_Transform(&light->matrix_worldtolight, p, v);
-                       f = 1 - VectorLength2(v);
-                       if (f > 0 && CL_Move(p, vec3_origin, vec3_origin, light->shadoworigin, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, true, false, NULL, false).fraction == 1)
-                               VectorMA(ambientcolor, f, light->currentcolor, ambientcolor);
-               }
-       }
-}
diff --git a/r_light.h b/r_light.h
deleted file mode 100644 (file)
index 7af2aad..0000000
--- a/r_light.h
+++ /dev/null
@@ -1,9 +0,0 @@
-
-#ifndef R_LIGHT_H
-#define R_LIGHT_H
-
-void R_DrawCoronas(void);
-void R_CompleteLightPoint(vec3_t ambientcolor, vec3_t diffusecolor, vec3_t diffusenormal, const vec3_t p, int dynamic);
-
-#endif
-
index fedb600..9d103b0 100644 (file)
@@ -194,6 +194,7 @@ rtexturepool_t *r_shadow_texturepool;
 rtexture_t *r_shadow_attenuationgradienttexture;
 rtexture_t *r_shadow_attenuation2dtexture;
 rtexture_t *r_shadow_attenuation3dtexture;
+rtexture_t *r_shadow_lightcorona;
 
 // lights are reloaded when this changes
 char r_shadow_mapname[MAX_QPATH];
@@ -232,6 +233,8 @@ cvar_t r_shadow_culltriangles = {0, "r_shadow_culltriangles", "1", "performs mor
 cvar_t r_shadow_polygonfactor = {0, "r_shadow_polygonfactor", "0", "how much to enlarge shadow volume polygons when rendering (should be 0!)"};
 cvar_t r_shadow_polygonoffset = {0, "r_shadow_polygonoffset", "1", "how much to push shadow volumes into the distance when rendering, to reduce chances of zfighting artifacts (should not be less than 0)"};
 cvar_t r_shadow_texture3d = {0, "r_shadow_texture3d", "1", "use 3D voxel textures for spherical attenuation rather than cylindrical (does not affect r_glsl lighting)"};
+cvar_t r_coronas = {CVAR_SAVE, "r_coronas", "1", "brightness of corona flare effects around certain lights, 0 disables corona effects"};
+cvar_t gl_flashblend = {CVAR_SAVE, "gl_flashblend", "0", "render bright coronas for dynamic lights instead of actual lighting, fast but ugly"};
 cvar_t gl_ext_separatestencil = {0, "gl_ext_separatestencil", "1", "make use of OpenGL 2.0 glStencilOpSeparate or GL_ATI_separate_stencil extension"};
 cvar_t gl_ext_stenciltwoside = {0, "gl_ext_stenciltwoside", "1", "make use of GL_EXT_stenciltwoside extension (NVIDIA only)"};
 cvar_t r_editlights = {0, "r_editlights", "0", "enables .rtlights file editing mode"};
@@ -253,7 +256,7 @@ static float r_shadow_attenlinearscale; // r_shadow_lightattenuationlinearscale
 static float r_shadow_attentable[ATTENTABLESIZE+1];
 
 rtlight_t *r_shadow_compilingrtlight;
-dlight_t *r_shadow_worldlightchain;
+static memexpandablearray_t r_shadow_worldlightsarray;
 dlight_t *r_shadow_selectedlight;
 dlight_t r_shadow_bufferlight;
 vec3_t r_editlights_cursorlocation;
@@ -283,11 +286,11 @@ static void R_Shadow_MakeTextures(void);
 
 // VorteX: custom editor light sprites
 #define EDLIGHTSPRSIZE                 8
-#define EDLIGHTSELECTSPRSIZE   12
 cachepic_t *r_editlights_sprcursor;
 cachepic_t *r_editlights_sprlight;
 cachepic_t *r_editlights_sprnoshadowlight;
-cachepic_t *r_editlights_sprcubemap;
+cachepic_t *r_editlights_sprcubemaplight;
+cachepic_t *r_editlights_sprcubemapnoshadowlight;
 cachepic_t *r_editlights_sprselection;
 
 void r_shadow_start(void)
@@ -453,6 +456,8 @@ void R_Shadow_Init(void)
        Cvar_RegisterVariable(&r_shadow_polygonfactor);
        Cvar_RegisterVariable(&r_shadow_polygonoffset);
        Cvar_RegisterVariable(&r_shadow_texture3d);
+       Cvar_RegisterVariable(&r_coronas);
+       Cvar_RegisterVariable(&gl_flashblend);
        Cvar_RegisterVariable(&gl_ext_separatestencil);
        Cvar_RegisterVariable(&gl_ext_stenciltwoside);
        if (gamemode == GAME_TENEBRAE)
@@ -462,7 +467,7 @@ void R_Shadow_Init(void)
        }
        Cmd_AddCommand("r_shadow_help", R_Shadow_Help_f, "prints documentation on console commands and variables used by realtime lighting and shadowing system");
        R_Shadow_EditLights_Init();
-       r_shadow_worldlightchain = NULL;
+       Mem_ExpandableArray_NewArray(&r_shadow_worldlightsarray, r_main_mempool, sizeof(dlight_t), 128);
        maxshadowtriangles = 0;
        shadowelements = NULL;
        maxshadowvertices = 0;
@@ -916,6 +921,28 @@ void R_Shadow_RenderVolume(int numvertices, int numtriangles, const float *verte
        CHECKGLERROR
 }
 
+static void R_Shadow_MakeTextures_MakeCorona(void)
+{
+       float dx, dy;
+       int x, y, a;
+       unsigned char pixels[32][32][4];
+       for (y = 0;y < 32;y++)
+       {
+               dy = (y - 15.5f) * (1.0f / 16.0f);
+               for (x = 0;x < 32;x++)
+               {
+                       dx = (x - 15.5f) * (1.0f / 16.0f);
+                       a = (int)(((1.0f / (dx * dx + dy * dy + 0.2f)) - (1.0f / (1.0f + 0.2))) * 32.0f / (1.0f / (1.0f + 0.2)));
+                       a = bound(0, a, 255);
+                       pixels[y][x][0] = a;
+                       pixels[y][x][1] = a;
+                       pixels[y][x][2] = a;
+                       pixels[y][x][3] = 255;
+               }
+       }
+       r_shadow_lightcorona = R_LoadTexture2D(r_shadow_texturepool, "lightcorona", 32, 32, &pixels[0][0][0], TEXTYPE_BGRA, TEXF_PRECACHE, NULL);
+}
+
 static unsigned int R_Shadow_MakeTextures_SamplePoint(float x, float y, float z)
 {
        float dist = sqrt(x*x+y*y+z*z);
@@ -963,11 +990,14 @@ static void R_Shadow_MakeTextures(void)
                r_shadow_attenuation3dtexture = NULL;
        Mem_Free(data);
 
+       R_Shadow_MakeTextures_MakeCorona();
+
        // Editor light sprites
        r_editlights_sprcursor = Draw_CachePic("gfx/editlights/cursor", true);
        r_editlights_sprlight = Draw_CachePic("gfx/editlights/light", true);
        r_editlights_sprnoshadowlight = Draw_CachePic("gfx/editlights/noshadow", true);
-       r_editlights_sprcubemap = Draw_CachePic("gfx/editlights/cubemap", true);
+       r_editlights_sprcubemaplight = Draw_CachePic("gfx/editlights/cubemaplight", true);
+       r_editlights_sprcubemapnoshadowlight = Draw_CachePic("gfx/editlights/cubemapnoshadowlight", true);
        r_editlights_sprselection = Draw_CachePic("gfx/editlights/selection", true);
 }
 
@@ -2496,9 +2526,15 @@ void R_RTLight_Uncompile(rtlight_t *rtlight)
 
 void R_Shadow_UncompileWorldLights(void)
 {
+       size_t lightindex;
        dlight_t *light;
-       for (light = r_shadow_worldlightchain;light;light = light->next)
+       for (lightindex = 0;lightindex < Mem_ExpandableArray_IndexRange(&r_shadow_worldlightsarray);lightindex++)
+       {
+               light = Mem_ExpandableArray_RecordAtIndex(&r_shadow_worldlightsarray, lightindex);
+               if (!light)
+                       continue;
                R_RTLight_Uncompile(&light->rtlight);
+       }
 }
 
 void R_Shadow_ComputeShadowCasterCullingPlanes(rtlight_t *rtlight)
@@ -3054,7 +3090,9 @@ void R_DrawRTLight(rtlight_t *rtlight, qboolean visible)
 void R_Shadow_DrawLightSprites(void);
 void R_ShadowVolumeLighting(qboolean visible)
 {
-       int lnum, flag;
+       int flag;
+       int lnum;
+       size_t lightindex;
        dlight_t *light;
 
        if (r_refdef.worldmodel && strncmp(r_refdef.worldmodel->name, r_shadow_mapname, sizeof(r_shadow_mapname)))
@@ -3068,14 +3106,20 @@ void R_ShadowVolumeLighting(qboolean visible)
        flag = r_refdef.rtworld ? LIGHTFLAG_REALTIMEMODE : LIGHTFLAG_NORMALMODE;
        if (r_shadow_debuglight.integer >= 0)
        {
-               for (lnum = 0, light = r_shadow_worldlightchain;light;lnum++, light = light->next)
-                       if (lnum == r_shadow_debuglight.integer && (light->flags & flag))
-                               R_DrawRTLight(&light->rtlight, visible);
+               lightindex = r_shadow_debuglight.integer;
+               light = Mem_ExpandableArray_RecordAtIndex(&r_shadow_worldlightsarray, lightindex);
+               if (light && (light->flags & flag))
+                       R_DrawRTLight(&light->rtlight, visible);
        }
        else
-               for (lnum = 0, light = r_shadow_worldlightchain;light;lnum++, light = light->next)
-                       if (light->flags & flag)
+       {
+               for (lightindex = 0;lightindex < Mem_ExpandableArray_IndexRange(&r_shadow_worldlightsarray);lightindex++)
+               {
+                       light = Mem_ExpandableArray_RecordAtIndex(&r_shadow_worldlightsarray, lightindex);
+                       if (light && (light->flags & flag))
                                R_DrawRTLight(&light->rtlight, visible);
+               }
+       }
        if (r_refdef.rtdlight)
                for (lnum = 0;lnum < r_refdef.numlights;lnum++)
                        R_DrawRTLight(&r_refdef.lights[lnum], visible);
@@ -3171,6 +3215,66 @@ void R_DrawModelShadows(void)
        R_Shadow_RenderMode_End();
 }
 
+void R_DrawCoronas(void)
+{
+       int i, flag;
+       float cscale, scale;
+       size_t lightindex;
+       dlight_t *light;
+       rtlight_t *rtlight;
+       if (r_coronas.value < (1.0f / 256.0f) && !gl_flashblend.integer)
+               return;
+       R_Mesh_Matrix(&identitymatrix);
+       flag = r_refdef.rtworld ? LIGHTFLAG_REALTIMEMODE : LIGHTFLAG_NORMALMODE;
+       // FIXME: these traces should scan all render entities instead of cl.world
+       for (lightindex = 0;lightindex < Mem_ExpandableArray_IndexRange(&r_shadow_worldlightsarray);lightindex++)
+       {
+               light = Mem_ExpandableArray_RecordAtIndex(&r_shadow_worldlightsarray, lightindex);
+               if (!light)
+                       continue;
+               rtlight = &light->rtlight;
+               if (!(rtlight->flags & flag))
+                       continue;
+               if (rtlight->corona * r_coronas.value <= 0)
+                       continue;
+               if (r_shadow_debuglight.integer >= 0 && r_shadow_debuglight.integer != (int)lightindex)
+                       continue;
+               cscale = rtlight->corona * r_coronas.value* 0.25f;
+               scale = rtlight->radius * rtlight->coronasizescale;
+               if (VectorDistance2(rtlight->shadoworigin, r_view.origin) < 16.0f * 16.0f)
+                       continue;
+               if (CL_Move(r_view.origin, vec3_origin, vec3_origin, rtlight->shadoworigin, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, true, false, NULL, false).fraction < 1)
+                       continue;
+               R_DrawSprite(GL_ONE, GL_ONE, r_shadow_lightcorona, NULL, true, false, rtlight->shadoworigin, r_view.right, r_view.up, scale, -scale, -scale, scale, rtlight->color[0] * cscale, rtlight->color[1] * cscale, rtlight->color[2] * cscale, 1);
+       }
+       for (i = 0;i < r_refdef.numlights;i++)
+       {
+               rtlight = &r_refdef.lights[i];
+               if (!(rtlight->flags & flag))
+                       continue;
+               if (rtlight->corona <= 0)
+                       continue;
+               if (VectorDistance2(rtlight->shadoworigin, r_view.origin) < 32.0f * 32.0f)
+                       continue;
+               if (gl_flashblend.integer)
+               {
+                       cscale = rtlight->corona * 1.0f;
+                       scale = rtlight->radius * rtlight->coronasizescale * 2.0f;
+               }
+               else
+               {
+                       cscale = rtlight->corona * r_coronas.value* 0.25f;
+                       scale = rtlight->radius * rtlight->coronasizescale;
+               }
+               if (VectorLength(rtlight->color) * cscale < (1.0f / 256.0f))
+                       continue;
+               if (CL_Move(r_view.origin, vec3_origin, vec3_origin, rtlight->shadoworigin, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, true, false, NULL, false).fraction < 1)
+                       continue;
+               R_DrawSprite(GL_ONE, GL_ONE, r_shadow_lightcorona, NULL, true, false, rtlight->shadoworigin, r_view.right, r_view.up, scale, -scale, -scale, scale, rtlight->color[0] * cscale, rtlight->color[1] * cscale, rtlight->color[2] * cscale, 1);
+       }
+}
+
+
 
 //static char *suffix[6] = {"ft", "bk", "rt", "lf", "up", "dn"};
 typedef struct suffixinfo_s
@@ -3294,11 +3398,7 @@ void R_Shadow_FreeCubemaps(void)
 
 dlight_t *R_Shadow_NewWorldLight(void)
 {
-       dlight_t *light;
-       light = (dlight_t *)Mem_Alloc(r_main_mempool, sizeof(dlight_t));
-       light->next = r_shadow_worldlightchain;
-       r_shadow_worldlightchain = light;
-       return light;
+       return (dlight_t *)Mem_ExpandableArray_AllocRecord(&r_shadow_worldlightsarray);
 }
 
 void R_Shadow_UpdateWorldLight(dlight_t *light, vec3_t origin, vec3_t angles, vec3_t color, vec_t radius, vec_t corona, int style, int shadowenable, const char *cubemapname, vec_t coronasizescale, vec_t ambientscale, vec_t diffusescale, vec_t specularscale, int flags)
@@ -3339,19 +3439,22 @@ void R_Shadow_UpdateWorldLight(dlight_t *light, vec3_t origin, vec3_t angles, ve
 
 void R_Shadow_FreeWorldLight(dlight_t *light)
 {
-       dlight_t **lightpointer;
+       if (r_shadow_selectedlight == light)
+               r_shadow_selectedlight = NULL;
        R_RTLight_Uncompile(&light->rtlight);
-       for (lightpointer = &r_shadow_worldlightchain;*lightpointer && *lightpointer != light;lightpointer = &(*lightpointer)->next);
-       if (*lightpointer != light)
-               Sys_Error("R_Shadow_FreeWorldLight: light not linked into chain");
-       *lightpointer = light->next;
-       Mem_Free(light);
+       Mem_ExpandableArray_FreeRecord(&r_shadow_worldlightsarray, light);
 }
 
 void R_Shadow_ClearWorldLights(void)
 {
-       while (r_shadow_worldlightchain)
-               R_Shadow_FreeWorldLight(r_shadow_worldlightchain);
+       size_t lightindex;
+       dlight_t *light;
+       for (lightindex = 0;lightindex < Mem_ExpandableArray_IndexRange(&r_shadow_worldlightsarray);lightindex++)
+       {
+               light = Mem_ExpandableArray_RecordAtIndex(&r_shadow_worldlightsarray, lightindex);
+               if (light)
+                       R_Shadow_FreeWorldLight(light);
+       }
        r_shadow_selectedlight = NULL;
        R_Shadow_FreeCubemaps();
 }
@@ -3368,62 +3471,69 @@ void R_Shadow_SelectLight(dlight_t *light)
 void R_Shadow_DrawCursor_TransparentCallback(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist)
 {
        // this is never batched (there can be only one)
-       R_DrawSprite(GL_SRC_ALPHA, GL_ONE, r_editlights_sprcursor->tex, NULL, false, false, r_editlights_cursorlocation, r_view.right, r_view.up, EDLIGHTSPRSIZE, -EDLIGHTSPRSIZE, -EDLIGHTSPRSIZE, EDLIGHTSPRSIZE, 1, 1, 1, 0.5f);
+       R_DrawSprite(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, r_editlights_sprcursor->tex, r_editlights_sprcursor->tex, false, false, r_editlights_cursorlocation, r_view.right, r_view.up, EDLIGHTSPRSIZE, -EDLIGHTSPRSIZE, -EDLIGHTSPRSIZE, EDLIGHTSPRSIZE, 1, 1, 1, 1);
 }
 
 void R_Shadow_DrawLightSprite_TransparentCallback(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist)
 {
        float intensity;
-       float scaling;
+       float s;
        vec3_t spritecolor;
+       cachepic_t *pic;
 
        // this is never batched (due to the ent parameter changing every time)
        // so numsurfaces == 1 and surfacelist[0] == lightnumber
        const dlight_t *light = (dlight_t *)ent;
-       intensity = 1;
-       scaling = 1;
-       if (light->selected)
-               scaling = 1.25 + 0.25*sin(realtime * M_PI * 1.5);
-       // vortex: get sprites color (solve 0 0 0 colored light being invisible here)
-       spritecolor[0] = max(0.1, light->color[0]);
-       spritecolor[1] = max(0.1, light->color[1]);
-       spritecolor[2] = max(0.1, light->color[2]);
+       s = EDLIGHTSPRSIZE;
+       intensity = 0.5f;
+       VectorScale(light->color, intensity, spritecolor);
+       if (VectorLength(spritecolor) < 0.1732f)
+               VectorSet(spritecolor, 0.1f, 0.1f, 0.1f);
+       if (VectorLength(spritecolor) > 1.0f)
+               VectorNormalize(spritecolor);
 
        // draw light sprite
-       if (!light->shadow)
-       {
-               intensity *= 0.5f;
-               R_DrawSprite(GL_SRC_ALPHA, GL_ONE, r_editlights_sprnoshadowlight->tex, NULL, false, false, light->origin, r_view.right, r_view.up, EDLIGHTSPRSIZE*scaling, -EDLIGHTSPRSIZE*scaling, -EDLIGHTSPRSIZE*scaling, EDLIGHTSPRSIZE*scaling, spritecolor[0]*intensity, spritecolor[1]*intensity, spritecolor[2]*intensity, 1);
-       }
+       if (light->cubemapname[0] && !light->shadow)
+               pic = r_editlights_sprcubemapnoshadowlight;
+       else if (light->cubemapname[0])
+               pic = r_editlights_sprcubemaplight;
+       else if (!light->shadow)
+               pic = r_editlights_sprnoshadowlight;
        else
-               R_DrawSprite(GL_SRC_ALPHA, GL_ONE, r_editlights_sprlight->tex, NULL, false, false, light->origin, r_view.right, r_view.up, EDLIGHTSELECTSPRSIZE*scaling, -EDLIGHTSELECTSPRSIZE*scaling, -EDLIGHTSELECTSPRSIZE*scaling, EDLIGHTSELECTSPRSIZE*scaling, spritecolor[0]*intensity, spritecolor[1]*intensity, spritecolor[2]*intensity, 1);
-       // draw cubemap sprite over light
-       if (light->cubemapname[0])
-               R_DrawSprite(GL_SRC_ALPHA, GL_ONE, r_editlights_sprcubemap->tex, NULL, false, false, light->origin, r_view.right, r_view.up, EDLIGHTSPRSIZE*scaling, -EDLIGHTSPRSIZE*scaling, -EDLIGHTSPRSIZE*scaling, EDLIGHTSPRSIZE*scaling, spritecolor[0]*intensity, spritecolor[1]*intensity, spritecolor[2]*intensity, 1);
+               pic = r_editlights_sprlight;
+       R_DrawSprite(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, pic->tex, pic->tex, false, false, light->origin, r_view.right, r_view.up, s, -s, -s, s, spritecolor[0], spritecolor[1], spritecolor[2], 1);
        // draw selection sprite if light is selected
        if (light->selected)
-               R_DrawSprite(GL_SRC_ALPHA, GL_ONE, r_editlights_sprselection->tex, NULL, false, false, light->origin, r_view.right, r_view.up, EDLIGHTSPRSIZE*scaling, -EDLIGHTSPRSIZE*scaling, -EDLIGHTSPRSIZE*scaling, EDLIGHTSPRSIZE*scaling, spritecolor[0]*intensity, spritecolor[1]*intensity, spritecolor[2]*intensity, 1);
+               R_DrawSprite(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, r_editlights_sprselection->tex, r_editlights_sprselection->tex, false, false, light->origin, r_view.right, r_view.up, s, -s, -s, s, 1, 1, 1, 1);
        // VorteX todo: add normalmode/realtime mode light overlay sprites?
 }
 
 void R_Shadow_DrawLightSprites(void)
 {
-       int i;
+       size_t lightindex;
        dlight_t *light;
-
-       for (i = 0, light = r_shadow_worldlightchain;light;i++, light = light->next)
-               R_MeshQueue_AddTransparent(light->origin, R_Shadow_DrawLightSprite_TransparentCallback, (entity_render_t *)light, 1+(i % 5), &light->rtlight);
+       for (lightindex = 0;lightindex < Mem_ExpandableArray_IndexRange(&r_shadow_worldlightsarray);lightindex++)
+       {
+               light = Mem_ExpandableArray_RecordAtIndex(&r_shadow_worldlightsarray, lightindex);
+               if (light)
+                       R_MeshQueue_AddTransparent(light->origin, R_Shadow_DrawLightSprite_TransparentCallback, (entity_render_t *)light, 5, &light->rtlight);
+       }
        R_MeshQueue_AddTransparent(r_editlights_cursorlocation, R_Shadow_DrawCursor_TransparentCallback, NULL, 0, NULL);
 }
 
 void R_Shadow_SelectLightInView(void)
 {
        float bestrating, rating, temp[3];
-       dlight_t *best, *light;
+       dlight_t *best;
+       size_t lightindex;
+       dlight_t *light;
        best = NULL;
        bestrating = 0;
-       for (light = r_shadow_worldlightchain;light;light = light->next)
+       for (lightindex = 0;lightindex < Mem_ExpandableArray_IndexRange(&r_shadow_worldlightsarray);lightindex++)
        {
+               light = Mem_ExpandableArray_RecordAtIndex(&r_shadow_worldlightsarray, lightindex);
+               if (!light)
+                       continue;
                VectorSubtract(light->origin, r_view.origin, temp);
                rating = (DotProduct(temp, r_view.forward) / sqrt(DotProduct(temp, temp)));
                if (rating >= 0.95)
@@ -3534,12 +3644,13 @@ void R_Shadow_LoadWorldLights(void)
 
 void R_Shadow_SaveWorldLights(void)
 {
+       size_t lightindex;
        dlight_t *light;
        size_t bufchars, bufmaxchars;
        char *buf, *oldbuf;
        char name[MAX_QPATH];
        char line[MAX_INPUTLINE];
-       if (!r_shadow_worldlightchain)
+       if (!Mem_ExpandableArray_IndexRange(&r_shadow_worldlightsarray))
                return;
        if (r_refdef.worldmodel == NULL)
        {
@@ -3550,8 +3661,11 @@ void R_Shadow_SaveWorldLights(void)
        strlcat (name, ".rtlights", sizeof (name));
        bufchars = bufmaxchars = 0;
        buf = NULL;
-       for (light = r_shadow_worldlightchain;light;light = light->next)
+       for (lightindex = 0;lightindex < Mem_ExpandableArray_IndexRange(&r_shadow_worldlightsarray);lightindex++)
        {
+               light = Mem_ExpandableArray_RecordAtIndex(&r_shadow_worldlightsarray, lightindex);
+               if (!light)
+                       continue;
                if (light->coronasizescale != 0.25f || light->ambientscale != 0 || light->diffusescale != 1 || light->specularscale != 1 || light->flags != LIGHTFLAG_REALTIMEMODE)
                        sprintf(line, "%s%f %f %f %f %f %f %f %d \"%s\" %f %f %f %f %f %f %f %f %i\n", light->shadow ? "" : "!", light->origin[0], light->origin[1], light->origin[2], light->radius, light->color[0], light->color[1], light->color[2], light->style, light->cubemapname, light->corona, light->angles[0], light->angles[1], light->angles[2], light->coronasizescale, light->ambientscale, light->diffusescale, light->specularscale, light->flags);
                else if (light->cubemapname[0] || light->corona || light->angles[0] || light->angles[1] || light->angles[2])
@@ -3901,10 +4015,10 @@ void R_Shadow_EditLights_Reload_f(void)
        strlcpy(r_shadow_mapname, r_refdef.worldmodel->name, sizeof(r_shadow_mapname));
        R_Shadow_ClearWorldLights();
        R_Shadow_LoadWorldLights();
-       if (r_shadow_worldlightchain == NULL)
+       if (!Mem_ExpandableArray_IndexRange(&r_shadow_worldlightsarray))
        {
                R_Shadow_LoadLightsFile();
-               if (r_shadow_worldlightchain == NULL)
+               if (!Mem_ExpandableArray_IndexRange(&r_shadow_worldlightsarray))
                        R_Shadow_LoadWorldLightsFromMap_LightArghliteTyrlite();
        }
 }
@@ -4262,6 +4376,7 @@ void R_Shadow_EditLights_Edit_f(void)
 
 void R_Shadow_EditLights_EditAll_f(void)
 {
+       size_t lightindex;
        dlight_t *light;
 
        if (!r_editlights.integer)
@@ -4270,8 +4385,11 @@ void R_Shadow_EditLights_EditAll_f(void)
                return;
        }
 
-       for (light = r_shadow_worldlightchain;light;light = light->next)
+       for (lightindex = 0;lightindex < Mem_ExpandableArray_IndexRange(&r_shadow_worldlightsarray);lightindex++)
        {
+               light = Mem_ExpandableArray_RecordAtIndex(&r_shadow_worldlightsarray, lightindex);
+               if (!light)
+                       continue;
                R_Shadow_SelectLight(light);
                R_Shadow_EditLights_Edit_f();
        }
@@ -4280,6 +4398,7 @@ void R_Shadow_EditLights_EditAll_f(void)
 void R_Shadow_EditLights_DrawSelectedLightProperties(void)
 {
        int lightnumber, lightcount;
+       size_t lightindex;
        dlight_t *light;
        float x, y;
        char temp[256];
@@ -4290,11 +4409,17 @@ void R_Shadow_EditLights_DrawSelectedLightProperties(void)
        DrawQ_Pic(x-5, y-5, NULL, 250, 155, 0, 0, 0, 0.75, 0);
        lightnumber = -1;
        lightcount = 0;
-       for (lightcount = 0, light = r_shadow_worldlightchain;light;lightcount++, light = light->next)
+       for (lightindex = 0;lightindex < Mem_ExpandableArray_IndexRange(&r_shadow_worldlightsarray);lightindex++)
+       {
+               light = Mem_ExpandableArray_RecordAtIndex(&r_shadow_worldlightsarray, lightindex);
+               if (!light)
+                       continue;
                if (light == r_shadow_selectedlight)
-                       lightnumber = lightcount;
+                       lightnumber = lightindex;
+               lightcount++;
+       }
        sprintf(temp, "Cursor origin: %.0f %.0f %.0f", r_editlights_cursorlocation[0], r_editlights_cursorlocation[1], r_editlights_cursorlocation[2]); DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, false);y += 8;
-       sprintf(temp, "Total lights : %i", lightcount); DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, false);y += 8;
+       sprintf(temp, "Total lights : %i active (%i total)", lightcount, (int)Mem_ExpandableArray_IndexRange(&r_shadow_worldlightsarray)); DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, false);y += 8;
        y += 8;
        if (r_shadow_selectedlight == NULL)
                return;
@@ -4484,3 +4609,41 @@ void R_Shadow_EditLights_Init(void)
        Cmd_AddCommand("r_editlights_pasteinfo", R_Shadow_EditLights_PasteInfo_f, "apply the stored properties onto the selected light (making it exactly identical except for origin)");
 }
 
+
+
+/*
+=============================================================================
+
+LIGHT SAMPLING
+
+=============================================================================
+*/
+
+void R_CompleteLightPoint(vec3_t ambientcolor, vec3_t diffusecolor, vec3_t diffusenormal, const vec3_t p, int dynamic)
+{
+       VectorClear(diffusecolor);
+       VectorClear(diffusenormal);
+
+       if (!r_fullbright.integer && r_refdef.worldmodel && r_refdef.worldmodel->brush.LightPoint)
+       {
+               ambientcolor[0] = ambientcolor[1] = ambientcolor[2] = r_ambient.value * (2.0f / 128.0f);
+               r_refdef.worldmodel->brush.LightPoint(r_refdef.worldmodel, p, ambientcolor, diffusecolor, diffusenormal);
+       }
+       else
+               VectorSet(ambientcolor, 1, 1, 1);
+
+       if (dynamic)
+       {
+               int i;
+               float f, v[3];
+               rtlight_t *light;
+               for (i = 0;i < r_refdef.numlights;i++)
+               {
+                       light = &r_refdef.lights[i];
+                       Matrix4x4_Transform(&light->matrix_worldtolight, p, v);
+                       f = 1 - VectorLength2(v);
+                       if (f > 0 && CL_Move(p, vec3_origin, vec3_origin, light->shadoworigin, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, true, false, NULL, false).fraction == 1)
+                               VectorMA(ambientcolor, f, light->currentcolor, ambientcolor);
+               }
+       }
+}
index b77be83..d868ddd 100644 (file)
@@ -59,8 +59,6 @@ extern matrix4x4_t matrix_attenuationz;
 
 rtexture_t *R_Shadow_Cubemap(const char *basename);
 
-extern dlight_t *r_shadow_worldlightchain;
-
 void R_Shadow_UpdateWorldLightSelection(void);
 
 extern rtlight_t *r_shadow_compilingrtlight;
@@ -70,6 +68,7 @@ void R_RTLight_Compile(rtlight_t *rtlight);
 void R_RTLight_Uncompile(rtlight_t *rtlight);
 
 void R_ShadowVolumeLighting(qboolean visible);
+void R_DrawCoronas(void);
 
 int *R_Shadow_ResizeShadowElements(int numtris);
 
@@ -80,4 +79,6 @@ extern int *shadowmarklist;
 extern int shadowmarkcount;
 void R_Shadow_PrepareShadowMark(int numtris);
 
+void R_CompleteLightPoint(vec3_t ambientcolor, vec3_t diffusecolor, vec3_t diffusenormal, const vec3_t p, int dynamic);
+
 #endif
index a204f77..d60e8e4 100644 (file)
--- a/render.h
+++ b/render.h
@@ -174,8 +174,6 @@ extern cvar_t r_test;
 
 #include "gl_backend.h"
 
-#include "r_light.h"
-
 extern rtexture_t *r_texture_blanknormalmap;
 extern rtexture_t *r_texture_white;
 extern rtexture_t *r_texture_grey128;
diff --git a/sbar.c b/sbar.c
index 149d5a5..ec29774 100644 (file)
--- a/sbar.c
+++ b/sbar.c
@@ -1580,8 +1580,11 @@ void Sbar_Draw (void)
 
        Sbar_ShowFPS();
 
-       if (cl.csqc_vidvars.drawcrosshair && crosshair.integer >= 1 && crosshair.integer <= NUMCROSSHAIRS && !cl.intermission && !r_letterbox.value && (pic = r_crosshairs[crosshair.integer]))
+       if (cl.csqc_vidvars.drawcrosshair && crosshair.integer >= 1 && !cl.intermission && !r_letterbox.value)
+       {
+               pic = Draw_CachePic(va("gfx/crosshair%i", crosshair.integer), true);
                DrawQ_Pic((vid_conwidth.integer - pic->width * crosshair_size.value) * 0.5f, (vid_conheight.integer - pic->height * crosshair_size.value) * 0.5f, pic, pic->width * crosshair_size.value, pic->height * crosshair_size.value, crosshair_color_red.value, crosshair_color_green.value, crosshair_color_blue.value, crosshair_color_alpha.value, 0);
+       }
 
        if (cl_prydoncursor.integer)
                DrawQ_Pic((cl.cmd.cursor_screen[0] + 1) * 0.5 * vid_conwidth.integer, (cl.cmd.cursor_screen[1] + 1) * 0.5 * vid_conheight.integer, Draw_CachePic(va("gfx/prydoncursor%03i", cl_prydoncursor.integer), true), 0, 0, 1, 1, 1, 1, 0);