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