Files
minecraft-pe-0.6.1/src/client/renderer/entity/MobRenderer.cpp
Shredder d7d887f882 few additions and bug fixes
Added Hand Sway (not an option yet) from b1,8

Fire works properly in multiplayer now and also renders on undead mobs in sunlight now

hopefully fixed bow stuck bug on touchscreen devices

Fire on entites uses updated rendering from b1.6.6

Shadow bug fix attempt the 15th

Added looking at block in debug screen

Zombie Pigman now renders his hat layer

Temporarily disabled most randomlevelsource cave, canyon and tall grass code just for this commit to test performance
2026-05-23 05:29:47 +05:00

251 lines
6.5 KiB
C++
Executable File

#include "MobRenderer.h"
#include "EntityRenderDispatcher.h"
#include "../../gui/Font.h"
#include "../Tesselator.h"
#include "../../Minecraft.h"
#include "../../model/Model.h"
#include "../../../world/entity/Mob.h"
#include "../../../util/Mth.h"
MobRenderer::MobRenderer(Model* model, float shadow)
: model(model),
armor(NULL)
{
shadowRadius = shadow;
}
MobRenderer::~MobRenderer() {
delete model;
}
void MobRenderer::setArmor(Model* armor) {
this->armor = armor;
}
Model* MobRenderer::getArmor() {
return armor;
}
void MobRenderer::render(Entity* e, float x, float y, float z, float rot, float a)
{
Mob* mob = (Mob*) e;
glPushMatrix2();
glDisable2(GL_CULL_FACE);
model->attackTime = getAttackAnim(mob, a);
model->riding = false;//mob.isRiding();
model->young = mob->isBaby();
if (armor) {
armor->riding = model->riding;
armor->young = model->young;
armor->attackTime = model->attackTime;
}
float bodyRot = (mob->yBodyRotO + (mob->yBodyRot - mob->yBodyRotO) * a);
float headRot = (mob->yRotO + (mob->yRot - mob->yRotO) * a);
float headRotx = (mob->xRotO + (mob->xRot - mob->xRotO) * a);
float yoffset = mob->heightOffset;
setupPosition(mob, x, y - yoffset, z);
float bob = getBob(mob, a);
setupRotations(mob, bob, bodyRot, a);
float ascale = 1 / 16.0f;
glScalef2(-1, -1, 1);
scale(mob, a);
glTranslatef2(0, -24 * ascale - 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()) {
wp *= 3.0f;
}
if (ws > 1) ws = 1;
bindTexture(mob->getTexture());
//glEnable2(GL_ALPHA_TEST);
model->prepareMobModel(mob, wp, ws, a);
model->render(e, wp, ws, bob, headRot - bodyRot, headRotx, ascale);
for (int i = 0; i < MAX_ARMOR_LAYERS; i++) {
if (prepareArmor(mob, i, a) < 0) continue;
armor->prepareMobModel(mob, wp, ws, a);
armor->render(e, wp, ws, bob, headRot - bodyRot, headRotx, ascale);
glDisable2(GL_BLEND);
glEnable2(GL_ALPHA_TEST);
}
additionalRendering(mob, a);
float br = mob->getBrightness(a);
int overlayColor = getOverlayColor(mob, br, a);
bool renderOverlay = ((overlayColor >> 24) & 0xff) > 0;
bool renderHurt = (mob->hurtTime > 0) || (mob->deathTime > 0);
if (renderOverlay || renderHurt) {
glDisable2(GL_TEXTURE_2D);
glDisable2(GL_ALPHA_TEST);
glEnable2(GL_BLEND);
glBlendFunc2(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDepthFunc(GL_EQUAL);
if (renderHurt) {
glEnable(GL_COLOR_MATERIAL);
glColor4f2(br, 0, 0, 0.4f);
model->render(e, wp, ws, bob, headRot - bodyRot, headRotx, ascale);
for (int i = 0; i < MAX_ARMOR_LAYERS; i++) {
if (prepareArmor(mob, i, a) < 0) continue;
glColor4f2(br, 0, 0, 0.4f);
armor->prepareMobModel(mob, wp, ws, a);
armor->render(e, wp, ws, bob, headRot - bodyRot, headRotx, ascale);
}
}
if (renderOverlay) {
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;
glColor4f2(r, g, b, aa);
model->render(e, wp, ws, bob, headRot - bodyRot, headRotx, ascale);
for (int i = 0; i < MAX_ARMOR_LAYERS; i++) {
if (prepareArmor(mob, i, a) < 0) continue;
glColor4f2(r, g, b, aa);
armor->prepareMobModel(mob, wp, ws, a);
armor->render(e, wp, ws, bob, headRot - bodyRot, headRotx, ascale);
}
}
glDepthFunc(GL_LEQUAL);
glDisable2(GL_BLEND);
glEnable2(GL_ALPHA_TEST);
glEnable2(GL_TEXTURE_2D);
}
glEnable2(GL_CULL_FACE);
//glEnable2(GL_DEPTH_TEST);
glPopMatrix2();
postRender(mob, x, y, z, rot, a);
renderName(mob, x, y, z);
}
void MobRenderer::setupPosition(Entity* mob, float x, float y, float z) {
glTranslatef2((float) x, (float) y, (float) z);
}
void MobRenderer::setupRotations(Entity* mob_, float bob, float bodyRot, float a) {
glRotatef2(180 - bodyRot, 0, 1, 0);
Mob* mob = (Mob*)mob_;
if (mob->deathTime > 0) {
float fall = (mob->deathTime + a - 1) / 20.0f * 1.6f;
fall = Mth::sqrt(fall);
if (fall > 1) fall = 1;
glRotatef2(fall * getFlipDegrees(mob), 0, 0, 1);
}
}
float MobRenderer::getAttackAnim(Mob* mob, float a) {
return mob->getAttackAnim(a);
}
float MobRenderer::getBob(Mob* mob, float a) {
return (mob->tickCount + a);
}
void MobRenderer::additionalRendering(Mob* mob, float a) {
}
void MobRenderer::onGraphicsReset() {
if (model) model->onGraphicsReset();
if (armor) armor->onGraphicsReset();
}
int MobRenderer::prepareArmor(Mob* mob, int layer, float a) {
return -1;
}
float MobRenderer::getFlipDegrees(Mob* mob) {
return 90;
}
int MobRenderer::getOverlayColor(Mob* mob, float br, float a) {
return 0;
}
void MobRenderer::scale(Mob* mob, float a) {
}
void MobRenderer::renderName(Mob* mob, float x, float y, float z) {
std::stringstream ss; ss << mob->entityId;
if (entityRenderDispatcher->minecraft->options.getBooleanValue(OPTIONS_RENDER_DEBUG)) {
renderNameTag(mob, ss.str(), x, y, z, 64);
}
}
void MobRenderer::renderNameTag(Mob* mob, const std::string& name, float x, float y, float z, int maxDist) {
float dist = mob->distanceToSqr(entityRenderDispatcher->cameraEntity);
if (dist > maxDist*maxDist)
return;
Font* font = getFont();
float size = 1.60f;
float s = 1 / 60.0f * size;
glPushMatrix2();
if (mob->isPlayer()){
glTranslatef2((float) x + 0, (float) y + 1.0f, (float) z);
} else {
glTranslatef2((float) x + 0, (float) y + 2.3f, (float) z);
}
glRotatef2(-entityRenderDispatcher->playerRotY, 0, 1, 0);
glRotatef2(entityRenderDispatcher->playerRotX, 1, 0, 0);
glScalef2(-s, -s, s);
glDisable(GL_LIGHTING);
glDepthMask(false);
glDisable2(GL_DEPTH_TEST);
glEnable2(GL_BLEND);
glBlendFunc2(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Tesselator& t = Tesselator::instance;
glDisable2(GL_TEXTURE_2D);
t.begin();
int w = font->width(name) / 2;
t.color(0.0f, 0.0f, 0.0f, 0.25f);
t.vertex(-(float)w - 1, -1, 0);
t.vertex(-(float)w - 1, +8, 0);
t.vertex(+(float)w + 1, +8, 0);
t.vertex(+(float)w + 1, -1, 0);
//t.end();
t.draw();
glEnable2(GL_TEXTURE_2D);
const float fnameWidth = (float)font->width(name) / -2;
font->draw(name, fnameWidth, 0, 0x20ffffff);
glEnable2(GL_DEPTH_TEST);
glDepthMask(true);
font->draw(name, (float) fnameWidth, 0, 0xffffffff);
glEnable(GL_LIGHTING);
glDisable2(GL_BLEND);
glColor4f2(1, 1, 1, 1);
glPopMatrix2();
}