the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
1#include "stdafx.h"
2#include "LivingEntityRenderer.h"
3#include "Lighting.h"
4#include "Cube.h"
5#include "ModelPart.h"
6#include "EntityRenderDispatcher.h"
7#include "MultiPlayerLocalPlayer.h"
8#include "..\Minecraft.World\Arrow.h"
9#include "..\Minecraft.World\Mth.h"
10#include "..\Minecraft.World\Player.h"
11
12
13ResourceLocation LivingEntityRenderer::ENCHANT_GLINT_LOCATION = ResourceLocation(TN__BLUR__MISC_GLINT);
14int LivingEntityRenderer::MAX_ARMOR_LAYERS = 4;
15
16LivingEntityRenderer::LivingEntityRenderer(Model *model, float shadow)
17{
18 this->model = model;
19 shadowRadius = shadow;
20 armor = NULL;
21}
22
23void LivingEntityRenderer::setArmor(Model *armor)
24{
25 this->armor = armor;
26}
27
28float LivingEntityRenderer::rotlerp(float from, float to, float a)
29{
30 float diff = to - from;
31 while (diff < -180)
32 diff += 360;
33 while (diff >= 180)
34 diff -= 360;
35 return from + a * diff;
36}
37
38void LivingEntityRenderer::render(shared_ptr<Entity> _mob, double x, double y, double z, float rot, float a)
39{
40 shared_ptr<LivingEntity> mob = dynamic_pointer_cast<LivingEntity>(_mob);
41
42 glPushMatrix();
43 glDisable(GL_CULL_FACE);
44
45 model->attackTime = getAttackAnim(mob, a);
46 if (armor != NULL) armor->attackTime = model->attackTime;
47 model->riding = mob->isRiding();
48 if (armor != NULL) armor->riding = model->riding;
49 model->young = mob->isBaby();
50 if (armor != NULL) armor->young = model->young;
51
52 /*try*/
53 {
54 float bodyRot = rotlerp(mob->yBodyRotO, mob->yBodyRot, a);
55 float headRot = rotlerp(mob->yHeadRotO, mob->yHeadRot, a);
56
57 if (mob->isRiding() && mob->riding->instanceof(eTYPE_LIVINGENTITY))
58 {
59 shared_ptr<LivingEntity> riding = dynamic_pointer_cast<LivingEntity>(mob->riding);
60 bodyRot = rotlerp(riding->yBodyRotO, riding->yBodyRot, a);
61
62 float headDiff = Mth::wrapDegrees(headRot - bodyRot);
63 if (headDiff < -85) headDiff = -85;
64 if (headDiff >= 85) headDiff = +85;
65 bodyRot = headRot - headDiff;
66 if (headDiff * headDiff > 50 * 50)
67 {
68 bodyRot += headDiff * 0.2f;
69 }
70 }
71
72 float headRotx = (mob->xRotO + (mob->xRot - mob->xRotO) * a);
73
74 setupPosition(mob, x, y, z);
75
76 float bob = getBob(mob, a);
77 setupRotations(mob, bob, bodyRot, a);
78
79 float fScale = 1 / 16.0f;
80 glEnable(GL_RESCALE_NORMAL);
81 glScalef(-1, -1, 1);
82
83 scale(mob, a);
84 glTranslatef(0, -24 * fScale - 0.125f / 16.0f, 0);
85
86 float ws = mob->walkAnimSpeedO + (mob->walkAnimSpeed - mob->walkAnimSpeedO) * a;
87 float wp = mob->walkAnimPos - mob->walkAnimSpeed * (1 - a);
88 if (mob->isBaby())
89 {
90 wp *= 3.0f;
91 }
92
93 if (ws > 1) ws = 1;
94
95 glEnable(GL_ALPHA_TEST);
96 model->prepareMobModel(mob, wp, ws, a);
97 renderModel(mob, wp, ws, bob, headRot - bodyRot, headRotx, fScale);
98
99 for (int i = 0; i < MAX_ARMOR_LAYERS; i++)
100 {
101 int armorType = prepareArmor(mob, i, a);
102 if (armorType > 0)
103 {
104 armor->prepareMobModel(mob, wp, ws, a);
105 armor->render(mob, wp, ws, bob, headRot - bodyRot, headRotx, fScale, true);
106 if ((armorType & 0xf0) == 16)
107 {
108 prepareSecondPassArmor(mob, i, a);
109 armor->render(mob, wp, ws, bob, headRot - bodyRot, headRotx, fScale, true);
110 }
111 // 4J - added condition here for rendering player as part of the gui. Avoiding rendering the glint here as it involves using its own blending, and for gui rendering
112 // we are globally blending to be able to offer user configurable gui opacity. Note that I really don't know why GL_BLEND is turned off at the end of the first
113 // armour layer anyway, or why alpha testing is turned on... but we definitely don't want to be turning blending off during the gui render.
114 if( !entityRenderDispatcher->isGuiRender )
115 {
116 if ((armorType & 0xf) == 0xf)
117 {
118 float time = mob->tickCount + a;
119 bindTexture(&ENCHANT_GLINT_LOCATION);
120 glEnable(GL_BLEND);
121 float br = 0.5f;
122 glColor4f(br, br, br, 1);
123 glDepthFunc(GL_EQUAL);
124 glDepthMask(false);
125
126 for (int j = 0; j < 2; j++)
127 {
128 glDisable(GL_LIGHTING);
129 float brr = 0.76f;
130 glColor4f(0.5f * brr, 0.25f * brr, 0.8f * brr, 1);
131 glBlendFunc(GL_SRC_COLOR, GL_ONE);
132 glMatrixMode(GL_TEXTURE);
133 glLoadIdentity();
134 float uo = time * (0.001f + j * 0.003f) * 20;
135 float ss = 1 / 3.0f;
136 glScalef(ss, ss, ss);
137 glRotatef(30 - (j) * 60.0f, 0, 0, 1);
138 glTranslatef(0, uo, 0);
139 glMatrixMode(GL_MODELVIEW);
140 armor->render(mob, wp, ws, bob, headRot - bodyRot, headRotx, fScale, false);
141 }
142
143 glColor4f(1, 1, 1, 1);
144 glMatrixMode(GL_TEXTURE);
145 glDepthMask(true);
146 glLoadIdentity();
147 glMatrixMode(GL_MODELVIEW);
148 glEnable(GL_LIGHTING);
149 glDisable(GL_BLEND);
150 glDepthFunc(GL_LEQUAL);
151
152 }
153 glDisable(GL_BLEND);
154 }
155 glEnable(GL_ALPHA_TEST);
156 }
157 }
158 glDepthMask(true);
159
160 additionalRendering(mob, a);
161 float br = mob->getBrightness(a);
162 int overlayColor = getOverlayColor(mob, br, a);
163 glActiveTexture(GL_TEXTURE1);
164 glDisable(GL_TEXTURE_2D);
165 glActiveTexture(GL_TEXTURE0);
166
167 if (((overlayColor >> 24) & 0xff) > 0 || mob->hurtTime > 0 || mob->deathTime > 0)
168 {
169 glDisable(GL_TEXTURE_2D);
170 glDisable(GL_ALPHA_TEST);
171 glEnable(GL_BLEND);
172 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
173 glDepthFunc(GL_EQUAL);
174
175 // 4J - changed these renders to not use the compiled version of their models, because otherwise the render states set
176 // about (in particular the depth & alpha test) don't work with our command buffer versions
177 if (mob->hurtTime > 0 || mob->deathTime > 0)
178 {
179 glColor4f(br, 0, 0, 0.4f);
180 model->render(mob, wp, ws, bob, headRot - bodyRot, headRotx, fScale, false);
181 for (int i = 0; i < MAX_ARMOR_LAYERS; i++)
182 {
183 if (prepareArmorOverlay(mob, i, a) >= 0)
184 {
185 glColor4f(br, 0, 0, 0.4f);
186 armor->render(mob, wp, ws, bob, headRot - bodyRot, headRotx, fScale, false);
187 }
188 }
189 }
190
191 if (((overlayColor >> 24) & 0xff) > 0)
192 {
193 float r = ((overlayColor >> 16) & 0xff) / 255.0f;
194 float g = ((overlayColor >> 8) & 0xff) / 255.0f;
195 float b = ((overlayColor) & 0xff) / 255.0f;
196 float aa = ((overlayColor >> 24) & 0xff) / 255.0f;
197 glColor4f(r, g, b, aa);
198 model->render(mob, wp, ws, bob, headRot - bodyRot, headRotx, fScale, false);
199 for (int i = 0; i < MAX_ARMOR_LAYERS; i++)
200 {
201 if (prepareArmorOverlay(mob, i, a) >= 0)
202 {
203 glColor4f(r, g, b, aa);
204 armor->render(mob, wp, ws, bob, headRot - bodyRot, headRotx, fScale, false);
205 }
206 }
207 }
208
209 glDepthFunc(GL_LEQUAL);
210 glDisable(GL_BLEND);
211 glEnable(GL_ALPHA_TEST);
212 glEnable(GL_TEXTURE_2D);
213 }
214 glDisable(GL_RESCALE_NORMAL);
215 }
216 /* catch (Exception e)
217 {
218 e.printStackTrace();
219 }*/
220
221 glActiveTexture(GL_TEXTURE1);
222 glEnable(GL_TEXTURE_2D);
223 glActiveTexture(GL_TEXTURE0);
224 glEnable(GL_CULL_FACE);
225
226 glPopMatrix();
227
228 MemSect(31);
229 renderName(mob, x, y, z);
230 MemSect(0);
231}
232
233void LivingEntityRenderer::renderModel(shared_ptr<LivingEntity> mob, float wp, float ws, float bob, float headRotMinusBodyRot, float headRotx, float scale)
234{
235 bindTexture(mob);
236 if (!mob->isInvisible())
237 {
238 model->render(mob, wp, ws, bob, headRotMinusBodyRot, headRotx, scale, true);
239 }
240 else if(!mob->isInvisibleTo(dynamic_pointer_cast<Player>(Minecraft::GetInstance()->player)))
241 {
242 glPushMatrix();
243 glColor4f(1, 1, 1, 0.15f);
244 glDepthMask(false);
245 glEnable(GL_BLEND);
246 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
247 glAlphaFunc(GL_GREATER, 1.0f / 255.0f);
248 model->render(mob, wp, ws, bob, headRotMinusBodyRot, headRotx, scale, true);
249 glDisable(GL_BLEND);
250 glAlphaFunc(GL_GREATER, .1f);
251 glPopMatrix();
252 glDepthMask(true);
253 }
254 else
255 {
256 model->setupAnim(wp, ws, bob, headRotMinusBodyRot, headRotx, scale, mob);
257 }
258}
259
260void LivingEntityRenderer::setupPosition(shared_ptr<LivingEntity> mob, double x, double y, double z)
261{
262 glTranslatef((float) x, (float) y, (float) z);
263}
264
265void LivingEntityRenderer::setupRotations(shared_ptr<LivingEntity> mob, float bob, float bodyRot, float a)
266{
267 glRotatef(180 - bodyRot, 0, 1, 0);
268 if (mob->deathTime > 0)
269 {
270 float fall = (mob->deathTime + a - 1) / 20.0f * 1.6f;
271 fall = sqrt(fall);
272 if (fall > 1) fall = 1;
273 glRotatef(fall * getFlipDegrees(mob), 0, 0, 1);
274 }
275 else
276 {
277 wstring name = mob->getAName();
278 if (name == L"Dinnerbone" || name == L"Grumm")
279 {
280 if ( !mob->instanceof(eTYPE_PLAYER) || !dynamic_pointer_cast<Player>(mob)->isCapeHidden() )
281 {
282 glTranslatef(0, mob->bbHeight + 0.1f, 0);
283 glRotatef(180, 0, 0, 1);
284 }
285 }
286 }
287}
288
289float LivingEntityRenderer::getAttackAnim(shared_ptr<LivingEntity> mob, float a)
290{
291 return mob->getAttackAnim(a);
292}
293
294float LivingEntityRenderer::getBob(shared_ptr<LivingEntity> mob, float a)
295{
296 return (mob->tickCount + a);
297}
298
299void LivingEntityRenderer::additionalRendering(shared_ptr<LivingEntity> mob, float a)
300{
301
302}
303
304void LivingEntityRenderer::renderArrows(shared_ptr<LivingEntity> mob, float a)
305{
306 int arrowCount = mob->getArrowCount();
307 if (arrowCount > 0)
308 {
309 shared_ptr<Entity> arrow = shared_ptr<Entity>(new Arrow(mob->level, mob->x, mob->y, mob->z));
310 Random random = Random(mob->entityId);
311 Lighting::turnOff();
312 for (int i = 0; i < arrowCount; i++)
313 {
314 glPushMatrix();
315 ModelPart *modelPart = model->getRandomModelPart(random);
316 Cube *cube = modelPart->cubes[random.nextInt(modelPart->cubes.size())];
317 modelPart->translateTo(1 / 16.0f);
318 float xd = random.nextFloat();
319 float yd = random.nextFloat();
320 float zd = random.nextFloat();
321 float xo = (cube->x0 + (cube->x1 - cube->x0) * xd) / 16.0f;
322 float yo = (cube->y0 + (cube->y1 - cube->y0) * yd) / 16.0f;
323 float zo = (cube->z0 + (cube->z1 - cube->z0) * zd) / 16.0f;
324 glTranslatef(xo, yo, zo);
325 xd = xd * 2 - 1;
326 yd = yd * 2 - 1;
327 zd = zd * 2 - 1;
328 if (true)
329 {
330 xd *= -1;
331 yd *= -1;
332 zd *= -1;
333 }
334 float sd = (float) sqrt(xd * xd + zd * zd);
335 arrow->yRotO = arrow->yRot = (float) (atan2(xd, zd) * 180 / PI);
336 arrow->xRotO = arrow->xRot = (float) (atan2(yd, sd) * 180 / PI);
337 double x = 0;
338 double y = 0;
339 double z = 0;
340 float yRot = 0;
341 entityRenderDispatcher->render(arrow, x, y, z, yRot, a);
342 glPopMatrix();
343 }
344 Lighting::turnOn();
345 }
346}
347
348int LivingEntityRenderer::prepareArmorOverlay(shared_ptr<LivingEntity> mob, int layer, float a)
349{
350 return prepareArmor(mob, layer, a);
351}
352
353int LivingEntityRenderer::prepareArmor(shared_ptr<LivingEntity> mob, int layer, float a)
354{
355 return -1;
356}
357
358void LivingEntityRenderer::prepareSecondPassArmor(shared_ptr<LivingEntity> mob, int layer, float a)
359{
360}
361
362float LivingEntityRenderer::getFlipDegrees(shared_ptr<LivingEntity> mob)
363{
364 return 90;
365}
366
367int LivingEntityRenderer::getOverlayColor(shared_ptr<LivingEntity> mob, float br, float a)
368{
369 return 0;
370}
371
372void LivingEntityRenderer::scale(shared_ptr<LivingEntity> mob, float a)
373{
374}
375
376void LivingEntityRenderer::renderName(shared_ptr<LivingEntity> mob, double x, double y, double z)
377{
378 if (shouldShowName(mob) || Minecraft::renderDebug())
379 {
380 float size = 1.60f;
381 float s = 1 / 60.0f * size;
382 double dist = mob->distanceToSqr(entityRenderDispatcher->cameraEntity);
383
384 float maxDist = mob->isSneaking() ? 32 : 64;
385
386 if (dist < maxDist * maxDist)
387 {
388 wstring msg = mob->getDisplayName();
389
390 if (!msg.empty())
391 {
392 if (mob->isSneaking())
393 {
394 if ( app.GetGameSettings(eGameSetting_DisplayHUD)==0 )
395 {
396 // 4J-PB - turn off gamertag render
397 return;
398 }
399
400 if(app.GetGameHostOption(eGameHostOption_Gamertags)==0)
401 {
402 // turn off gamertags if the host has set them off
403 return;
404 }
405
406 Font *font = getFont();
407 glPushMatrix();
408 glTranslatef((float) x + 0, (float) y + mob->bbHeight + 0.5f, (float) z);
409 glNormal3f(0, 1, 0);
410
411 glRotatef(-entityRenderDispatcher->playerRotY, 0, 1, 0);
412 glRotatef(entityRenderDispatcher->playerRotX, 1, 0, 0);
413
414 glScalef(-s, -s, s);
415 glDisable(GL_LIGHTING);
416
417 glTranslatef(0, 0.25f / s, 0);
418 glDepthMask(false);
419 glEnable(GL_BLEND);
420 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
421 Tesselator *t = Tesselator::getInstance();
422
423 glDisable(GL_TEXTURE_2D);
424 t->begin();
425 int w = font->width(msg) / 2;
426 t->color(0.f, 0.f, 0.f, 0.25f);
427 t->vertex(-w - 1, -1, 0);
428 t->vertex(-w - 1, +8, 0);
429 t->vertex(+w + 1, +8, 0);
430 t->vertex(+w + 1, -1, 0);
431 t->end();
432 glEnable(GL_TEXTURE_2D);
433 glDepthMask(true);
434 font->draw(msg, -font->width(msg) / 2, 0, 0x20ffffff);
435 glEnable(GL_LIGHTING);
436 glDisable(GL_BLEND);
437 glColor4f(1, 1, 1, 1);
438 glPopMatrix();
439 }
440 else
441 {
442 renderNameTags(mob, x, y, z, msg, s, dist);
443 }
444 }
445 }
446 }
447}
448
449bool LivingEntityRenderer::shouldShowName(shared_ptr<LivingEntity> mob)
450{
451 return Minecraft::renderNames() && mob != entityRenderDispatcher->cameraEntity && !mob->isInvisibleTo(Minecraft::GetInstance()->player) && mob->rider.lock() == NULL;
452}
453
454void LivingEntityRenderer::renderNameTags(shared_ptr<LivingEntity> mob, double x, double y, double z, const wstring &msg, float scale, double dist)
455{
456 if (mob->isSleeping())
457 {
458 renderNameTag(mob, msg, x, y - 1.5f, z, 64);
459 }
460 else
461 {
462 renderNameTag(mob, msg, x, y, z, 64);
463 }
464}
465
466// 4J Added parameter for color here so that we can colour players names
467void LivingEntityRenderer::renderNameTag(shared_ptr<LivingEntity> mob, const wstring &name, double x, double y, double z, int maxDist, int color /*= 0xff000000*/)
468{
469 if ( app.GetGameSettings(eGameSetting_DisplayHUD)==0 )
470 {
471 // 4J-PB - turn off gamertag render
472 return;
473 }
474
475 if(app.GetGameHostOption(eGameHostOption_Gamertags)==0)
476 {
477 // turn off gamertags if the host has set them off
478 return;
479 }
480
481 float dist = mob->distanceTo(entityRenderDispatcher->cameraEntity);
482
483 if (dist > maxDist )
484 {
485 return;
486 }
487
488 Font *font = getFont();
489
490 float size = 1.60f;
491 float s = 1 / 60.0f * size;
492
493 glPushMatrix();
494 glTranslatef((float) x + 0, (float) y + 2.3f, (float) z);
495 glNormal3f(0, 1, 0);
496
497 glRotatef(-this->entityRenderDispatcher->playerRotY, 0, 1, 0);
498 glRotatef(this->entityRenderDispatcher->playerRotX, 1, 0, 0);
499
500 glScalef(-s, -s, s);
501 glDisable(GL_LIGHTING);
502
503 // 4J Stu - If it's beyond readable distance, then just render a coloured box
504 int readableDist = PLAYER_NAME_READABLE_FULLSCREEN;
505 if( !RenderManager.IsHiDef() )
506 {
507 readableDist = PLAYER_NAME_READABLE_DISTANCE_SD;
508 }
509 else if ( app.GetLocalPlayerCount() > 2 )
510 {
511 readableDist = PLAYER_NAME_READABLE_DISTANCE_SPLITSCREEN;
512 }
513
514 float textOpacity = 1.0f;
515 if( dist >= readableDist )
516 {
517 int diff = dist - readableDist;
518
519 textOpacity /= (diff/2);
520
521 if( diff > readableDist ) textOpacity = 0.0f;
522 }
523
524 if( textOpacity < 0.0f ) textOpacity = 0.0f;
525 if( textOpacity > 1.0f ) textOpacity = 1.0f;
526
527 glEnable(GL_BLEND);
528 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
529 Tesselator *t = Tesselator::getInstance();
530
531 int offs = 0;
532
533 wstring playerName;
534 WCHAR wchName[2];
535
536 if(mob->instanceof(eTYPE_PLAYER))
537 {
538 shared_ptr<Player> player = dynamic_pointer_cast<Player>(mob);
539
540 if(app.isXuidDeadmau5( player->getXuid() ) ) offs = -10;
541
542#if defined(__PS3__) || defined(__ORBIS__)
543 // Check we have all the font characters for this player name
544 switch(player->GetPlayerNameValidState())
545 {
546 case Player::ePlayerNameValid_NotSet:
547 if(font->AllCharactersValid(name))
548 {
549 playerName=name;
550 player->SetPlayerNameValidState(true);
551 }
552 else
553 {
554 memset(wchName,0,sizeof(WCHAR)*2);
555 swprintf(wchName, 2, L"%d",player->getPlayerIndex()+1);
556 playerName=wchName;
557 player->SetPlayerNameValidState(false);
558 }
559 break;
560 case Player::ePlayerNameValid_True:
561 playerName=name;
562 break;
563 case Player::ePlayerNameValid_False:
564 memset(wchName,0,sizeof(WCHAR)*2);
565 swprintf(wchName, 2, L"%d",player->getPlayerIndex()+1);
566 playerName=wchName;
567 break;
568 }
569#else
570 playerName = name;
571#endif
572 }
573 else
574 {
575 playerName = name;
576 }
577
578 if( textOpacity > 0.0f )
579 {
580 glColor4f(1.0f,1.0f,1.0f,textOpacity);
581
582 glDepthMask(false);
583 glDisable(GL_DEPTH_TEST);
584
585 glDisable(GL_TEXTURE_2D);
586
587 t->begin();
588 int w = font->width(playerName) / 2;
589
590 if( textOpacity < 1.0f )
591 {
592 t->color(color, 255 * textOpacity);
593 }
594 else
595 {
596 t->color(0.0f, 0.0f, 0.0f, 0.25f);
597 }
598 t->vertex((float)(-w - 1), (float)( -1 + offs), (float)( 0));
599 t->vertex((float)(-w - 1), (float)( +8 + offs + 1), (float)( 0));
600 t->vertex((float)(+w + 1), (float)( +8 + offs + 1), (float)( 0));
601 t->vertex((float)(+w + 1), (float)( -1 + offs), (float)( 0));
602 t->end();
603
604 glEnable(GL_DEPTH_TEST);
605 glDepthMask(true);
606 glDepthFunc(GL_ALWAYS);
607 glLineWidth(2.0f);
608 t->begin(GL_LINE_STRIP);
609 t->color(color, 255 * textOpacity);
610 t->vertex((float)(-w - 1), (float)( -1 + offs), (float)( 0));
611 t->vertex((float)(-w - 1), (float)( +8 + offs + 1), (float)( 0));
612 t->vertex((float)(+w + 1), (float)( +8 + offs + 1), (float)( 0));
613 t->vertex((float)(+w + 1), (float)( -1 + offs), (float)( 0));
614 t->vertex((float)(-w - 1), (float)( -1 + offs), (float)( 0));
615 t->end();
616 glDepthFunc(GL_LEQUAL);
617 glDepthMask(false);
618 glDisable(GL_DEPTH_TEST);
619
620 glEnable(GL_TEXTURE_2D);
621 font->draw(playerName, -font->width(playerName) / 2, offs, 0x20ffffff);
622 glEnable(GL_DEPTH_TEST);
623
624 glDepthMask(true);
625 }
626
627 if( textOpacity < 1.0f )
628 {
629 glColor4f(1.0f,1.0f,1.0f,1.0f);
630 glDisable(GL_TEXTURE_2D);
631 glDepthFunc(GL_ALWAYS);
632 t->begin();
633 int w = font->width(playerName) / 2;
634 t->color(color, 255);
635 t->vertex((float)(-w - 1), (float)( -1 + offs), (float)( 0));
636 t->vertex((float)(-w - 1), (float)( +8 + offs), (float)( 0));
637 t->vertex((float)(+w + 1), (float)( +8 + offs), (float)( 0));
638 t->vertex((float)(+w + 1), (float)( -1 + offs), (float)( 0));
639 t->end();
640 glDepthFunc(GL_LEQUAL);
641 glEnable(GL_TEXTURE_2D);
642
643 glTranslatef(0.0f, 0.0f, -0.04f);
644 }
645
646 if( textOpacity > 0.0f )
647 {
648 int textColor = ( ( (int)(textOpacity*255) << 24 ) | 0xffffff );
649 font->draw(playerName, -font->width(playerName) / 2, offs, textColor);
650 }
651
652 glEnable(GL_LIGHTING);
653 glDisable(GL_BLEND);
654 glColor4f(1, 1, 1, 1);
655 glPopMatrix();
656}