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
251 lines
6.5 KiB
C++
Executable File
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();
|
|
}
|