2 Copyright (C) 1996-1997 Id Software, Inc.
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 See the GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 #include "cl_collision.h"
26 cvar_t r_coronas = {CVAR_SAVE, "r_coronas", "1", "brightness of corona flare effects around certain lights, 0 disables corona effects"};
27 cvar_t gl_flashblend = {CVAR_SAVE, "gl_flashblend", "0", "render bright coronas for dynamic lights instead of actual lighting, fast but ugly"};
29 static rtexture_t *lightcorona;
30 static rtexturepool_t *lighttexturepool;
32 void r_light_start(void)
36 unsigned char pixels[32][32][4];
37 lighttexturepool = R_AllocTexturePool();
38 for (y = 0;y < 32;y++)
40 dy = (y - 15.5f) * (1.0f / 16.0f);
41 for (x = 0;x < 32;x++)
43 dx = (x - 15.5f) * (1.0f / 16.0f);
44 a = (int)(((1.0f / (dx * dx + dy * dy + 0.2f)) - (1.0f / (1.0f + 0.2))) * 32.0f / (1.0f / (1.0f + 0.2)));
49 pixels[y][x][3] = 255;
52 lightcorona = R_LoadTexture2D(lighttexturepool, "lightcorona", 32, 32, &pixels[0][0][0], TEXTYPE_RGBA, TEXF_PRECACHE, NULL);
55 void r_light_shutdown(void)
57 lighttexturepool = NULL;
61 void r_light_newmap(void)
64 for (i = 0;i < MAX_LIGHTSTYLES;i++)
65 r_refdef.lightstylevalue[i] = 264; // normal light value
68 void R_Light_Init(void)
70 Cvar_RegisterVariable(&r_coronas);
71 Cvar_RegisterVariable(&gl_flashblend);
72 R_RegisterModule("R_Light", r_light_start, r_light_shutdown, r_light_newmap);
75 void R_DrawCoronas(void)
78 float cscale, scale, viewdist, dist;
81 if (r_coronas.value < 0.01)
83 R_Mesh_Matrix(&identitymatrix);
84 viewdist = DotProduct(r_view.origin, r_view.forward);
85 flag = r_refdef.rtworld ? LIGHTFLAG_REALTIMEMODE : LIGHTFLAG_NORMALMODE;
86 // FIXME: these traces should scan all render entities instead of cl.world
87 for (lnum = 0, light = r_shadow_worldlightchain;light;light = light->next, lnum++)
89 if ((light->flags & flag) && light->corona * r_coronas.value > 0 && (r_shadow_debuglight.integer < 0 || r_shadow_debuglight.integer == lnum) && (dist = (DotProduct(light->rtlight.shadoworigin, r_view.forward) - viewdist)) >= 24.0f && CL_Move(light->rtlight.shadoworigin, vec3_origin, vec3_origin, r_view.origin, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, true, false, NULL, false).fraction == 1)
91 cscale = light->rtlight.corona * r_coronas.value * 0.25f;
92 scale = light->rtlight.radius * light->rtlight.coronasizescale;
93 R_DrawSprite(GL_ONE, GL_ONE, lightcorona, NULL, true, light->rtlight.shadoworigin, r_view.right, r_view.up, scale, -scale, -scale, scale, light->rtlight.color[0] * cscale, light->rtlight.color[1] * cscale, light->rtlight.color[2] * cscale, 1);
96 for (i = 0;i < r_refdef.numlights;i++)
98 rtlight = &r_refdef.lights[i];
99 if ((rtlight->flags & flag) && rtlight->corona * r_coronas.value > 0 && (dist = (DotProduct(rtlight->shadoworigin, r_view.forward) - viewdist)) >= 24.0f && CL_Move(rtlight->shadoworigin, vec3_origin, vec3_origin, r_view.origin, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, true, false, NULL, false).fraction == 1)
101 cscale = rtlight->corona * r_coronas.value * 0.25f;
102 scale = rtlight->radius * rtlight->coronasizescale;
103 if (gl_flashblend.integer)
108 R_DrawSprite(GL_ONE, GL_ONE, lightcorona, NULL, true, 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);
114 =============================================================================
118 =============================================================================
121 void R_CompleteLightPoint(vec3_t ambientcolor, vec3_t diffusecolor, vec3_t diffusenormal, const vec3_t p, int dynamic)
123 VectorClear(diffusecolor);
124 VectorClear(diffusenormal);
126 if (!r_fullbright.integer && r_refdef.worldmodel && r_refdef.worldmodel->brush.LightPoint)
128 ambientcolor[0] = ambientcolor[1] = ambientcolor[2] = r_ambient.value * (2.0f / 128.0f);
129 r_refdef.worldmodel->brush.LightPoint(r_refdef.worldmodel, p, ambientcolor, diffusecolor, diffusenormal);
132 VectorSet(ambientcolor, 1, 1, 1);
139 for (i = 0;i < r_refdef.numlights;i++)
141 light = &r_refdef.lights[i];
142 Matrix4x4_Transform(&light->matrix_worldtolight, p, v);
143 f = 1 - VectorLength2(v);
144 if (f > 0 && CL_Move(p, vec3_origin, vec3_origin, light->shadoworigin, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, true, false, NULL, false).fraction == 1)
145 VectorMA(ambientcolor, f, light->currentcolor, ambientcolor);