aboutsummaryrefslogtreecommitdiff
path: root/Minecraft.Client/MobRenderer.cpp
diff options
context:
space:
mode:
authorLoki Rautio <lokirautio@gmail.com>2026-03-04 03:56:03 -0600
committerLoki Rautio <lokirautio@gmail.com>2026-03-04 03:56:03 -0600
commit42aec6dac53dffa6afe072560a7e1d4986112538 (patch)
tree0836426857391df1b6a83f6368a183f83ec9b104 /Minecraft.Client/MobRenderer.cpp
parentc9d58eeac7c72f0b3038e084667b4d89a6249fce (diff)
parentef9b6fd500dfabd9463267b0dd9e29577eea8a2b (diff)
Merge branch 'main' into pr/win64-world-saves
# Conflicts: # Minecraft.Client/MinecraftServer.cpp # README.md
Diffstat (limited to 'Minecraft.Client/MobRenderer.cpp')
-rw-r--r--Minecraft.Client/MobRenderer.cpp568
1 files changed, 90 insertions, 478 deletions
diff --git a/Minecraft.Client/MobRenderer.cpp b/Minecraft.Client/MobRenderer.cpp
index 8874ab9c..ee512530 100644
--- a/Minecraft.Client/MobRenderer.cpp
+++ b/Minecraft.Client/MobRenderer.cpp
@@ -1,5 +1,6 @@
#include "stdafx.h"
#include "MobRenderer.h"
+#include "LivingEntityRenderer.h"
#include "MultiPlayerLocalPlayer.h"
#include "..\Minecraft.World\net.minecraft.world.entity.h"
#include "..\Minecraft.World\net.minecraft.world.entity.player.h"
@@ -8,508 +9,119 @@
#include "..\Minecraft.World\Mth.h"
#include "entityRenderDispatcher.h"
-MobRenderer::MobRenderer(Model *model, float shadow) : EntityRenderer()
+MobRenderer::MobRenderer(Model *model, float shadow) : LivingEntityRenderer(model, shadow)
{
- this->model = model;
- this->shadowRadius = shadow;
-
- this->armor = NULL;
}
-void MobRenderer::setArmor(Model *armor)
+void MobRenderer::render(shared_ptr<Entity> _mob, double x, double y, double z, float rot, float a)
{
- this->armor = armor;
+ shared_ptr<Mob> mob = dynamic_pointer_cast<Mob>(_mob);
+
+ LivingEntityRenderer::render(mob, x, y, z, rot, a);
+ renderLeash(mob, x, y, z, rot, a);
}
-float MobRenderer::rotlerp(float from, float to, float a)
+bool MobRenderer::shouldShowName(shared_ptr<LivingEntity> mob)
{
- float diff = to - from;
- while (diff < -180)
- diff += 360;
- while (diff >= 180)
- diff -= 360;
- return from + a * diff;
+ return LivingEntityRenderer::shouldShowName(mob) && (mob->shouldShowName() || dynamic_pointer_cast<Mob>(mob)->hasCustomName() && mob == entityRenderDispatcher->crosshairPickMob);
}
-void MobRenderer::render(shared_ptr<Entity> _mob, double x, double y, double z, float rot, float a)
+void MobRenderer::renderLeash(shared_ptr<Mob> entity, double x, double y, double z, float rot, float a)
{
- // 4J - added - this used to use generics so the input parameter could be a mob (or derived type), but we aren't
- // able to do that so dynamically casting to get the more specific type here.
- shared_ptr<Mob> mob = dynamic_pointer_cast<Mob>(_mob);
- glPushMatrix();
- glDisable(GL_CULL_FACE);
-
- model->attackTime = getAttackAnim(mob, a);
- if (armor != NULL) armor->attackTime = model->attackTime;
- model->riding = mob->isRiding();
- if (armor != NULL) armor->riding = model->riding;
- model->young = mob->isBaby();
- if (armor != NULL) armor->young = model->young;
-
- // 4J - removed try/catch
-// try
-// {
- float bodyRot = rotlerp(mob->yBodyRotO, mob->yBodyRot, a);
- float headRot = rotlerp(mob->yHeadRotO, mob->yHeadRot, a);
-
- if (mob->isRiding() && dynamic_pointer_cast<Mob>(mob->riding))
- {
- shared_ptr<Mob> riding = dynamic_pointer_cast<Mob>(mob->riding);
- bodyRot = rotlerp(riding->yBodyRotO, riding->yBodyRot, a);
-
- float headDiff = Mth::wrapDegrees(headRot - bodyRot);
- if (headDiff < -85) headDiff = -85;
- if (headDiff >= 85) headDiff = +85;
- bodyRot = headRot - headDiff;
- if (headDiff * headDiff > 50 * 50)
- {
- bodyRot += headDiff * 0.2f;
- }
- }
-
- float headRotx = (mob->xRotO + (mob->xRot - mob->xRotO) * a);
-
- setupPosition(mob, x, y, z);
-
- float bob = getBob(mob, a);
- setupRotations(mob, bob, bodyRot, a);
-
- float _scale = 1 / 16.0f;
- glEnable(GL_RESCALE_NORMAL);
- glScalef(-1, -1, 1);
-
- scale(mob, a);
- glTranslatef(0, -24 * _scale - 0.125f / 16.0f, 0);
-
-
- float ws = mob->walkAnimSpeedO + (mob->walkAnimSpeed - mob->walkAnimSpeedO) * a;
- float wp = mob->walkAnimPos - mob->walkAnimSpeed * (1 - a);
- if (mob->isBaby())
+ shared_ptr<Entity> roper = entity->getLeashHolder();
+ // roper = entityRenderDispatcher.cameraEntity;
+ if (roper != NULL)
+ {
+ glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
+
+ y -= (1.6 - entity->bbHeight) * .5;
+ Tesselator *tessellator = Tesselator::getInstance();
+ double roperYRot = lerp(roper->yRotO, roper->yRot, a * .5f) * Mth::RAD_TO_GRAD;
+ double roperXRot = lerp(roper->xRotO, roper->xRot, a * .5f) * Mth::RAD_TO_GRAD;
+ double rotOffCos = cos(roperYRot);
+ double rotOffSin = sin(roperYRot);
+ double yOff = sin(roperXRot);
+ if (roper->instanceof(eTYPE_HANGING_ENTITY))
{
- wp *= 3.0f;
- }
-
- if (ws > 1) ws = 1;
-
- MemSect(31);
- bindTexture(mob->customTextureUrl, mob->getTexture());
- MemSect(0);
- glEnable(GL_ALPHA_TEST);
-
- model->prepareMobModel(mob, wp, ws, a);
- renderModel(mob, wp, ws, bob, headRot - bodyRot, headRotx, _scale);
- for (int i = 0; i < MAX_ARMOR_LAYERS; i++)
+ rotOffCos = 0;
+ rotOffSin = 0;
+ yOff = -1;
+ }
+ double swingOff = cos(roperXRot);
+ double endX = lerp(roper->xo, roper->x, a) - (rotOffCos * 0.7) - (rotOffSin * 0.5 * swingOff);
+ double endY = lerp(roper->yo + roper->getHeadHeight() * .7, roper->y + roper->getHeadHeight() * .7, a) - (yOff * 0.5) - .25;
+ double endZ = lerp(roper->zo, roper->z, a) - (rotOffSin * 0.7) + (rotOffCos * 0.5 * swingOff);
+
+ double entityYRot = lerp(entity->yBodyRotO, entity->yBodyRot, a) * Mth::RAD_TO_GRAD + PI * .5;
+ rotOffCos = cos(entityYRot) * entity->bbWidth * .4;
+ rotOffSin = sin(entityYRot) * entity->bbWidth * .4;
+ double startX = lerp(entity->xo, entity->x, a) + rotOffCos;
+ double startY = lerp(entity->yo, entity->y, a);
+ double startZ = lerp(entity->zo, entity->z, a) + rotOffSin;
+ x += rotOffCos;
+ z += rotOffSin;
+
+ double dx = (float) (endX - startX);
+ double dy = (float) (endY - startY);
+ double dz = (float) (endZ - startZ);
+
+ glDisable(GL_TEXTURE_2D);
+ glDisable(GL_LIGHTING);
+ glDisable(GL_CULL_FACE);
+
+ unsigned int lightCol = Minecraft::GetInstance()->getColourTable()->getColor( eMinecraftColour_Leash_Light_Colour );
+ float rLightCol = ( (lightCol>>16)&0xFF )/255.0f;
+ float gLightCol = ( (lightCol>>8)&0xFF )/255.0;
+ float bLightCol = ( lightCol&0xFF )/255.0;
+
+ unsigned int darkCol = Minecraft::GetInstance()->getColourTable()->getColor( eMinecraftColour_Leash_Dark_Colour );
+ float rDarkCol = ( (darkCol>>16)&0xFF )/255.0f;
+ float gDarkCol = ( (darkCol>>8)&0xFF )/255.0;
+ float bDarkCol = ( darkCol&0xFF )/255.0;
+
+ int steps = 24;
+ double width = .025;
+ tessellator->begin(GL_TRIANGLE_STRIP);
+ for (int k = 0; k <= steps; k++)
{
- int armorType = prepareArmor(mob, i, a);
- if (armorType > 0)
+ if (k % 2 == 0)
{
- armor->prepareMobModel(mob, wp, ws, a);
- armor->render(mob, wp, ws, bob, headRot - bodyRot, headRotx, _scale, true);
- if ((armorType & 0xf0) == 16)
- {
- prepareSecondPassArmor(mob, i, a);
- armor->render(mob, wp, ws, bob, headRot - bodyRot, headRotx, _scale, true);
- }
- // 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
- // 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
- // 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.
- if( !entityRenderDispatcher->isGuiRender )
- {
- if ((armorType & 0xf) == 0xf) //MGH - fix for missing enchantment glow
- {
- float time = mob->tickCount + a;
- bindTexture(TN__BLUR__MISC_GLINT); // 4J was "%blur%/misc/glint.png"
- glEnable(GL_BLEND);
- float br = 0.5f;
- glColor4f(br, br, br, 1);
- glDepthFunc(GL_EQUAL);
- glDepthMask(false);
-
- for (int j = 0; j < 2; j++)
- {
- glDisable(GL_LIGHTING);
- float brr = 0.76f;
- glColor4f(0.5f * brr, 0.25f * brr, 0.8f * brr, 1);
- glBlendFunc(GL_SRC_COLOR, GL_ONE);
- glMatrixMode(GL_TEXTURE);
- glLoadIdentity();
- float uo = time * (0.001f + j * 0.003f) * 20;
- float ss = 1 / 3.0f;
- glScalef(ss, ss, ss);
- glRotatef(30 - (j) * 60.0f, 0, 0, 1);
- glTranslatef(0, uo, 0);
- glMatrixMode(GL_MODELVIEW);
- armor->render(mob, wp, ws, bob, headRot - bodyRot, headRotx, _scale, false);
- }
-
- glColor4f(1, 1, 1, 1);
- glMatrixMode(GL_TEXTURE);
- glDepthMask(true);
- glLoadIdentity();
- glMatrixMode(GL_MODELVIEW);
- glEnable(GL_LIGHTING);
- glDisable(GL_BLEND);
- glDepthFunc(GL_LEQUAL);
-
- }
- glDisable(GL_BLEND);
- }
- glEnable(GL_ALPHA_TEST);
+ tessellator->color(rLightCol, gLightCol, bLightCol, 1.0F);
}
+ else
+ {
+ tessellator->color(rDarkCol, gDarkCol, bDarkCol, 1.0F);
+ }
+ float aa = (float) k / (float) steps;
+ tessellator->vertex(x + (dx * aa) + 0, y + (dy * ((aa * aa) + aa) * 0.5) + ((((float) steps - (float) k) / (steps * 0.75F)) + 0.125F), z + (dz * aa));
+ tessellator->vertex(x + (dx * aa) + width, y + (dy * ((aa * aa) + aa) * 0.5) + ((((float) steps - (float) k) / (steps * 0.75F)) + 0.125F) + width, z + (dz * aa));
}
+ tessellator->end();
- glDepthMask(true);
-
- additionalRendering(mob, a);
- float br = mob->getBrightness(a);
- int overlayColor = getOverlayColor(mob, br, a);
- glActiveTexture(GL_TEXTURE1);
- glDisable(GL_TEXTURE_2D);
- glActiveTexture(GL_TEXTURE0);
-
- if (((overlayColor >> 24) & 0xff) > 0 || mob->hurtTime > 0 || mob->deathTime > 0)
+ tessellator->begin(GL_TRIANGLE_STRIP);
+ for (int k = 0; k <= steps; k++)
{
- glDisable(GL_TEXTURE_2D);
- glDisable(GL_ALPHA_TEST);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glDepthFunc(GL_EQUAL);
-
- // 4J - changed these renders to not use the compiled version of their models, because otherwise the render states set
- // about (in particular the depth & alpha test) don't work with our command buffer versions
- if (mob->hurtTime > 0 || mob->deathTime > 0)
+ if (k % 2 == 0)
{
- glColor4f(br, 0, 0, 0.4f);
- model->render(mob, wp, ws, bob, headRot - bodyRot, headRotx, _scale, false);
- for (int i = 0; i < MAX_ARMOR_LAYERS; i++)
- {
- if (prepareArmorOverlay(mob, i, a) >= 0)
- {
- glColor4f(br, 0, 0, 0.4f);
- armor->render(mob, wp, ws, bob, headRot - bodyRot, headRotx, _scale, false);
- }
- }
+ tessellator->color(rLightCol, gLightCol, bLightCol, 1.0F);
}
-
- if (((overlayColor >> 24) & 0xff) > 0)
+ else
{
- float r = ((overlayColor >> 16) & 0xff) / 255.0f;
- float g = ((overlayColor >> 8) & 0xff) / 255.0f;
- float b = ((overlayColor) & 0xff) / 255.0f;
- float aa = ((overlayColor >> 24) & 0xff) / 255.0f;
- glColor4f(r, g, b, aa);
- model->render(mob, wp, ws, bob, headRot - bodyRot, headRotx, _scale, false);
- for (int i = 0; i < MAX_ARMOR_LAYERS; i++)
- {
- if (prepareArmorOverlay(mob, i, a) >= 0)
- {
- glColor4f(r, g, b, aa);
- armor->render(mob, wp, ws, bob, headRot - bodyRot, headRotx, _scale, false);
- }
- }
+ tessellator->color(rDarkCol, gDarkCol, bDarkCol, 1.0F);
}
-
- glDepthFunc(GL_LEQUAL);
- glDisable(GL_BLEND);
- glEnable(GL_ALPHA_TEST);
- glEnable(GL_TEXTURE_2D);
+ float aa = (float) k / (float) steps;
+ tessellator->vertex(x + (dx * aa) + 0, y + (dy * ((aa * aa) + aa) * 0.5) + ((((float) steps - (float) k) / (steps * 0.75F)) + 0.125F) + width, z + (dz * aa));
+ tessellator->vertex(x + (dx * aa) + width, y + (dy * ((aa * aa) + aa) * 0.5) + ((((float) steps - (float) k) / (steps * 0.75F)) + 0.125F), z + (dz * aa) + width);
}
- glDisable(GL_RESCALE_NORMAL);
-// }
-//catch (Exception e) {
- // // System.out.println("Failed: " + modelNames[model]);
- // e.printStackTrace();
- // }
- glActiveTexture(GL_TEXTURE1);
- glEnable(GL_TEXTURE_2D);
- glActiveTexture(GL_TEXTURE0);
-
- glEnable(GL_CULL_FACE);
-
- glPopMatrix();
-
- MemSect(31);
- renderName(mob, x, y, z);
- MemSect(0);
-}
-
-void MobRenderer::renderModel(shared_ptr<Entity> mob, float wp, float ws, float bob, float headRotMinusBodyRot, float headRotx, float scale)
-{
- shared_ptr<Player> player = dynamic_pointer_cast<Player>(Minecraft::GetInstance()->player);
-
- bindTexture(mob->customTextureUrl, mob->getTexture());
- if (!mob->isInvisible())
- {
- model->render(mob, wp, ws, bob, headRotMinusBodyRot, headRotx, scale, true);
- }
- else if ( !mob->isInvisibleTo(player) )
- {
- glPushMatrix();
- glColor4f(1, 1, 1, 0.15f);
- glDepthMask(false);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glAlphaFunc(GL_GREATER, 1.0f / 255.0f);
- model->render(mob, wp, ws, bob, headRotMinusBodyRot, headRotx, scale, true);
- glDisable(GL_BLEND);
- glAlphaFunc(GL_GREATER, .1f);
- glPopMatrix();
- glDepthMask(true);
- }
- else
- {
- model->setupAnim(wp, ws, bob, headRotMinusBodyRot, headRotx, scale);//, mob);
- }
-}
-
-void MobRenderer::setupPosition(shared_ptr<Mob> mob, double x, double y, double z)
-{
- glTranslatef((float) x, (float) y, (float) z);
-}
+ tessellator->end();
-void MobRenderer::setupRotations(shared_ptr<Mob> mob, float bob, float bodyRot, float a)
-{
- glRotatef(180 - bodyRot, 0, 1, 0);
- if (mob->deathTime > 0)
- {
- float fall = (mob->deathTime + a - 1) / 20.0f * 1.6f;
- fall = (float)sqrt(fall);
- if (fall > 1) fall = 1;
- glRotatef(fall * getFlipDegrees(mob), 0, 0, 1);
+ glEnable(GL_LIGHTING);
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_CULL_FACE);
}
}
-float MobRenderer::getAttackAnim(shared_ptr<Mob> mob, float a)
-{
- return mob->getAttackAnim(a);
-}
-
-float MobRenderer::getBob(shared_ptr<Mob> mob, float a)
-{
- return (mob->tickCount + a);
-}
-
-void MobRenderer::additionalRendering(shared_ptr<Mob> mob, float a)
-{
-}
-
-int MobRenderer::prepareArmorOverlay(shared_ptr<Mob> mob, int layer, float a)
+double MobRenderer::lerp(double prev, double next, double a)
{
- return prepareArmor(mob, layer, a);
-}
-
-int MobRenderer::prepareArmor(shared_ptr<Mob> mob, int layer, float a)
-{
- return -1;
-}
-
-void MobRenderer::prepareSecondPassArmor(shared_ptr<Mob> mob, int layer, float a)
-{
-}
-
-float MobRenderer::getFlipDegrees(shared_ptr<Mob> mob)
-{
- return 90;
-}
-
-int MobRenderer::getOverlayColor(shared_ptr<Mob> mob, float br, float a)
-{
- return 0;
-}
-
-void MobRenderer::scale(shared_ptr<Mob> mob, float a)
-{
-}
-
-void MobRenderer::renderName(shared_ptr<Mob> mob, double x, double y, double z)
-{
- if (Minecraft::renderDebug())
- {
- //renderNameTag(mob, _toString<int>(mob->entityId), x, y, z, 64);
- }
-}
-
-// 4J Added parameter for color here so that we can colour players names
-void MobRenderer::renderNameTag(shared_ptr<Mob> mob, const wstring& OriginalName, double x, double y, double z, int maxDist, int color /*= 0xffffffff*/)
-{
-
- if ( app.GetGameSettings(eGameSetting_DisplayHUD)==0 )
- {
- // 4J-PB - turn off gamertag render
- return;
- }
-
- if(app.GetGameHostOption(eGameHostOption_Gamertags)==0)
- {
- // turn off gamertags if the host has set them off
- return;
- }
-
- float dist = mob->distanceTo(entityRenderDispatcher->cameraEntity);
-
- if (dist > maxDist)
- {
- return;
- }
-
- Font *font = getFont();
-
- float size = 1.60f;
- float s = 1 / 60.0f * size;
-
- glPushMatrix();
- glTranslatef((float) x + 0, (float) y + 2.3f, (float) z);
- glNormal3f(0, 1, 0);
-
- glRotatef(-this->entityRenderDispatcher->playerRotY, 0, 1, 0);
- glRotatef(this->entityRenderDispatcher->playerRotX, 1, 0, 0);
-
- glScalef(-s, -s, s);
- glDisable(GL_LIGHTING);
-
- // 4J Stu - If it's beyond readable distance, then just render a coloured box
- int readableDist = PLAYER_NAME_READABLE_FULLSCREEN;
- if( !RenderManager.IsHiDef() )
- {
- readableDist = PLAYER_NAME_READABLE_DISTANCE_SD;
- }
- else if ( app.GetLocalPlayerCount() > 2 )
- {
- readableDist = PLAYER_NAME_READABLE_DISTANCE_SPLITSCREEN;
- }
-
- float textOpacity = 1.0f;
- if( dist >= readableDist )
- {
- int diff = dist - readableDist;
-
- textOpacity /= (diff/2);
-
- if( diff > readableDist ) textOpacity = 0.0f;
- }
-
- if( textOpacity < 0.0f ) textOpacity = 0.0f;
- if( textOpacity > 1.0f ) textOpacity = 1.0f;
-
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- Tesselator *t = Tesselator::getInstance();
-
- int offs = 0;
- shared_ptr<Player> player = dynamic_pointer_cast<Player>(mob);
- if (player != NULL && app.isXuidDeadmau5( player->getXuid() ) ) offs = -10;
-
- wstring playerName;
- WCHAR wchName[2];
-
-#if defined(__PS3__) || defined(__ORBIS__)
- // Check we have all the font characters for this player name
- switch(player->GetPlayerNameValidState())
- {
- case Player::ePlayerNameValid_NotSet:
- if(font->AllCharactersValid(OriginalName))
- {
- playerName=OriginalName;
- player->SetPlayerNameValidState(true);
- }
- else
- {
- memset(wchName,0,sizeof(WCHAR)*2);
- swprintf(wchName, 2, L"%d",player->getPlayerIndex()+1);
- playerName=wchName;
- player->SetPlayerNameValidState(false);
- }
- break;
- case Player::ePlayerNameValid_True:
- playerName=OriginalName;
- break;
- case Player::ePlayerNameValid_False:
- memset(wchName,0,sizeof(WCHAR)*2);
- swprintf(wchName, 2, L"%d",player->getPlayerIndex()+1);
- playerName=wchName;
- break;
- }
-
-#else
- playerName=OriginalName;
-#endif
-
- if( textOpacity > 0.0f )
- {
- glColor4f(1.0f,1.0f,1.0f,textOpacity);
-
- glDepthMask(false);
- glDisable(GL_DEPTH_TEST);
-
- glDisable(GL_TEXTURE_2D);
-
- t->begin();
- int w = font->width(playerName) / 2;
-
- if( textOpacity < 1.0f )
- {
- t->color(color, 255 * textOpacity);
- }
- else
- {
- t->color(0.0f, 0.0f, 0.0f, 0.25f);
- }
- t->vertex((float)(-w - 1), (float)( -1 + offs), (float)( 0));
- t->vertex((float)(-w - 1), (float)( +8 + offs + 1), (float)( 0));
- t->vertex((float)(+w + 1), (float)( +8 + offs + 1), (float)( 0));
- t->vertex((float)(+w + 1), (float)( -1 + offs), (float)( 0));
- t->end();
-
- glEnable(GL_DEPTH_TEST);
- glDepthMask(true);
- glDepthFunc(GL_ALWAYS);
- glLineWidth(2.0f);
- t->begin(GL_LINE_STRIP);
- t->color(color, 255 * textOpacity);
- t->vertex((float)(-w - 1), (float)( -1 + offs), (float)( 0));
- t->vertex((float)(-w - 1), (float)( +8 + offs + 1), (float)( 0));
- t->vertex((float)(+w + 1), (float)( +8 + offs + 1), (float)( 0));
- t->vertex((float)(+w + 1), (float)( -1 + offs), (float)( 0));
- t->vertex((float)(-w - 1), (float)( -1 + offs), (float)( 0));
- t->end();
- glDepthFunc(GL_LEQUAL);
- glDepthMask(false);
- glDisable(GL_DEPTH_TEST);
-
- glEnable(GL_TEXTURE_2D);
- font->draw(playerName, -font->width(playerName) / 2, offs, 0x20ffffff);
- glEnable(GL_DEPTH_TEST);
-
- glDepthMask(true);
- }
-
- if( textOpacity < 1.0f )
- {
- glColor4f(1.0f,1.0f,1.0f,1.0f);
- glDisable(GL_TEXTURE_2D);
- glDepthFunc(GL_ALWAYS);
- t->begin();
- int w = font->width(playerName) / 2;
- t->color(color, 255);
- t->vertex((float)(-w - 1), (float)( -1 + offs), (float)( 0));
- t->vertex((float)(-w - 1), (float)( +8 + offs), (float)( 0));
- t->vertex((float)(+w + 1), (float)( +8 + offs), (float)( 0));
- t->vertex((float)(+w + 1), (float)( -1 + offs), (float)( 0));
- t->end();
- glDepthFunc(GL_LEQUAL);
- glEnable(GL_TEXTURE_2D);
-
- glTranslatef(0.0f, 0.0f, -0.04f);
- }
-
- if( textOpacity > 0.0f )
- {
- int textColor = ( ( (int)(textOpacity*255) << 24 ) | 0xffffff );
- font->draw(playerName, -font->width(playerName) / 2, offs, textColor);
- }
-
- glEnable(GL_LIGHTING);
- glDisable(GL_BLEND);
- glColor4f(1, 1, 1, 1);
- glPopMatrix();
-}
+ return prev + (next - prev) * a;
+} \ No newline at end of file