DarkPlaces
Game engine based on the Quake 1 engine by id Software, developed by LadyHavoc
 
r_lightning.c
Go to the documentation of this file.
1
2#include "quakedef.h"
3#include "image.h"
4
5cvar_t r_lightningbeam_thickness = {CF_CLIENT | CF_ARCHIVE, "r_lightningbeam_thickness", "8", "thickness of the lightning beam effect"};
6cvar_t r_lightningbeam_scroll = {CF_CLIENT | CF_ARCHIVE, "r_lightningbeam_scroll", "5", "speed of texture scrolling on the lightning beam effect"};
7cvar_t r_lightningbeam_repeatdistance = {CF_CLIENT | CF_ARCHIVE, "r_lightningbeam_repeatdistance", "128", "how far to stretch the texture along the lightning beam effect"};
8cvar_t r_lightningbeam_color_red = {CF_CLIENT | CF_ARCHIVE, "r_lightningbeam_color_red", "1", "color of the lightning beam effect"};
9cvar_t r_lightningbeam_color_green = {CF_CLIENT | CF_ARCHIVE, "r_lightningbeam_color_green", "1", "color of the lightning beam effect"};
10cvar_t r_lightningbeam_color_blue = {CF_CLIENT | CF_ARCHIVE, "r_lightningbeam_color_blue", "1", "color of the lightning beam effect"};
11cvar_t r_lightningbeam_qmbtexture = {CF_CLIENT | CF_ARCHIVE, "r_lightningbeam_qmbtexture", "0", "load the qmb textures/particles/lightning.pcx texture instead of generating one, can look better"};
12
15
16static void r_lightningbeams_start(void)
17{
20}
21
27
29{
30 // beam direction is horizontal in the lightning texture
31 int texwidth = 128;
32 int texheight = 64;
33 float r, g, b, intensity, thickness = texheight * 0.25f, border = thickness + 2.0f, ithickness = 1.0f / thickness, center, n;
34 int x, y;
35 unsigned char *data;
36 skinframe_t *skinframe;
37 float centersamples[17][2];
38
39 // make a repeating noise pattern for the beam path
40 for (x = 0; x < 16; x++)
41 {
42 centersamples[x][0] = lhrandom(border, texheight - border);
43 centersamples[x][1] = lhrandom(0.2f, 1.00f);
44 }
45 centersamples[16][0] = centersamples[0][0];
46 centersamples[16][1] = centersamples[0][1];
47
48 data = (unsigned char *)Mem_Alloc(tempmempool, texwidth * texheight * 4);
49
50 // iterate by columns and draw the entire column of pixels
51 for (x = 0; x < texwidth; x++)
52 {
53 r = x * 16.0f / texwidth;
54 y = (int)r;
55 g = r - y;
56 center = centersamples[y][0] * (1.0f - g) + centersamples[y+1][0] * g;
57 n = centersamples[y][1] * (1.0f - g) + centersamples[y + 1][1] * g;
58 for (y = 0; y < texheight; y++)
59 {
60 intensity = 1.0f - fabs((y - center) * ithickness);
61 if (intensity > 0)
62 {
63 intensity = pow(intensity * n, 2);
64 r = intensity * 1.000f * 255.0f;
65 g = intensity * 2.000f * 255.0f;
66 b = intensity * 4.000f * 255.0f;
67 data[(y * texwidth + x) * 4 + 2] = (unsigned char)(bound(0, r, 255));
68 data[(y * texwidth + x) * 4 + 1] = (unsigned char)(bound(0, g, 255));
69 data[(y * texwidth + x) * 4 + 0] = (unsigned char)(bound(0, b, 255));
70 }
71 else
72 intensity = 0.0f;
73 data[(y * texwidth + x) * 4 + 3] = (unsigned char)255;
74 }
75 }
76
77 skinframe = R_SkinFrame_LoadInternalBGRA("lightningbeam", TEXF_FORCELINEAR, data, texwidth, texheight, 0, 0, 0, false);
80}
81
87
95
107
108static void CL_Beam_AddQuad(model_t *mod, msurface_t *surf, const vec3_t start, const vec3_t end, const vec3_t offset, float t1, float t2)
109{
110 int e0, e1, e2, e3;
111 vec3_t n;
112 vec3_t dir;
113 float c[4];
114
116
117 VectorSubtract(end, start, dir);
120
121 e0 = Mod_Mesh_IndexForVertex(mod, surf, start[0] + offset[0], start[1] + offset[1], start[2] + offset[2], n[0], n[1], n[2], t1, 0, 0, 0, c[0], c[1], c[2], c[3]);
122 e1 = Mod_Mesh_IndexForVertex(mod, surf, start[0] - offset[0], start[1] - offset[1], start[2] - offset[2], n[0], n[1], n[2], t1, 1, 0, 0, c[0], c[1], c[2], c[3]);
123 e2 = Mod_Mesh_IndexForVertex(mod, surf, end[0] - offset[0], end[1] - offset[1], end[2] - offset[2], n[0], n[1], n[2], t2, 1, 0, 0, c[0], c[1], c[2], c[3]);
124 e3 = Mod_Mesh_IndexForVertex(mod, surf, end[0] + offset[0], end[1] + offset[1], end[2] + offset[2], n[0], n[1], n[2], t2, 0, 0, 0, c[0], c[1], c[2], c[3]);
125 Mod_Mesh_AddTriangle(mod, surf, e0, e1, e2);
126 Mod_Mesh_AddTriangle(mod, surf, e0, e2, e3);
127}
128
130{
131 vec3_t beamdir, right, up, offset, start, end;
133 vec_t beamrepeatscale = 1.0f / r_lightningbeam_repeatdistance.value;
134 float length, t1, t2;
135 model_t *mod;
136 msurface_t *surf;
137
142
143 // calculate beam direction (beamdir) vector and beam length
144 // get difference vector
145 CL_Beam_CalculatePositions(b, start, end);
146 VectorSubtract(end, start, beamdir);
147 // find length of difference vector
148 length = sqrt(DotProduct(beamdir, beamdir));
149 // calculate scale to make beamdir a unit vector (normalized)
150 t1 = 1.0f / length;
151 // scale beamdir so it is now normalized
152 VectorScale(beamdir, t1, beamdir);
153
154 // calculate up vector such that it points toward viewer, and rotates around the beamdir
155 // get direction from start of beam to viewer
157 // remove the portion of the vector that moves along the beam
158 // (this leaves only a vector pointing directly away from the beam)
159 t1 = -DotProduct(up, beamdir);
160 VectorMA(up, t1, beamdir, up);
161 // generate right vector from forward and up, the result is unnormalized
162 CrossProduct(beamdir, up, right);
163 // now normalize the right vector and up vector
166
167 // calculate T coordinate scrolling (start and end texcoord along the beam)
168 t1 = beamscroll;
169 t1 = t1 - (int)t1;
170 t2 = t1 + beamrepeatscale * length;
171
172 // the beam is 3 polygons in this configuration:
173 // * 2
174 // * *
175 // 1*****
176 // * *
177 // * 3
178 // they are showing different portions of the beam texture, creating an
179 // illusion of a beam that appears to curl around in 3D space
180 // (and realize that the whole polygon assembly orients itself to face
181 // the viewer)
182
183 mod = CL_Mesh_Scene();
185 // polygon 1
187 CL_Beam_AddQuad(mod, surf, start, end, offset, t1, t2);
188 // polygon 2
190 CL_Beam_AddQuad(mod, surf, start, end, offset, t1 + 0.33f, t2 + 0.33f);
191 // polygon 3
193 CL_Beam_AddQuad(mod, surf, start, end, offset, t1 + 0.66f, t2 + 0.66f);
194}
void CL_Beam_CalculatePositions(const beam_t *b, vec3_t start, vec3_t end)
Definition cl_main.c:1851
#define CL_Mesh_Scene()
Definition client.h:1371
#define CF_CLIENT
cvar/command that only the client can change/execute
Definition cmd.h:48
#define CF_ARCHIVE
cvar should have its set value saved to config.cfg and persist across sessions
Definition cmd.h:53
float mod(float dividend, float divisor)
void Cvar_SetValueQuick(cvar_t *var, float value)
Definition cvar.c:473
void Cvar_RegisterVariable(cvar_t *variable)
registers a cvar that already has the name, string, and optionally the archive elements set.
Definition cvar.c:599
#define n(x, y)
static int(ZEXPORT *qz_inflate)(z_stream *strm
skinframe_t * R_SkinFrame_LoadInternalBGRA(const char *name, int textureflags, const unsigned char *skindata, int width, int height, int comparewidth, int compareheight, int comparecrc, qbool sRGB)
Definition gl_rmain.c:2546
mempool_t * r_main_mempool
Definition gl_rmain.c:42
void R_SkinFrame_MarkUsed(skinframe_t *skinframe)
Definition gl_rmain.c:2176
r_refdef_t r_refdef
Definition gl_rmain.c:57
GLint GLenum GLsizei GLsizei GLint border
Definition glquake.h:647
GLenum GLuint GLenum GLsizei length
Definition glquake.h:657
GLint GLenum GLint GLint y
Definition glquake.h:651
GLint GLenum GLint x
Definition glquake.h:651
GLsizeiptr const GLvoid * data
Definition glquake.h:639
GLuint GLuint GLintptr offset
Definition glquake.h:632
#define VectorNormalize(v)
Definition mathlib.h:104
#define bound(min, num, max)
Definition mathlib.h:34
#define lhrandom(MIN, MAX)
LadyHavoc: this function never returns exactly MIN or exactly MAX, because of a QuakeC bug in id1 whe...
Definition mathlib.h:48
#define Vector4Set(vec, r, g, b, a)
Definition mathlib.h:86
#define VectorSubtract(a, b, out)
Definition mathlib.h:99
#define CrossProduct(a, b, out)
Definition mathlib.h:103
#define DotProduct(a, b)
Definition mathlib.h:98
#define VectorScale(in, scale, out)
Definition mathlib.h:111
#define VectorMAM(scale1, b1, scale2, b2, out)
Definition mathlib.h:116
#define VectorMA(a, scale, b, out)
Definition mathlib.h:114
#define VectorM(scale1, b1, out)
Definition mathlib.h:115
float pow(float a, float b)
float sqrt(float f)
float fabs(float f)
#define MATERIALFLAG_ADD
Definition model_brush.h:81
#define MATERIALFLAG_VERTEXCOLOR
#define MATERIALFLAG_BLENDED
#define MATERIALFLAG_ALPHAGEN_VERTEX
#define MATERIALFLAG_WALL
Definition model_brush.h:89
#define MATERIALFLAG_NOSHADOW
#define MATERIALFLAG_NOCULLFACE
qbool Mod_LoadTextureFromQ3Shader(mempool_t *mempool, const char *modelname, texture_t *texture, const char *name, qbool warnmissing, qbool fallback, int defaulttexflags, int defaultmaterialflags)
msurface_t * Mod_Mesh_AddSurface(model_t *mod, texture_t *tex, qbool batchwithprevioussurface)
int Mod_Mesh_IndexForVertex(model_t *mod, msurface_t *surf, float x, float y, float z, float nx, float ny, float nz, float s, float t, float u, float v, float r, float g, float b, float a)
void Mod_Mesh_AddTriangle(model_t *mod, msurface_t *surf, int e0, int e1, int e2)
void Mod_LoadCustomMaterial(mempool_t *mempool, texture_t *texture, const char *name, int supercontents, int materialflags, skinframe_t *skinframe)
#define NULL
Definition qtypes.h:12
float vec_t
Definition qtypes.h:68
vec_t vec3_t[3]
Definition qtypes.h:71
cvar_t r_lightningbeam_scroll
Definition r_lightning.c:6
cvar_t r_lightningbeam_repeatdistance
Definition r_lightning.c:7
static void CL_Beams_SetupBuiltinTexture(void)
Definition r_lightning.c:28
cvar_t r_lightningbeam_color_red
Definition r_lightning.c:8
static void r_lightningbeams_start(void)
Definition r_lightning.c:16
cvar_t r_lightningbeam_color_blue
Definition r_lightning.c:10
static void r_lightningbeams_shutdown(void)
Definition r_lightning.c:82
void R_LightningBeams_Init(void)
Definition r_lightning.c:96
static texture_t cl_beams_builtintexture
Definition r_lightning.c:14
cvar_t r_lightningbeam_color_green
Definition r_lightning.c:9
cvar_t r_lightningbeam_thickness
Definition r_lightning.c:5
static void CL_Beam_AddQuad(model_t *mod, msurface_t *surf, const vec3_t start, const vec3_t end, const vec3_t offset, float t1, float t2)
cvar_t r_lightningbeam_qmbtexture
Definition r_lightning.c:11
void CL_Beam_AddPolygons(const beam_t *b)
static texture_t cl_beams_externaltexture
Definition r_lightning.c:13
static void r_lightningbeams_newmap(void)
Definition r_lightning.c:88
static void CL_Beams_SetupExternalTexture(void)
Definition r_lightning.c:22
void R_RegisterModule(const char *name, void(*start)(void), void(*shutdown)(void), void(*newmap)(void), void(*devicelost)(void), void(*devicerestored)(void))
Definition r_modules.c:25
#define TEXF_ALPHA
Definition r_textures.h:9
#define TEXF_FORCELINEAR
Definition r_textures.h:19
dp_FragColor r
vec2 dir
dp_FragColor g
dp_FragColor b
float intensity
Definition snd_mix.c:314
Definition cvar.h:66
float value
Definition cvar.h:74
int integer
Definition cvar.h:73
describes the textures to use on a range of triangles in the model, and mins/maxs (AABB) for culling.
double time
(client gameworld) time for rendering time based effects
Definition render.h:352
r_refdef_view_t view
Definition render.h:406
r_refdef_scene_t scene
Definition render.h:418
vec3_t origin
Definition render.h:267
struct skinframe_s * currentskinframe
static vec3_t right
Definition sv_user.c:305
static vec3_t up
Definition sv_user.c:305
mempool_t * tempmempool
Definition zone.c:794
#define Mem_Free(mem)
Definition zone.h:96
#define Mem_Alloc(pool, size)
Definition zone.h:92