1 /*
2 Copyright (C) 1997-2001 Id Software, Inc.
3
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.
8
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.
12
13 See the GNU General Public License for more details.
14
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.
18 */
19
20 //
21 // rf_sprite.c
22 // sprite model rendering
23 //
24
25 #include "rf_local.h"
26
27 /*
28 =============================================================================
29
30 SP2 MODELS
31
32 =============================================================================
33 */
34
35 static bvec4_t r_spriteColors[4];
36 static vec2_t r_spriteCoords[4];
37 static vec3_t r_spriteVerts[4];
38 static vec3_t r_spriteNormals[4];
39
40 /*
41 =================
42 R_AddSP2ModelToList
43 =================
44 */
R_AddSP2ModelToList(refEntity_t * ent)45 void R_AddSP2ModelToList (refEntity_t *ent)
46 {
47 mSpriteModel_t *spriteModel;
48 mSpriteFrame_t *spriteFrame;
49 shader_t *shader;
50
51 spriteModel = ent->model->spriteModel;
52 spriteFrame = &spriteModel->frames[ent->frame % spriteModel->numFrames];
53 shader = spriteFrame->skin;
54
55 if (!shader) {
56 Com_DevPrintf (PRNT_WARNING, "R_AddSP2ModelToList: '%s' has a NULL shader\n", ent->model->name);
57 return;
58 }
59
60 R_AddMeshToList (shader, ent->shaderTime, ent, R_FogForSphere (ent->origin, spriteFrame->radius), MBT_SP2, spriteModel);
61 }
62
63
64 /*
65 =================
66 R_DrawSP2Model
67 =================
68 */
R_DrawSP2Model(meshBuffer_t * mb)69 void R_DrawSP2Model (meshBuffer_t *mb)
70 {
71 mSpriteModel_t *spriteModel;
72 mSpriteFrame_t *spriteFrame;
73 mesh_t mesh;
74 meshFeatures_t features;
75
76 spriteModel = (mSpriteModel_t *)mb->mesh;
77 spriteFrame = &spriteModel->frames[mb->entity->frame % spriteModel->numFrames];
78
79 //
80 // Culling
81 //
82 if ((mb->entity->origin[0] - ri.def.viewOrigin[0]) * ri.def.viewAxis[0][0]
83 + (mb->entity->origin[1] - ri.def.viewOrigin[1]) * ri.def.viewAxis[0][1]
84 + (mb->entity->origin[2] - ri.def.viewOrigin[2]) * ri.def.viewAxis[0][2] < 0)
85 return;
86
87 //
88 // create verts/normals/coords
89 //
90 Vec4Copy (mb->entity->color, r_spriteColors[0]);
91 r_spriteVerts[0][0] = mb->entity->origin[0] + (ri.def.viewAxis[2][0] * -spriteFrame->originY) + (ri.def.rightVec[0] * -spriteFrame->originX);
92 r_spriteVerts[0][1] = mb->entity->origin[1] + (ri.def.viewAxis[2][1] * -spriteFrame->originY) + (ri.def.rightVec[1] * -spriteFrame->originX);
93 r_spriteVerts[0][2] = mb->entity->origin[2] + (ri.def.viewAxis[2][2] * -spriteFrame->originY) + (ri.def.rightVec[2] * -spriteFrame->originX);
94 Vec2Set (r_spriteCoords[0], 0, 1);
95 Vec3Set (r_spriteNormals[0], 0, 1, 0);
96
97 Vec4Copy (mb->entity->color, r_spriteColors[1]);
98 r_spriteVerts[1][0] = mb->entity->origin[0] + (ri.def.viewAxis[2][0] * (spriteFrame->height-spriteFrame->originY)) + (ri.def.rightVec[0] * -spriteFrame->originX);
99 r_spriteVerts[1][1] = mb->entity->origin[1] + (ri.def.viewAxis[2][1] * (spriteFrame->height-spriteFrame->originY)) + (ri.def.rightVec[1] * -spriteFrame->originX);
100 r_spriteVerts[1][2] = mb->entity->origin[2] + (ri.def.viewAxis[2][2] * (spriteFrame->height-spriteFrame->originY)) + (ri.def.rightVec[2] * -spriteFrame->originX);
101 Vec2Set (r_spriteCoords[1], 0, 0);
102 Vec3Set (r_spriteNormals[1], 0, 1, 0);
103
104 Vec4Copy (mb->entity->color, r_spriteColors[2]);
105 r_spriteVerts[2][0] = mb->entity->origin[0] + (ri.def.viewAxis[2][0] * (spriteFrame->height-spriteFrame->originY)) + (ri.def.rightVec[0] * (spriteFrame->width-spriteFrame->originX));
106 r_spriteVerts[2][1] = mb->entity->origin[1] + (ri.def.viewAxis[2][1] * (spriteFrame->height-spriteFrame->originY)) + (ri.def.rightVec[1] * (spriteFrame->width-spriteFrame->originX));
107 r_spriteVerts[2][2] = mb->entity->origin[2] + (ri.def.viewAxis[2][2] * (spriteFrame->height-spriteFrame->originY)) + (ri.def.rightVec[2] * (spriteFrame->width-spriteFrame->originX));
108 Vec2Set (r_spriteCoords[2], 1, 0);
109 Vec3Set (r_spriteNormals[2], 0, 1, 0);
110
111 Vec4Copy (mb->entity->color, r_spriteColors[3]);
112 r_spriteVerts[3][0] = mb->entity->origin[0] + (ri.def.viewAxis[2][0] * -spriteFrame->originY) + (ri.def.rightVec[0] * (spriteFrame->width-spriteFrame->originX));
113 r_spriteVerts[3][1] = mb->entity->origin[1] + (ri.def.viewAxis[2][1] * -spriteFrame->originY) + (ri.def.rightVec[1] * (spriteFrame->width-spriteFrame->originX));
114 r_spriteVerts[3][2] = mb->entity->origin[2] + (ri.def.viewAxis[2][2] * -spriteFrame->originY) + (ri.def.rightVec[2] * (spriteFrame->width-spriteFrame->originX));
115 Vec2Set (r_spriteCoords[3], 1, 1);
116 Vec3Set (r_spriteNormals[3], 0, 1, 0);
117
118 //
119 // Create mesh item
120 //
121 mesh.numIndexes = 0;
122 mesh.numVerts = 4;
123
124 mesh.colorArray = r_spriteColors;
125 mesh.coordArray = r_spriteCoords;
126 mesh.lmCoordArray = NULL;
127 mesh.indexArray = NULL;
128 mesh.normalsArray = r_spriteNormals;
129 mesh.sVectorsArray = NULL;
130 mesh.tVectorsArray = NULL;
131 mesh.trNeighborsArray = NULL;
132 mesh.trNormalsArray = NULL;
133 mesh.vertexArray = r_spriteVerts;
134
135 //
136 // Push
137 //
138 features = MF_TRIFAN|MF_NOCULL|MF_NONBATCHED|mb->shader->features;
139 if (gl_shownormals->intVal)
140 features |= MF_NORMALS;
141
142 RB_PushMesh (&mesh, features);
143 RB_RenderMeshBuffer (mb, qFalse);
144 }
145
146 /*
147 =============================================================================
148
149 Q3BSP FLARE
150
151 =============================================================================
152 */
153
154 static vec3_t r_flareVerts[4];
155 static vec2_t r_flareCoords[4] = { {0, 1}, {0, 0}, {1,0}, {1,1} };
156 static bvec4_t r_flareColors[4];
157 static mesh_t r_flareMesh;
158
159 /*
160 =================
161 R_FlareOverflow
162 =================
163 */
R_FlareOverflow(void)164 qBool R_FlareOverflow (void)
165 {
166 // Only need to check the current one, because the next one will have the same vertex/index count anyways.
167 return RB_BackendOverflow (4, 6);
168 }
169
170
171 /*
172 =================
173 R_PushFlare
174 =================
175 */
R_PushFlare(meshBuffer_t * mb)176 void R_PushFlare (meshBuffer_t *mb)
177 {
178 vec4_t color;
179 vec3_t origin, point, v;
180 float radius = r_flareSize->floatVal, flarescale, depth;
181 float up = radius, down = -radius, left = -radius, right = radius;
182 mBspSurface_t *surf = (mBspSurface_t *)mb->mesh;
183 meshFeatures_t features;
184
185 if (mb->entity && mb->entity->model && !mb->entity->model->isBspModel) {
186 Matrix3_TransformVector (mb->entity->axis, surf->q3_origin, origin);
187 Vec3Add(origin, mb->entity->origin, origin);
188 }
189 else {
190 Vec3Copy (surf->q3_origin, origin);
191 }
192 R_TransformToScreen_Vec3 (origin, v);
193
194 if (v[0] < ri.def.x || v[0] > ri.def.x + ri.def.width)
195 return;
196 if (v[1] < ri.def.y || v[1] > ri.def.y + ri.def.height)
197 return;
198
199 qglReadPixels ((int)(v[0]), (int)(v[1]), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth);
200 if (depth + 1e-4 < v[2])
201 return; // Occluded
202
203 Vec3Copy (origin, origin);
204
205 Vec3MA (origin, down, ri.def.viewAxis[2], point);
206 Vec3MA (point, -left, ri.def.rightVec, r_flareVerts[0]);
207 Vec3MA (point, -right, ri.def.rightVec, r_flareVerts[3]);
208
209 Vec3MA (origin, up, ri.def.viewAxis[2], point);
210 Vec3MA (point, -left, ri.def.rightVec, r_flareVerts[1]);
211 Vec3MA (point, -right, ri.def.rightVec, r_flareVerts[2]);
212
213 flarescale = 1.0f / r_flareFade->floatVal;
214 Vec4Set (color,
215 COLOR_R (surf->dLightBits) * flarescale,
216 COLOR_G (surf->dLightBits) * flarescale,
217 COLOR_B (surf->dLightBits) * flarescale, 255);
218
219 Vec4Copy (color, r_flareColors[0]);
220 Vec4Copy (color, r_flareColors[1]);
221 Vec4Copy (color, r_flareColors[2]);
222 Vec4Copy (color, r_flareColors[3]);
223
224 r_flareMesh.numIndexes = 6;
225 r_flareMesh.numVerts = 4;
226 r_flareMesh.vertexArray = r_flareVerts;
227 r_flareMesh.coordArray = r_flareCoords;
228 r_flareMesh.colorArray = r_flareColors;
229
230 features = MF_NOCULL|MF_TRIFAN|mb->shader->features;
231 if (r_debugBatching->intVal == 2)
232 features |= MF_NONBATCHED;
233
234 RB_PushMesh (&r_flareMesh, features);
235 }
236