UFO: Alien Invasion
Loading...
Searching...
No Matches
r_particle.cpp
Go to the documentation of this file.
1
4
5/*
6Copyright (C) 2002-2025 UFO: Alien Invasion.
7
8This program is free software; you can redistribute it and/or
9modify it under the terms of the GNU General Public License
10as published by the Free Software Foundation; either version 2
11of the License, or (at your option) any later version.
12
13This program is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16
17See the GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along with this program; if not, write to the Free Software
21Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22
23*/
24
25#include "r_local.h"
26#include "r_particle.h"
27#include "r_draw.h"
28
31
33
34/*
35=============================================================
36PARTICLE DRAWING
37=============================================================
38*/
39
47static void R_GetSpriteVectors (const ptl_t* p, vec3_t right, vec3_t up)
48{
49 /* get transformation */
50 switch (p->style) {
51 case STYLE_FACING:
52 VectorScale(r_locals.right, p->size[0], right);
53 VectorScale(r_locals.up, p->size[1], up);
54 break;
55
56 case STYLE_ROTATED:
57 AngleVectors(p->angles, nullptr, right, up);
58 VectorScale(right, p->size[0], right);
59 VectorScale(up, p->size[1], up);
60 break;
61
62 case STYLE_BEAM:
63 case STYLE_AXIS:
64 AngleVectors(p->angles, right, nullptr, nullptr);
65 CrossProduct(right, r_locals.forward, up);
67 VectorScale(right, p->size[0], right);
68 VectorScale(up, p->size[1], up);
69 break;
70
71 default:
72 Com_Error(ERR_FATAL, "R_GetSpriteVectors: unknown style");
73 }
74}
75
80static inline void R_SpriteTexcoords (const ptl_t* p, float out[8])
81{
82 const float s = p->scrollS * refdef.time;
83 const float t = p->scrollT * refdef.time;
84
85 out[0] = 0.0 + s;
86 out[1] = 1.0 + t;
87
88 out[2] = 0.0 + s;
89 out[3] = 0.0 + t;
90
91 out[4] = 1.0 + s;
92 out[5] = 0.0 + t;
93
94 out[6] = 1.0 + s;
95 out[7] = 1.0 + t;
96}
97
101static void R_DrawSprite (const ptl_t* p)
102{
103 const ptl_t* q;
104 vec3_t up, right;
105 vec3_t nup, nright;
106 vec3_t pos;
107 float texcoords[8];
108
109 /* load texture set up coordinates */
110 assert(p->pic);
112
113 /* calculate main position and normalised up and right vectors */
114 q = p->parent ? p->parent : p;
115 R_GetSpriteVectors(q, right, up);
116
117 /* Calculate normalised */
118 VectorCopy(up, nup);
119 VectorCopy(right, nright);
121 VectorNormalizeFast(nright);
122
123 /* offset */
124 VectorCopy(q->s, pos);
125 VectorMA(pos, q->offset[0], nup, pos);
126 VectorMA(pos, q->offset[1], nright, pos);
127
128 if (p->parent) {
129 /* if this is a child then calculate our own up and right vectors and offsets */
130 R_GetSpriteVectors(p, right, up);
131
132 /* but offset by our parent's nup and nright */
133 VectorMA(pos, p->offset[0], nup, pos);
134 VectorMA(pos, p->offset[1], nright, pos);
135 }
136
137 /* center image */
138 VectorMA(pos, -0.5, up, pos);
139 VectorMA(pos, -0.5, right, pos);
140
141 R_SpriteTexcoords(p, texcoords);
142
143 R_Color(p->color);
144 {
145 /* draw it */
146 const vec3_t points[] = { { pos[0], pos[1], pos[2] }, { pos[0] + up[0], pos[1] + up[1], pos[2] + up[2] }, { pos[0]
147 + up[0] + right[0], pos[1] + up[1] + right[1], pos[2] + up[2] + right[2] }, { pos[0] + right[0], pos[1]
148 + right[1], pos[2] + right[2] } };
149
150 R_BindArray(GL_TEXTURE_COORD_ARRAY, GL_FLOAT, texcoords);
151 R_BindArray(GL_VERTEX_ARRAY, GL_FLOAT, points);
152 glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
153 R_BindDefaultArray(GL_VERTEX_ARRAY);
154 R_BindDefaultArray(GL_TEXTURE_COORD_ARRAY);
155
156 refdef.batchCount++;
157 }
158}
159
160
165{
166 modelInfo_t mi;
167
168 /* initialize model info */
169 OBJZERO(mi);
170 mi.color = p->color;
171 mi.origin = p->s;
172 mi.angles = p->angles;
173 assert(p->model);
174 mi.model = p->model->art.model;
175 mi.skin = p->skin;
176
177 /* draw it */
179}
180
186static void R_DrawPtlCircle (const ptl_t* p)
187{
188 const float radius = p->size[0];
189 const float thickness = p->size[1];
190
192
193 R_DrawCircle(radius, p->color, thickness, p->s);
194
196}
197
201static void R_DrawPtlLine (const ptl_t* p)
202{
203 const vec3_t points[] = { { p->s[0], p->s[1], p->s[2] }, { p->v[0], p->v[1], p->v[2] } };
204
206
207 glEnable(GL_LINE_SMOOTH);
208
209 R_Color(p->color);
210
211 /* draw line from s to v */
212 R_BindArray(GL_VERTEX_ARRAY, GL_FLOAT, points);
213 glDrawArrays(GL_LINE_STRIP, 0, 2);
214 R_BindDefaultArray(GL_VERTEX_ARRAY);
215
216 refdef.batchCount++;
217
218 R_Color(nullptr);
219
220 glDisable(GL_LINE_SMOOTH);
221
223}
224
225
226/*
227=============================================================
228GENERIC PARTICLE FUNCTIONS
229=============================================================
230*/
231
235static void R_SetBlendMode (int mode)
236{
237 switch (mode) {
238 case BLEND_REPLACE:
239 R_TexEnv(GL_REPLACE);
240 break;
241 case BLEND_ONE:
242 R_BlendFunc(GL_SRC_ALPHA, GL_ONE);
243 break;
244 case BLEND_BLEND:
245 R_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
246 break;
247 case BLEND_ADD:
248 R_BlendFunc(GL_ONE, GL_ONE);
249 break;
250 case BLEND_FILTER:
251 R_BlendFunc(GL_ZERO, GL_SRC_COLOR);
252 break;
253 case BLEND_INVFILTER:
254 R_BlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR);
255 break;
256 default:
257 Com_Error(ERR_DROP, "unknown blend mode");
258 break;
259 }
260}
261
267{
268 ptl_t* p;
269 int i;
270
271 if (!r_particles->integer)
272 return;
273
274 for (i = 0, p = r_particleArray; i < r_numParticles; i++, p++)
275 if (p->inuse && !p->invis) {
276 /* test for visibility */
277 if (p->levelFlags && !((1 << refdef.worldlevel) & p->levelFlags))
278 continue;
279
280 if (p->program != nullptr)
282
283 /* set blend mode and draw gfx */
285 switch (p->style) {
286 case STYLE_LINE:
287 R_DrawPtlLine(p);
288 break;
289 case STYLE_CIRCLE:
291 break;
292 default:
293 break;
294 }
295 if (p->pic)
296 R_DrawSprite(p);
297 if (p->model)
299 R_TexEnv(GL_MODULATE);
300
301 R_UseProgram(nullptr);
302 }
303
304 R_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
305
306 R_Color(nullptr);
307}
#define MAX_PTLS
Definition cl_renderer.h:44
rendererData_t refdef
Definition r_main.cpp:45
void R_Color(const vec4_t rgba)
Change the color to given value.
Definition r_state.cpp:1011
void Com_Error(int code, const char *fmt,...)
Definition common.cpp:459
#define ERR_DROP
Definition common.h:211
#define ERR_FATAL
Definition common.h:210
const char int mode
Definition ioapi.h:41
void VectorMA(const vec3_t veca, const float scale, const vec3_t vecb, vec3_t outVector)
Sets vector_out (vc) to vevtor1 (va) + scale * vector2 (vb).
Definition mathlib.cpp:261
void AngleVectors(const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up)
Create the rotation matrix in order to rotate something.
Definition mathlib.cpp:631
void CrossProduct(const vec3_t v1, const vec3_t v2, vec3_t cross)
binary operation on vectors in a three-dimensional space
Definition mathlib.cpp:820
void VectorNormalizeFast(vec3_t v)
fast vector normalize routine that does not check to make sure that length != 0, nor does it return l...
Definition mathlib.cpp:762
void R_DrawCircle(float radius, const vec4_t color, float thickness, const vec3_t shift)
Definition r_draw.cpp:422
QGL_EXTERN GLint i
Definition r_gl.h:113
local graphics definitions
cvar_t * r_particles
void R_DrawModelParticle(modelInfo_t *mi)
Renders a particle model for the battlescape.
Definition r_mesh.cpp:397
rlocals_t r_locals
Definition r_main.cpp:49
static void R_GetSpriteVectors(const ptl_t *p, vec3_t right, vec3_t up)
Get Sprite Vectors.
void R_DrawParticles(void)
static void R_DrawSprite(const ptl_t *p)
static void R_DrawPtlLine(const ptl_t *p)
static void R_DrawPtlCircle(const ptl_t *p)
Draws a circle out of lines.
static void R_SpriteTexcoords(const ptl_t *p, float out[8])
Fills float array with texture coordinates.
int r_numParticles
ptl_t r_particleArray[MAX_PTLS]
static void R_SetBlendMode(int mode)
static void R_DrawParticleModel(ptl_t *p)
Particle system header file.
void R_UseProgram(r_program_t *prog)
Definition r_program.cpp:43
void R_EnableTexture(gltexunit_t *texunit, bool enable)
Definition r_state.cpp:303
void R_BindDefaultArray(GLenum target)
Binds the appropriate shared vertex array to the specified target.
Definition r_state.cpp:182
void R_BlendFunc(GLenum src, GLenum dest)
Definition r_state.cpp:232
void R_TexEnv(GLenum mode)
Definition r_state.cpp:956
void R_BindArray(GLenum target, GLenum type, const void *array)
Definition r_state.cpp:148
#define texunit_diffuse
Definition r_state.h:68
#define R_BindTexture(tn)
Definition r_state.h:184
@ STYLE_ROTATED
Definition scripts.h:126
@ STYLE_FACING
Definition scripts.h:125
@ STYLE_AXIS
Definition scripts.h:129
@ STYLE_CIRCLE
Definition scripts.h:130
@ STYLE_BEAM
Definition scripts.h:127
@ STYLE_LINE
Definition scripts.h:128
@ BLEND_BLEND
Definition scripts.h:116
@ BLEND_INVFILTER
Definition scripts.h:119
@ BLEND_FILTER
Definition scripts.h:118
@ BLEND_REPLACE
Definition scripts.h:114
@ BLEND_ONE
Definition scripts.h:115
@ BLEND_ADD
Definition scripts.h:117
#define OBJZERO(obj)
Definition shared.h:178
This is a cvar definition. Cvars can be user modified and used in our menus e.g.
Definition cvar.h:71
GLuint texnum
Definition r_image.h:66
float * origin
Definition cl_renderer.h:61
float * angles
Definition cl_renderer.h:62
float * color
Definition cl_renderer.h:71
model_t * model
Definition cl_renderer.h:58
vec3_t offset
vec4_t color
struct ptl_s * parent
ptlArt_t * model
vec2_t size
ptlArt_t * pic
vec3_t angles
bool invis
float scrollT
vec3_t s
blend_t blend
vec3_t v
int skin
int levelFlags
bool inuse
float scrollS
style_t style
r_program_t * program
const image_t * image
union ptlArt_t::@003311107351012232215144266245032026252364056310 art
model_t * model
vec_t vec3_t[3]
Definition ufotypes.h:39
#define VectorCopy(src, dest)
Definition vector.h:51
#define VectorScale(in, scale, out)
Definition vector.h:79