1 //**************************************************************************
2 //**
3 //**	##   ##    ##    ##   ##   ####     ####   ###     ###
4 //**	##   ##  ##  ##  ##   ##  ##  ##   ##  ##  ####   ####
5 //**	 ## ##  ##    ##  ## ##  ##    ## ##    ## ## ## ## ##
6 //**	 ## ##  ########  ## ##  ##    ## ##    ## ##  ###  ##
7 //**	  ###   ##    ##   ###    ##  ##   ##  ##  ##       ##
8 //**	   #    ##    ##    #      ####     ####   ##       ##
9 //**
10 //**	$Id: gl_model.cpp 4286 2010-05-30 22:16:52Z dj_jl $
11 //**
12 //**	Copyright (C) 1999-2006 Jānis Legzdiņš
13 //**
14 //**	This program is free software; you can redistribute it and/or
15 //**  modify it under the terms of the GNU General Public License
16 //**  as published by the Free Software Foundation; either version 2
17 //**  of the License, or (at your option) any later version.
18 //**
19 //**	This program is distributed in the hope that it will be useful,
20 //**  but WITHOUT ANY WARRANTY; without even the implied warranty of
21 //**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22 //**  GNU General Public License for more details.
23 //**
24 //**************************************************************************
25 
26 // HEADER FILES ------------------------------------------------------------
27 
28 #include "gl_local.h"
29 
30 // MACROS ------------------------------------------------------------------
31 
32 // TYPES -------------------------------------------------------------------
33 
34 // EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
35 
36 // PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
37 
38 // PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
39 
40 // EXTERNAL DATA DECLARATIONS ----------------------------------------------
41 
42 // PUBLIC DATA DEFINITIONS -------------------------------------------------
43 
44 // PRIVATE DATA DEFINITIONS ------------------------------------------------
45 
46 // CODE --------------------------------------------------------------------
47 
48 //==========================================================================
49 //
50 //	AliasSetUpTransform
51 //
52 //==========================================================================
53 
AliasSetUpTransform(const TVec & modelorg,const TAVec & angles,const TVec & Offset,const TVec & Scale,VMatrix4 & RotationMatrix)54 static void AliasSetUpTransform(const TVec& modelorg, const TAVec& angles,
55 	const TVec& Offset, const TVec& Scale, VMatrix4& RotationMatrix)
56 {
57 	VMatrix4 t3matrix = VMatrix4::Identity;
58 	t3matrix[0][0] = Scale.x;
59 	t3matrix[1][1] = Scale.y;
60 	t3matrix[2][2] = Scale.z;
61 
62 	t3matrix[0][3] = Scale.x * Offset.x;
63 	t3matrix[1][3] = Scale.y * Offset.y;
64 	t3matrix[2][3] = Scale.z * Offset.z;
65 
66 	TVec alias_forward, alias_right, alias_up;
67 	AngleVectors(angles, alias_forward, alias_right, alias_up);
68 
69 	VMatrix4 t2matrix = VMatrix4::Identity;
70 	for (int i = 0; i < 3; i++)
71 	{
72 		t2matrix[i][0] = alias_forward[i];
73 		t2matrix[i][1] = -alias_right[i];
74 		t2matrix[i][2] = alias_up[i];
75 	}
76 
77 	t2matrix[0][3] = modelorg[0];
78 	t2matrix[1][3] = modelorg[1];
79 	t2matrix[2][3] = modelorg[2];
80 
81 	RotationMatrix = t2matrix * t3matrix;
82 }
83 
84 //==========================================================================
85 //
86 //	AliasSetUpNormalTransform
87 //
88 //==========================================================================
89 
AliasSetUpNormalTransform(const TAVec & angles,const TVec & Scale,VMatrix4 & RotationMatrix)90 static void AliasSetUpNormalTransform(const TAVec& angles, const TVec& Scale,
91 	VMatrix4& RotationMatrix)
92 {
93 	TVec alias_forward, alias_right, alias_up;
94 	AngleVectors(angles, alias_forward, alias_right, alias_up);
95 
96 	VMatrix4 t3matrix = VMatrix4::Identity;
97 	t3matrix[0][0] = Scale.x;
98 	t3matrix[1][1] = Scale.y;
99 	t3matrix[2][2] = Scale.z;
100 
101 	VMatrix4 t2matrix = VMatrix4::Identity;
102 	for (int i = 0; i < 3; i++)
103 	{
104 		t2matrix[i][0] = alias_forward[i];
105 		t2matrix[i][1] = -alias_right[i];
106 		t2matrix[i][2] = alias_up[i];
107 	}
108 
109 	RotationMatrix = t2matrix * t3matrix;
110 
111 	if (fabs(Scale.x) != fabs(Scale.y) || fabs(Scale.x) != fabs(Scale.z))
112 	{
113 		//	Non-uniform scale, do full inverse transpose.
114 		RotationMatrix = RotationMatrix.Inverse().Transpose();
115 	}
116 }
117 
118 //==========================================================================
119 //
120 //	VOpenGLDrawer::UploadModel
121 //
122 //==========================================================================
123 
UploadModel(VMeshModel * Mdl)124 void VOpenGLDrawer::UploadModel(VMeshModel* Mdl)
125 {
126 	guard(VOpenGLDrawer::UploadModel);
127 	if (Mdl->Uploaded)
128 	{
129 		return;
130 	}
131 
132 	//	Create buffer.
133 	p_glGenBuffersARB(1, &Mdl->VertsBuffer);
134 	p_glBindBufferARB(GL_ARRAY_BUFFER_ARB, Mdl->VertsBuffer);
135 	int Size = sizeof(VMeshSTVert) * Mdl->STVerts.Num() +
136 		sizeof(TVec) * Mdl->STVerts.Num() * 2 * Mdl->Frames.Num();
137 	p_glBufferDataARB(GL_ARRAY_BUFFER_ARB, Size, NULL, GL_STATIC_DRAW_ARB);
138 
139 	//	Upload data
140 	p_glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(VMeshSTVert) * Mdl->STVerts.Num(),
141 		&Mdl->STVerts[0]);
142 	p_glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, sizeof(VMeshSTVert) * Mdl->STVerts.Num(),
143 		sizeof(TVec) * Mdl->AllVerts.Num(), &Mdl->AllVerts[0]);
144 	p_glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, sizeof(VMeshSTVert) * Mdl->STVerts.Num() +
145 		sizeof(TVec) * Mdl->AllVerts.Num(), sizeof(TVec) * Mdl->AllNormals.Num(),
146 		&Mdl->AllNormals[0]);
147 
148 	//	Pre-calculate offsets.
149 	for (int i = 0; i < Mdl->Frames.Num(); i++)
150 	{
151 		Mdl->Frames[i].VertsOffset = sizeof(VMeshSTVert) * Mdl->STVerts.Num() +
152 			i * sizeof(TVec) * Mdl->STVerts.Num();
153 		Mdl->Frames[i].NormalsOffset = sizeof(VMeshSTVert) * Mdl->STVerts.Num() +
154 			sizeof(TVec) * Mdl->AllVerts.Num() +
155 			i * sizeof(TVec) * Mdl->STVerts.Num();
156 	}
157 
158 	//	Indexes
159 	p_glGenBuffersARB(1, &Mdl->IndexBuffer);
160 	p_glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, Mdl->IndexBuffer);
161 	p_glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 6 * Mdl->Tris.Num(),
162 		&Mdl->Tris[0], GL_STATIC_DRAW_ARB);
163 
164 	p_glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
165 	p_glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
166 	Mdl->Uploaded = true;
167 	UploadedModels.Append(Mdl);
168 	unguard;
169 }
170 
171 //==========================================================================
172 //
173 //	VOpenGLDrawer::UnloadModels
174 //
175 //==========================================================================
176 
UnloadModels()177 void VOpenGLDrawer::UnloadModels()
178 {
179 	guard(VOpenGLDrawer::UnloadModels);
180 	for (int i = 0; i < UploadedModels.Num(); i++)
181 	{
182 		p_glDeleteBuffersARB(1, &UploadedModels[i]->VertsBuffer);
183 		p_glDeleteBuffersARB(1, &UploadedModels[i]->IndexBuffer);
184 		UploadedModels[i]->Uploaded = false;
185 	}
186 	UploadedModels.Clear();
187 	unguard;
188 }
189 
190 //==========================================================================
191 //
192 //	VOpenGLDrawer::DrawAliasModel
193 //
194 //==========================================================================
195 
DrawAliasModel(const TVec & origin,const TAVec & angles,const TVec & Offset,const TVec & Scale,VMeshModel * Mdl,int frame,int nextframe,VTexture * Skin,VTextureTranslation * Trans,int CMap,vuint32 light,vuint32 Fade,float Alpha,bool Additive,bool is_view_model,float Inter,bool Interpolate)196 void VOpenGLDrawer::DrawAliasModel(const TVec &origin, const TAVec &angles,
197 	const TVec& Offset, const TVec& Scale, VMeshModel* Mdl, int frame, int nextframe,
198 	VTexture* Skin, VTextureTranslation* Trans, int CMap, vuint32 light,
199 	vuint32 Fade, float Alpha, bool Additive, bool is_view_model, float Inter,
200 	bool Interpolate)
201 {
202 	guard(VOpenGLDrawer::DrawAliasModel);
203 	if (is_view_model)
204 	{
205 		// hack the depth range to prevent view model from poking into walls
206 		glDepthRange(0.0, 0.3);
207 	}
208 
209 	//
210 	// get lighting information
211 	//
212 	float shadelightr = ((light >> 16) & 0xff) / 510.0;
213 	float shadelightg = ((light >> 8) & 0xff) / 510.0;
214 	float shadelightb = (light & 0xff) / 510.0;
215 	float* shadedots = r_avertexnormal_dots[((int)(angles.yaw * (SHADEDOT_QUANT / 360.0))) & (SHADEDOT_QUANT - 1)];
216 
217 	//
218 	// draw all the triangles
219 	//
220 	glPushMatrix();
221 	glTranslatef(origin.x, origin.y, origin.z);
222 
223 	glRotatef(angles.yaw,  0, 0, 1);
224 	glRotatef(angles.pitch,  0, 1, 0);
225 	glRotatef(angles.roll,  1, 0, 0);
226 
227 	glScalef(Scale.x, Scale.y, Scale.z);
228 	glTranslatef(Offset.x, Offset.y, Offset.z);
229 
230 	mmdl_t* pmdl = Mdl->Data;
231 	mframe_t* framedesc = (mframe_t*)((byte *)pmdl + pmdl->ofsframes + frame * pmdl->framesize);
232 	mframe_t* nextframedesc = (mframe_t*)((byte *)pmdl + pmdl->ofsframes + nextframe * pmdl->framesize);
233 
234 	if (!HaveShaders || !HaveVertexBufferObject)
235 	{
236 		// Interpolate Scales
237 		TVec scale_origin;
238 		if (Interpolate)
239 		{
240 			scale_origin[0] = ((1 - Inter) * framedesc->scale_origin[0] + Inter * nextframedesc->scale_origin[0]);
241 			scale_origin[1] = ((1 - Inter) * framedesc->scale_origin[1] + Inter * nextframedesc->scale_origin[1]);
242 			scale_origin[2] = ((1 - Inter) * framedesc->scale_origin[2] + Inter * nextframedesc->scale_origin[2]);
243 		}
244 		else
245 		{
246 			scale_origin[0] = framedesc->scale_origin[0];
247 			scale_origin[1] = framedesc->scale_origin[1];
248 			scale_origin[2] = framedesc->scale_origin[2];
249 		}
250 		glTranslatef(scale_origin[0], scale_origin[1], scale_origin[2]);
251 
252 		TVec scale;
253 		if (Interpolate)
254 		{
255 			scale[0] = framedesc->scale[0] + Inter * (nextframedesc->scale[0] - framedesc->scale[0]) * Scale.x;
256 			scale[1] = framedesc->scale[1] + Inter * (nextframedesc->scale[1] - framedesc->scale[1]) * Scale.y;
257 			scale[2] = framedesc->scale[2] + Inter * (nextframedesc->scale[2] - framedesc->scale[2]) * Scale.z;
258 		}
259 		else
260 		{
261 			scale[0] = framedesc->scale[0];
262 			scale[1] = framedesc->scale[1];
263 			scale[2] = framedesc->scale[2];
264 		}
265 		glScalef(scale[0], scale[1], scale[2]);
266 	}
267 
268 	SetPic(Skin, Trans, CMap);
269 
270 	if (HaveShaders)
271 	{
272 		p_glUseProgramObjectARB(SurfModelProgram);
273 		p_glUniform1iARB(SurfModelTextureLoc, 0);
274 		p_glUniform1iARB(SurfModelFogTypeLoc, r_fog & 3);
275 
276 		if (Fade)
277 		{
278 			p_glUniform1iARB(SurfModelFogEnabledLoc, GL_TRUE);
279 			p_glUniform4fARB(SurfModelFogColourLoc,
280 				((Fade >> 16) & 255) / 255.0,
281 				((Fade >> 8) & 255) / 255.0,
282 				(Fade & 255) / 255.0, 1.0);
283 			p_glUniform1fARB(SurfModelFogDensityLoc, Fade == FADE_LIGHT ? 0.3 : r_fog_density);
284 			p_glUniform1fARB(SurfModelFogStartLoc, Fade == FADE_LIGHT ? 1.0 : r_fog_start);
285 			p_glUniform1fARB(SurfModelFogEndLoc, Fade == FADE_LIGHT ? 1024.0 * r_fade_factor : r_fog_end);
286 		}
287 		else
288 		{
289 			p_glUniform1iARB(SurfModelFogEnabledLoc, GL_FALSE);
290 		}
291 		p_glUniform1fARB(SurfModelInterLoc, Inter);
292 	}
293 	else
294 	{
295 		if (!model_lighting)
296 		{
297 			SetColour((light & 0x00ffffff) | (int(255 * Alpha) << 24));
298 		}
299 		SetFade(Fade);
300 		glEnable(GL_ALPHA_TEST);
301 		glShadeModel(GL_SMOOTH);
302 		glAlphaFunc(GL_GREATER, 0.0);
303 	}
304 	glEnable(GL_BLEND);
305 	if (Additive)
306 	{
307 		glBlendFunc(GL_SRC_ALPHA, GL_ONE);
308 	}
309 
310 	if (HaveShaders && HaveVertexBufferObject)
311 	{
312 		UploadModel(Mdl);
313 		VMeshFrame* FrameDesc = &Mdl->Frames[frame];
314 		VMeshFrame* NextFrameDesc = &Mdl->Frames[nextframe];
315 
316 		p_glBindBufferARB(GL_ARRAY_BUFFER_ARB, Mdl->VertsBuffer);
317 		p_glVertexAttribPointerARB(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)FrameDesc->VertsOffset);
318 		p_glEnableVertexAttribArrayARB(0);
319 		p_glVertexAttribPointerARB(SurfModelVert2Loc, 3, GL_FLOAT, GL_FALSE, 0,
320 			(void*)NextFrameDesc->VertsOffset);
321 		p_glEnableVertexAttribArrayARB(SurfModelVert2Loc);
322 		p_glVertexAttribPointerARB(SurfModelTexCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, 0);
323 		p_glEnableVertexAttribArrayARB(SurfModelTexCoordLoc);
324 		p_glVertexAttrib4fARB(SurfModelLightValLoc,
325 			((light >> 16) & 255) / 255.0,
326 			((light >> 8) & 255) / 255.0,
327 			(light & 255) / 255.0, Alpha);
328 
329 		p_glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, Mdl->IndexBuffer);
330 		p_glDrawRangeElementsEXT(GL_TRIANGLES, 0, Mdl->STVerts.Num() - 1,
331 			Mdl->Tris.Num() * 3, GL_UNSIGNED_SHORT, 0);
332 		p_glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
333 
334 		p_glDisableVertexAttribArrayARB(0);
335 		p_glDisableVertexAttribArrayARB(SurfModelVert2Loc);
336 		p_glDisableVertexAttribArrayARB(SurfModelTexCoordLoc);
337 		p_glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
338 	}
339 	else
340 	{
341 		trivertx_t* verts = (trivertx_t *)(framedesc + 1);
342 		trivertx_t* verts2 = (trivertx_t *)(nextframedesc + 1);
343 		int* order = (int *)((byte *)pmdl + pmdl->ofscmds);
344 
345 		while (*order)
346 		{
347 			// get the vertex count and primitive type
348 			int count = *order++;
349 			if (count < 0)
350 			{
351 				count = -count;
352 				glBegin(GL_TRIANGLE_FAN);
353 			}
354 			else
355 			{
356 				glBegin(GL_TRIANGLE_STRIP);
357 			}
358 
359 			do
360 			{
361 				if (HaveShaders)
362 				{
363 					// texture coordinates come from the draw list
364 					p_glVertexAttrib2fARB(SurfModelTexCoordLoc, ((float *)order)[0], ((float *)order)[1]);
365 					order += 2;
366 
367 					// normals and vertexes come from the frame list
368 					int index = *order++;
369 					if (model_lighting)
370 					{
371 						float l = shadedots[verts[index].lightnormalindex];
372 						p_glVertexAttrib4fARB(SurfModelLightValLoc,
373 							l * shadelightr, l * shadelightg, l * shadelightb, Alpha);
374 					}
375 					else
376 					{
377 						p_glVertexAttrib4fARB(SurfModelLightValLoc,
378 							((light >> 16) & 255) / 255.0,
379 							((light >> 8) & 255) / 255.0,
380 							(light & 255) / 255.0, Alpha);
381 					}
382 					p_glVertexAttrib3fARB(SurfModelVert2Loc,
383 						verts2[index].v[0], verts2[index].v[1], verts2[index].v[2]);
384 					glVertex3f(verts[index].v[0], verts[index].v[1], verts[index].v[2]);
385 				}
386 				else
387 				{
388 					// texture coordinates come from the draw list
389 					glTexCoord2f(((float *)order)[0], ((float *)order)[1]);
390 					order += 2;
391 
392 					// normals and vertexes come from the frame list
393 					int index = *order++;
394 					if (model_lighting)
395 					{
396 						float l = shadedots[verts[index].lightnormalindex];
397 						glColor4f(l * shadelightr, l * shadelightg, l * shadelightb, Alpha);
398 					}
399 					if (Interpolate)
400 					{
401 						glVertex3f((1 - Inter) * verts[index].v[0] + Inter * verts2[index].v[0],
402 							(1 - Inter) * verts[index].v[1] + Inter * verts2[index].v[1],
403 							(1 - Inter) * verts[index].v[2] + Inter * verts2[index].v[2]);
404 					}
405 					else
406 					{
407 						glVertex3f(verts[index].v[0], verts[index].v[1], verts[index].v[2]);
408 					}
409 				}
410 			} while (--count);
411 
412 			glEnd();
413 		}
414 	}
415 
416 	if (!HaveShaders)
417 	{
418 		glShadeModel(GL_FLAT);
419 		glAlphaFunc(GL_GREATER, 0.666);
420 		glDisable(GL_ALPHA_TEST);
421 	}
422 	glDisable(GL_BLEND);
423 	if (Additive)
424 	{
425 		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
426 	}
427 
428 	glPopMatrix();
429 	if (is_view_model)
430 	{
431 		glDepthRange(0.0, 1.0);
432 	}
433 	unguard;
434 }
435 
436 //==========================================================================
437 //
438 //	VOpenGLDrawer::DrawAliasModelAmbient
439 //
440 //==========================================================================
441 
DrawAliasModelAmbient(const TVec & origin,const TAVec & angles,const TVec & Offset,const TVec & Scale,VMeshModel * Mdl,int frame,int nextframe,VTexture * Skin,vuint32 light,float Inter,bool Interpolate)442 void VOpenGLDrawer::DrawAliasModelAmbient(const TVec &origin, const TAVec &angles,
443 	const TVec& Offset, const TVec& Scale, VMeshModel* Mdl, int frame, int nextframe,
444 	VTexture* Skin, vuint32 light, float Inter, bool Interpolate)
445 {
446 	guard(VOpenGLDrawer::DrawAliasModelAmbient);
447 	UploadModel(Mdl);
448 	VMeshFrame* FrameDesc = &Mdl->Frames[frame];
449 	VMeshFrame* NextFrameDesc = &Mdl->Frames[nextframe];
450 
451 	SetPic(Skin, NULL, CM_Default);
452 
453 	VMatrix4 RotationMatrix;
454 	AliasSetUpTransform(origin, angles, Offset, Scale, RotationMatrix);
455 
456 	p_glUseProgramObjectARB(ShadowsModelAmbientProgram);
457 	p_glUniform1iARB(ShadowsModelAmbientTextureLoc, 0);
458 	p_glUniform1fARB(ShadowsModelAmbientInterLoc, Inter);
459 	p_glUniform4fARB(ShadowsModelAmbientLightLoc,
460 		((light >> 16) & 255) / 255.0,
461 		((light >> 8) & 255) / 255.0,
462 		(light & 255) / 255.0, 1);
463 	p_glUniformMatrix4fvARB(ShadowsModelAmbientModelToWorldMatLoc, 1, GL_FALSE, RotationMatrix[0]);
464 
465 	p_glBindBufferARB(GL_ARRAY_BUFFER_ARB, Mdl->VertsBuffer);
466 	p_glVertexAttribPointerARB(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)FrameDesc->VertsOffset);
467 	p_glEnableVertexAttribArrayARB(0);
468 	p_glVertexAttribPointerARB(ShadowsModelAmbientVert2Loc, 3, GL_FLOAT, GL_FALSE, 0,
469 		(void*)NextFrameDesc->VertsOffset);
470 	p_glEnableVertexAttribArrayARB(ShadowsModelAmbientVert2Loc);
471 	p_glVertexAttribPointerARB(ShadowsModelAmbientTexCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, 0);
472 	p_glEnableVertexAttribArrayARB(ShadowsModelAmbientTexCoordLoc);
473 
474 	p_glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, Mdl->IndexBuffer);
475 	p_glDrawRangeElementsEXT(GL_TRIANGLES, 0, Mdl->STVerts.Num() - 1, Mdl->Tris.Num() * 3, GL_UNSIGNED_SHORT, 0);
476 	p_glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
477 
478 	p_glDisableVertexAttribArrayARB(0);
479 	p_glDisableVertexAttribArrayARB(ShadowsModelAmbientVert2Loc);
480 	p_glDisableVertexAttribArrayARB(ShadowsModelAmbientTexCoordLoc);
481 	p_glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
482 	unguard;
483 }
484 
485 //==========================================================================
486 //
487 //	VOpenGLDrawer::DrawAliasModelTextures
488 //
489 //==========================================================================
490 
DrawAliasModelTextures(const TVec & origin,const TAVec & angles,const TVec & Offset,const TVec & Scale,VMeshModel * Mdl,int frame,int nextframe,VTexture * Skin,VTextureTranslation * Trans,int CMap,float Inter,bool Interpolate)491 void VOpenGLDrawer::DrawAliasModelTextures(const TVec &origin, const TAVec &angles,
492 	const TVec& Offset, const TVec& Scale, VMeshModel* Mdl, int frame, int nextframe,
493 	VTexture* Skin, VTextureTranslation* Trans, int CMap, float Inter,
494 	bool Interpolate)
495 {
496 	guard(VOpenGLDrawer::DrawAliasModelTextures);
497 	UploadModel(Mdl);
498 	VMeshFrame* FrameDesc = &Mdl->Frames[frame];
499 	VMeshFrame* NextFrameDesc = &Mdl->Frames[nextframe];
500 
501 	SetPic(Skin, Trans, CMap);
502 
503 	VMatrix4 RotationMatrix;
504 	AliasSetUpTransform(origin, angles, Offset, Scale, RotationMatrix);
505 
506 	p_glUseProgramObjectARB(ShadowsModelTexturesProgram);
507 	p_glUniform1iARB(ShadowsModelTexturesTextureLoc, 0);
508 	p_glUniform1fARB(ShadowsModelTexturesInterLoc, Inter);
509 	p_glUniformMatrix4fvARB(ShadowsModelTexturesModelToWorldMatLoc, 1, GL_FALSE, RotationMatrix[0]);
510 
511 	p_glBindBufferARB(GL_ARRAY_BUFFER_ARB, Mdl->VertsBuffer);
512 	p_glVertexAttribPointerARB(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)FrameDesc->VertsOffset);
513 	p_glEnableVertexAttribArrayARB(0);
514 	p_glVertexAttribPointerARB(ShadowsModelTexturesVert2Loc, 3, GL_FLOAT, GL_FALSE, 0,
515 		(void*)NextFrameDesc->VertsOffset);
516 	p_glEnableVertexAttribArrayARB(ShadowsModelTexturesVert2Loc);
517 	p_glVertexAttribPointerARB(ShadowsModelTexturesTexCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, 0);
518 	p_glEnableVertexAttribArrayARB(ShadowsModelTexturesTexCoordLoc);
519 
520 	p_glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, Mdl->IndexBuffer);
521 	p_glDrawRangeElementsEXT(GL_TRIANGLES, 0, Mdl->STVerts.Num() - 1, Mdl->Tris.Num() * 3, GL_UNSIGNED_SHORT, 0);
522 	p_glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
523 
524 	p_glDisableVertexAttribArrayARB(0);
525 	p_glDisableVertexAttribArrayARB(ShadowsModelTexturesVert2Loc);
526 	p_glDisableVertexAttribArrayARB(ShadowsModelTexturesTexCoordLoc);
527 	p_glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
528 	unguard;
529 }
530 
531 //==========================================================================
532 //
533 //	VOpenGLDrawer::BeginModelsLightPass
534 //
535 //==========================================================================
536 
BeginModelsLightPass(TVec & LightPos,float Radius,vuint32 Colour)537 void VOpenGLDrawer::BeginModelsLightPass(TVec& LightPos, float Radius, vuint32 Colour)
538 {
539 	guard(VOpenGLDrawer::BeginModelsLightPass);
540 	p_glUseProgramObjectARB(ShadowsModelLightProgram);
541 	p_glUniform1iARB(ShadowsModelLightTextureLoc, 0);
542 	p_glUniform3fARB(ShadowsModelLightLightPosLoc, LightPos.x, LightPos.y, LightPos.z);
543 	p_glUniform1fARB(ShadowsModelLightLightRadiusLoc, Radius);
544 	p_glUniform3fARB(ShadowsModelLightLightColourLoc,
545 		((Colour >> 16) & 255) / 255.0,
546 		((Colour >> 8) & 255) / 255.0,
547 		(Colour & 255) / 255.0);
548 	unguard;
549 }
550 
551 //==========================================================================
552 //
553 //	VOpenGLDrawer::DrawAliasModelLight
554 //
555 //==========================================================================
556 
DrawAliasModelLight(const TVec & origin,const TAVec & angles,const TVec & Offset,const TVec & Scale,VMeshModel * Mdl,int frame,int nextframe,VTexture * Skin,float Inter,bool Interpolate)557 void VOpenGLDrawer::DrawAliasModelLight(const TVec &origin, const TAVec &angles,
558 	const TVec& Offset, const TVec& Scale, VMeshModel* Mdl, int frame, int nextframe,
559 	VTexture* Skin, float Inter, bool Interpolate)
560 {
561 	guard(VOpenGLDrawer::DrawAliasModelLight);
562 	UploadModel(Mdl);
563 	VMeshFrame* FrameDesc = &Mdl->Frames[frame];
564 	VMeshFrame* NextFrameDesc = &Mdl->Frames[nextframe];
565 
566 	VMatrix4 RotationMatrix;
567 	AliasSetUpTransform(origin, angles, Offset, Scale, RotationMatrix);
568 	VMatrix4 normalmatrix;
569 	AliasSetUpNormalTransform(angles, Scale, normalmatrix);
570 	float NormalMat[3][3];
571 	NormalMat[0][0] = normalmatrix[0][0];
572 	NormalMat[0][1] = normalmatrix[0][1];
573 	NormalMat[0][2] = normalmatrix[0][2];
574 	NormalMat[1][0] = normalmatrix[1][0];
575 	NormalMat[1][1] = normalmatrix[1][1];
576 	NormalMat[1][2] = normalmatrix[1][2];
577 	NormalMat[2][0] = normalmatrix[2][0];
578 	NormalMat[2][1] = normalmatrix[2][1];
579 	NormalMat[2][2] = normalmatrix[2][2];
580 
581 	SetPic(Skin, NULL, CM_Default);
582 
583 	p_glUniform1fARB(ShadowsModelLightInterLoc, Inter);
584 	p_glUniformMatrix4fvARB(ShadowsModelLightModelToWorldMatLoc, 1, GL_FALSE, RotationMatrix[0]);
585 	p_glUniformMatrix3fvARB(ShadowsModelLightNormalToWorldMatLoc, 1, GL_FALSE, NormalMat[0]);
586 
587 	p_glBindBufferARB(GL_ARRAY_BUFFER_ARB, Mdl->VertsBuffer);
588 	p_glVertexAttribPointerARB(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)FrameDesc->VertsOffset);
589 	p_glEnableVertexAttribArrayARB(0);
590 	p_glVertexAttribPointerARB(ShadowsModelLightVertNormalLoc, 3, GL_FLOAT, GL_FALSE, 0,
591 		(void*)FrameDesc->NormalsOffset);
592 	p_glEnableVertexAttribArrayARB(ShadowsModelLightVertNormalLoc);
593 	p_glVertexAttribPointerARB(ShadowsModelLightVert2Loc, 3, GL_FLOAT, GL_FALSE, 0,
594 		(void*)NextFrameDesc->VertsOffset);
595 	p_glEnableVertexAttribArrayARB(ShadowsModelLightVert2Loc);
596 	p_glVertexAttribPointerARB(ShadowsModelLightVert2NormalLoc, 3, GL_FLOAT, GL_FALSE, 0,
597 		(void*)NextFrameDesc->NormalsOffset);
598 	p_glEnableVertexAttribArrayARB(ShadowsModelLightVert2NormalLoc);
599 	p_glVertexAttribPointerARB(ShadowsModelLightTexCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, 0);
600 	p_glEnableVertexAttribArrayARB(ShadowsModelLightTexCoordLoc);
601 
602 	p_glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, Mdl->IndexBuffer);
603 	p_glDrawRangeElementsEXT(GL_TRIANGLES, 0, Mdl->STVerts.Num() - 1, Mdl->Tris.Num() * 3, GL_UNSIGNED_SHORT, 0);
604 	p_glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
605 
606 	p_glDisableVertexAttribArrayARB(0);
607 	p_glDisableVertexAttribArrayARB(ShadowsModelLightVertNormalLoc);
608 	p_glDisableVertexAttribArrayARB(ShadowsModelLightVert2Loc);
609 	p_glDisableVertexAttribArrayARB(ShadowsModelLightVert2NormalLoc);
610 	p_glDisableVertexAttribArrayARB(ShadowsModelLightTexCoordLoc);
611 	p_glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
612 	unguard;
613 }
614 
615 //==========================================================================
616 //
617 //	VOpenGLDrawer::BeginModelsShadowsPass
618 //
619 //==========================================================================
620 
BeginModelsShadowsPass(TVec & LightPos,float LightRadius)621 void VOpenGLDrawer::BeginModelsShadowsPass(TVec& LightPos, float LightRadius)
622 {
623 	guard(VOpenGLDrawer::BeginModelsShadowsPass);
624 	p_glUseProgramObjectARB(ShadowsModelShadowProgram);
625 	p_glUniform3fARB(ShadowsModelShadowLightPosLoc, LightPos.x, LightPos.y, LightPos.z);
626 	unguard;
627 }
628 
629 //==========================================================================
630 //
631 //	VOpenGLDrawer::DrawAliasModelShadow
632 //
633 //==========================================================================
634 
DrawAliasModelShadow(const TVec & origin,const TAVec & angles,const TVec & Offset,const TVec & Scale,VMeshModel * Mdl,int frame,int nextframe,float Inter,bool Interpolate,const TVec & LightPos,float LightRadius)635 void VOpenGLDrawer::DrawAliasModelShadow(const TVec &origin, const TAVec &angles,
636 	const TVec& Offset, const TVec& Scale, VMeshModel* Mdl, int frame, int nextframe,
637 	float Inter, bool Interpolate, const TVec& LightPos, float LightRadius)
638 {
639 	guard(VOpenGLDrawer::DrawAliasModelShadow);
640 	UploadModel(Mdl);
641 	VMeshFrame* FrameDesc = &Mdl->Frames[frame];
642 	VMeshFrame* NextFrameDesc = &Mdl->Frames[nextframe];
643 
644 	VMatrix4 RotationMatrix;
645 	AliasSetUpTransform(origin, angles, Offset, Scale, RotationMatrix);
646 
647 	VMatrix4 InvRotationMatrix = RotationMatrix.Inverse();
648 	TVec LocalLightPos = InvRotationMatrix.Transform(LightPos);
649 
650 	TArray<bool> PlaneSides;
651 	PlaneSides.SetNum(Mdl->Tris.Num());
652 	VMeshFrame* PlanesFrame = Inter >= 0.5 ? NextFrameDesc : FrameDesc;
653 	TPlane* P = PlanesFrame->Planes;
654 	for (int i = 0; i < Mdl->Tris.Num(); i++, P++)
655 	{
656 		PlaneSides[i] = DotProduct(LocalLightPos, P->normal) - P->dist > 0.1;
657 	}
658 
659 	p_glUniform1fARB(ShadowsModelShadowInterLoc, Inter);
660 	p_glUniformMatrix4fvARB(ShadowsModelShadowModelToWorldMatLoc, 1, GL_FALSE, RotationMatrix[0]);
661 
662 	p_glBindBufferARB(GL_ARRAY_BUFFER_ARB, Mdl->VertsBuffer);
663 	p_glVertexAttribPointerARB(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)FrameDesc->VertsOffset);
664 	p_glEnableVertexAttribArrayARB(0);
665 	p_glVertexAttribPointerARB(ShadowsModelShadowVert2Loc, 3, GL_FLOAT, GL_FALSE, 0,
666 		(void*)NextFrameDesc->VertsOffset);
667 	p_glEnableVertexAttribArrayARB(ShadowsModelShadowVert2Loc);
668 
669 	float Offset = M_INFINITY;
670 
671 	glBegin(GL_TRIANGLES);
672 	p_glVertexAttrib1fARB(ShadowsModelShadowOffsetLoc, 0);
673 	for (int i = 0; i < Mdl->Tris.Num(); i++)
674 	{
675 		if (PlaneSides[i])
676 		{
677 			glArrayElement(Mdl->Tris[i].VertIndex[0]);
678 			glArrayElement(Mdl->Tris[i].VertIndex[1]);
679 			glArrayElement(Mdl->Tris[i].VertIndex[2]);
680 		}
681 	}
682 
683 	p_glVertexAttrib1fARB(ShadowsModelShadowOffsetLoc, Offset);
684 	for (int i = 0; i < Mdl->Tris.Num(); i++)
685 	{
686 		if (PlaneSides[i])
687 		{
688 			glArrayElement(Mdl->Tris[i].VertIndex[2]);
689 			glArrayElement(Mdl->Tris[i].VertIndex[1]);
690 			glArrayElement(Mdl->Tris[i].VertIndex[0]);
691 		}
692 	}
693 	glEnd();
694 
695 	for (int i = 0; i < Mdl->Edges.Num(); i++)
696 	{
697 		//	Edges with no matching pair are drawn only if corresponding triangle
698 		// is facing light, other are drawn if facing light changes.
699 		if ((Mdl->Edges[i].Tri2 == -1 && PlaneSides[Mdl->Edges[i].Tri1]) ||
700 			(Mdl->Edges[i].Tri2 != -1 && PlaneSides[Mdl->Edges[i].Tri1] != PlaneSides[Mdl->Edges[i].Tri2]))
701 		{
702 			int index1 = Mdl->Edges[i].Vert1;
703 			int index2 = Mdl->Edges[i].Vert2;
704 
705 #define outv(idx, offs) \
706 			p_glVertexAttrib1fARB(ShadowsModelShadowOffsetLoc, offs); \
707 			glArrayElement(index ## idx);
708 
709 			glBegin(GL_TRIANGLE_STRIP);
710 			if (PlaneSides[Mdl->Edges[i].Tri1])
711 			{
712 				outv(1, 0);
713 				outv(1, Offset);
714 				outv(2, 0);
715 				outv(2, Offset);
716 			}
717 			else
718 			{
719 				outv(2, 0);
720 				outv(2, Offset);
721 				outv(1, 0);
722 				outv(1, Offset);
723 			}
724 			glEnd();
725 		}
726 	}
727 
728 	p_glDisableVertexAttribArrayARB(0);
729 	p_glDisableVertexAttribArrayARB(ShadowsModelShadowVert2Loc);
730 	p_glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
731 	unguard;
732 }
733 
734 //==========================================================================
735 //
736 //	VOpenGLDrawer::DrawAliasModelFog
737 //
738 //==========================================================================
739 
DrawAliasModelFog(const TVec & origin,const TAVec & angles,const TVec & Offset,const TVec & Scale,VMeshModel * Mdl,int frame,int nextframe,VTexture * Skin,vuint32 Fade,float Inter,bool Interpolate)740 void VOpenGLDrawer::DrawAliasModelFog(const TVec &origin, const TAVec &angles,
741 	const TVec& Offset, const TVec& Scale, VMeshModel* Mdl, int frame, int nextframe,
742 	VTexture* Skin, vuint32 Fade, float Inter, bool Interpolate)
743 {
744 	guard(VOpenGLDrawer::DrawAliasModelFog);
745 	UploadModel(Mdl);
746 	VMeshFrame* FrameDesc = &Mdl->Frames[frame];
747 	VMeshFrame* NextFrameDesc = &Mdl->Frames[nextframe];
748 
749 	SetPic(Skin, NULL, CM_Default);
750 
751 	VMatrix4 RotationMatrix;
752 	AliasSetUpTransform(origin, angles, Offset, Scale, RotationMatrix);
753 
754 	p_glUseProgramObjectARB(ShadowsModelFogProgram);
755 	p_glUniform1iARB(ShadowsModelFogTextureLoc, 0);
756 	p_glUniform1fARB(ShadowsModelFogInterLoc, Inter);
757 	p_glUniformMatrix4fvARB(ShadowsModelFogModelToWorldMatLoc, 1, GL_FALSE, RotationMatrix[0]);
758 	p_glUniform1iARB(ShadowsModelFogFogTypeLoc, r_fog & 3);
759 	p_glUniform4fARB(ShadowsModelFogFogColourLoc,
760 		((Fade >> 16) & 255) / 255.0,
761 		((Fade >> 8) & 255) / 255.0,
762 		(Fade & 255) / 255.0, 1.0);
763 	p_glUniform1fARB(ShadowsModelFogFogDensityLoc, Fade == FADE_LIGHT ? 0.3 : r_fog_density);
764 	p_glUniform1fARB(ShadowsModelFogFogStartLoc, Fade == FADE_LIGHT ? 1.0 : r_fog_start);
765 	p_glUniform1fARB(ShadowsModelFogFogEndLoc, Fade == FADE_LIGHT ? 1024.0 * r_fade_factor : r_fog_end);
766 
767 	p_glBindBufferARB(GL_ARRAY_BUFFER_ARB, Mdl->VertsBuffer);
768 	p_glVertexAttribPointerARB(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)FrameDesc->VertsOffset);
769 	p_glEnableVertexAttribArrayARB(0);
770 	p_glVertexAttribPointerARB(ShadowsModelFogVert2Loc, 3, GL_FLOAT, GL_FALSE, 0,
771 		(void*)NextFrameDesc->VertsOffset);
772 	p_glEnableVertexAttribArrayARB(ShadowsModelFogVert2Loc);
773 	p_glVertexAttribPointerARB(ShadowsModelFogTexCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, 0);
774 	p_glEnableVertexAttribArrayARB(ShadowsModelFogTexCoordLoc);
775 
776 	p_glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, Mdl->IndexBuffer);
777 	p_glDrawRangeElementsEXT(GL_TRIANGLES, 0, Mdl->STVerts.Num() - 1, Mdl->Tris.Num() * 3, GL_UNSIGNED_SHORT, 0);
778 	p_glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
779 
780 	p_glDisableVertexAttribArrayARB(0);
781 	p_glDisableVertexAttribArrayARB(ShadowsModelFogVert2Loc);
782 	p_glDisableVertexAttribArrayARB(ShadowsModelFogTexCoordLoc);
783 	p_glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
784 	unguard;
785 }
786