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