Files
minecraft-pe-0.6.1/src/client/renderer/ItemInHandRenderer.cpp
Shredder e346df682c Another Huge Commit my bad - shredder
Restored Java's Debug Screen using partial unused code and ported code, avaliable in options menu as a style

Slight Water texture is now overlayed when in water

Vignette function has been fixed and can now be toggled in options

World Generation now includes Tall Grass and Ferns both

Broken Frame Chart Graph found in the source has now been fixed and enabled when debug screen is turned on

Pie Chart works now and will appear when debug screen is opened

Most changes have not been tested on anything besides windows, will test it
2026-05-04 01:28:27 +05:00

582 lines
16 KiB
C++
Executable File

#include "ItemInHandRenderer.h"
#include "gles.h"
#include "Tesselator.h"
#include "entity/EntityRenderDispatcher.h"
#include "entity/EntityRenderer.h"
#include "entity/MobRenderer.h"
#include "../Minecraft.h"
#include "../player/LocalPlayer.h"
#include "../../world/entity/player/Player.h"
#include "../../world/item/Item.h"
#include "../../world/level/material/Material.h"
#include "../../world/level/tile/Tile.h"
#include "../../world/level/Level.h"
#include "../../util/Mth.h"
#include "../../world/entity/player/Inventory.h"
#include "../../platform/time.h"
#include "Textures.h"
#include "../../world/item/UseAnim.h"
#include "../../world/item/BowItem.h"
#include "../../world/level/tile/LeafTile.h"
#include "entity/HumanoidMobRenderer.h"
#include "Lighting.h"
//static StopwatchHandler handler;
ItemInHandRenderer::ItemInHandRenderer( Minecraft* mc )
: mc(mc),
lastSlot(-1),
height(0),
oHeight(0),
lastIconRendered(0),
lastItemRendered(0),
//selectedItem(NULL),
item(0, 1, 0)
{
GLuint ids[MaxNumRenderObjects];
glGenBuffers2(MaxNumRenderObjects, ids);
for (int i = 0; i < MaxNumRenderObjects; ++i) {
renderObjects[i].itemId = -1;
renderObjects[i].chunk.vboId = ids[i];
//LOGI("IDS: %d\n", ids[i]);
}
//LOGI("SizeOf :%d (256 * %d)\n", sizeof(renderObjects), sizeof(RenderCall));
}
void ItemInHandRenderer::tick()
{
oHeight = height;
//item.id = 0;
ItemInstance* itemInHand = mc->player->inventory->getSelected();
bool sameItem = (itemInHand && item.id == itemInHand->id && item.getAuxValue() == itemInHand->getAuxValue());
if (mc->options.getBooleanValue(OPTIONS_RESTORED_ANIMS)) // if enabled, restores and fixes item switching animation
{
if (!itemInHand && item.id == 0) sameItem = true;
float max = 0.4f;
float tHeight = sameItem ? 1 : 0;
float dd = tHeight - height;
if (dd < -max) dd = -max;
if (dd > max) dd = max;
height += dd;
if (height < 0.1){
if (itemInHand && itemInHand->count > 0) {
item.id = itemInHand->id;
item.setAuxValue(itemInHand->getAuxValue());
} else {
item.id = 0;
}
}
} else // otherwise use vanilla broken behaviour where it instantly switches items/blocks
{
if (itemInHand && itemInHand->count > 0) {
item.id = itemInHand->id;
item.setAuxValue(itemInHand->getAuxValue());
}
float max = 0.4f;
float tHeight = 1;//matches ? 1 : 0;
float dd = tHeight - height;
if (dd < -max) dd = -max;
if (dd > max) dd = max;
height += dd;
}
}
void ItemInHandRenderer::renderItem(Mob* mob, ItemInstance* item )
{
//Stopwatch& w = handler.get("item:" + Tile::tiles[item->id]->getDescriptionId());
//w.start();
int itemId = item->id;
// Ugly hack, but what the heck, I don't have time at the moment
// Use spare slots between 200 and 255 (for now) for items with different
// graphics per data. @note: Check Tile.cpp for needed IDs to override
if (itemId == Tile::cloth->id) {
itemId = 200 + item->getAuxValue(); // 200 to 215
} else if (itemId == Tile::treeTrunk->id) {
itemId = 216 + item->getAuxValue(); // 216 to 219 @treeTrunk
} else if (itemId == Tile::sapling->id) {
itemId = 220 + item->getAuxValue(); // 220 to 223 @sapling
} else if (itemId == Tile::stoneSlabHalf->id) {
itemId = 224 + item->getAuxValue(); // 224 to 231 @stoneslab
} else if (itemId == ((Tile*)Tile::leaves)->id) {
itemId = 232 + (item->getAuxValue() & LeafTile::LEAF_TYPE_MASK); // 232 to 235 @leaves
}
RenderCall& renderObject = renderObjects[itemId];
int itemIcon = item->getIcon();
if(mob != NULL) {
itemIcon = mob->getItemInHandIcon(item, 0);
}
bool reTesselate(false);
if(itemIcon != lastIconRendered && lastItemRendered == itemId)
reTesselate = true;
lastItemRendered = itemId;
lastIconRendered = itemIcon;
//const int aux = item->getAuxValue();
if (renderObject.itemId == -1 || reTesselate) {
if (item->id < 256 && TileRenderer::canRender(Tile::tiles[item->id]->getRenderShape())) {
Tesselator& t = Tesselator::instance;
t.beginOverride();
int renderedItemId = item->id;
if (renderedItemId == ((Tile*)Tile::leaves)->id)
renderedItemId = ((Tile*)Tile::leaves_carried)->id;
if (renderedItemId == Tile::grass->id)
renderedItemId = Tile::grass_carried->id;
tileRenderer.renderTile(Tile::tiles[renderedItemId], item->getAuxValue());
renderObject.chunk = t.endOverride(renderObject.chunk.vboId);
renderObject.texture = "terrain.png";
renderObject.itemId = itemId;
renderObject.isFlat = false;
} else {
renderObject.itemId = itemId;
renderObject.isFlat = true;
if (item->id < 256) {
renderObject.texture = "terrain.png";
//mc->textures->loadAndBindTexture("terrain.png");
} else {
renderObject.texture = "gui/items.png";
//mc->textures->loadAndBindTexture("gui/items.png");
}
// glDisable2(GL_LIGHTING);
Tesselator& t = Tesselator::instance;
t.beginOverride();
t.color(0xff, 0xff, 0xff);
const int up = itemIcon & 15;
const int vp = itemIcon >> 4;
float u1 = (up * 16 + 0.00f) / 256.0f;
float u0 = (up * 16 + 15.99f) / 256.0f;
float v0 = (vp * 16 + 0.00f) / 256.0f;
float v1 = (vp * 16 + 15.99f) / 256.0f;
float r = 1.0f;
// float xo = 0.0f;
// float yo = 0.3f;
/*
//glEnable2(GL_RESCALE_NORMAL);
glTranslatef2(-xo, -yo, 0);
float s = 1.5f;
glScalef2(s, s, s);
glRotatef2(50, 0, 1, 0);
glRotatef2(45 + 290, 0, 0, 1);
glTranslatef2(-15 / 16.0f, -1 / 16.0f, 0);
*/
float dd = 1 / 16.0f;
float col = 1.0f;
float br = mc->player->getBrightness(0);
t.color(col*br,col*br,col*br,1.0f);
t.normal(0.0f, 0.0f, 1.0f);
t.vertexUV(0, 0, 0, u0, v1);
t.vertexUV(r, 0, 0, u1, v1);
t.vertexUV(r, 1, 0, u1, v0);
t.vertexUV(0, 1, 0, u0, v0);
t.normal(0.0f, 0.0f, -1.0f);
t.vertexUV(0, 1, 0 - dd, u0, v0);
t.vertexUV(r, 1, 0 - dd, u1, v0);
t.vertexUV(r, 0, 0 - dd, u1, v1);
t.vertexUV(0, 0, 0 - dd, u0, v1);
col = 0.8f;
t.color(col*br,col*br,col*br,1.0f);
t.normal(-1.0f, 0.0f, 0.0f);
for (int i = 0; i < 16; i++) {
float p = i / 16.0f;
float uu = u0 + (u1 - u0) * p - 0.5f / 256.0f;
float xx = r * p;
t.vertexUV(xx, 0, 0 - dd, uu, v1);
t.vertexUV(xx, 0, 0, uu, v1);
t.vertexUV(xx, 1, 0, uu, v0);
t.vertexUV(xx, 1, 0 - dd, uu, v0);
}
t.normal(1.0f, 0.0f, 0.0f);
for (int i = 0; i < 16; i++) {
float p = i / 16.0f;
float uu = u0 + (u1 - u0) * p - 0.5f / 256.0f;
float xx = r * p + 1 / 16.0f;
t.vertexUV(xx, 1, 0 - dd, uu, v0);
t.vertexUV(xx, 1, 0, uu, v0);
t.vertexUV(xx, 0, 0, uu, v1);
t.vertexUV(xx, 0, 0 - dd, uu, v1);
}
col = 0.6f;
t.color(col*br,col*br,col*br,1.0f);
t.normal(0.0f, 1.0f, 0.0f);
for (int i = 0; i < 16; i++) {
float p = i / 16.0f;
float vv = v1 + (v0 - v1) * p - 0.5f / 256.0f;
float yy = r * p + 1 / 16.0f;
t.vertexUV(0, yy, 0, u0, vv);
t.vertexUV(r, yy, 0, u1, vv);
t.vertexUV(r, yy, 0 - dd, u1, vv);
t.vertexUV(0, yy, 0 - dd, u0, vv);
}
t.normal(0.0f, -1.0f, 0.0f);
for (int i = 0; i < 16; i++) {
float p = i / 16.0f;
float vv = v1 + (v0 - v1) * p - 0.5f / 256.0f;
float yy = r * p;
t.vertexUV(r, yy, 0, u1, vv);
t.vertexUV(0, yy, 0, u0, vv);
t.vertexUV(0, yy, 0 - dd, u0, vv);
t.vertexUV(r, yy, 0 - dd, u1, vv);
}
renderObject.chunk = t.endOverride(renderObject.chunk.vboId);
}
}
if (renderObject.itemId >= 0) {
if (renderObject.isFlat) {
float xo = 0.0f;
float yo = 0.3f;
glPushMatrix2();
glTranslatef2(-xo, -yo, 0);
float s = 1.5f;
glScalef2(s, s, s);
glRotatef2(50, 0, 1, 0);
glRotatef2(45 + 290, 0, 0, 1);
glTranslatef2(-15 / 16.0f, -1 / 16.0f, 0);
}
mc->textures->loadAndBindTexture(renderObject.texture);
drawArrayVTN_NoState(renderObject.chunk.vboId, renderObject.chunk.vertexCount);
if (renderObject.isFlat)
glPopMatrix2();
}
//w.stop();
//handler.printEvery(100);
}
void ItemInHandRenderer::render( float a )
{
//return;
//Stopwatch& w = handler.get("render");
//w.start();
float h = oHeight + (height - oHeight) * a;
Player* player = mc->player;
// if (selectedTile==NULL) return;
glPushMatrix2();
glRotatef2(player->xRotO + (player->xRot - player->xRotO) * a, 1, 0, 0);
glRotatef2(player->yRotO + (player->yRot - player->yRotO) * a, 0, 1, 0);
glEnable(GL_RESCALE_NORMAL);
Lighting::turnOn(mc);
glPopMatrix2();
float br = mc->level->getBrightness(Mth::floor(player->x), Mth::floor(player->y), Mth::floor(player->z));
ItemInstance* item;// = selectedItem;
//if (player.fishing != NULL) {
// item = /*new*/ ItemInstance(Item.stick);
//}
if (this->item.id > 0)
item = &this->item;
else
item = NULL;
if (item != NULL) {
glColor4f2(br, br, br, 1);
bool isUsing = player->getUseItemDuration() > 0;
bool isBow = item->id == Item::bow->id;
bool noSwingAnimation = isUsing && (isBow || (item->getUseAnimation() != UseAnim::none));
const float swing = noSwingAnimation ? 0 : player->getAttackAnim(a);
const float sqrtSwing = Mth::sqrt(swing);
const float swing3 = Mth::sin(swing * swing * Mth::PI);
const float swing1 = Mth::sin(swing * Mth::PI);
const float swing2 = Mth::sin(sqrtSwing * Mth::PI);
const float d = 0.8f;
glPushMatrix2();
if (isUsing) {
UseAnim::UseAnimation anim = item->getUseAnimation();
if (anim == UseAnim::eat || anim == UseAnim::drink) {
float t = (player->getUseItemDuration() - a + 1);
float useProgress = 1 - (t / item->getUseDuration());
float swing = useProgress;
float is = 1 - swing;
is = is * is * is;
is = is * is * is;
is = is * is * is;
float iss = 1 - is;
glTranslatef(0, Mth::abs(Mth::cos(t / 4 * Mth::PI) * 0.1f) * (swing > 0.2 ? 1 : 0), 0);
glTranslatef(iss * 0.6f, -iss * 0.5f, 0);
glRotatef(iss * 90, 0, 1, 0);
glRotatef(iss * 10, 1, 0, 0);
glRotatef(iss * 30, 0, 0, 1);
}
} else {
glTranslatef2(-swing2 * 0.4f, (float) Mth::sin(sqrtSwing * Mth::PI * 2) * 0.2f, -swing1 * 0.2f);
}
glTranslatef2(0.7f * d, -0.65f * d - (1 - h) * 0.6f, -0.9f * d);
glRotatef2(45, 0, 1, 0);
glEnable2(GL_RESCALE_NORMAL);
glRotatef2(-swing3 * 20, 0, 1, 0);
glRotatef2(-swing2 * 20, 0, 0, 1);
glRotatef2(-swing2 * 80, 1, 0, 0);
float ss = 0.4f;
glScalef2(ss, ss, ss);
if (player->getUseItemDuration() > 0) {
UseAnim::UseAnimation anim = item->getUseAnimation();
if(anim == UseAnim::bow) {
glRotatef(-18, 0, 0, 1);
glRotatef(-12, 0, 1, 0);
glRotatef(-8, 1, 0, 0);
glTranslatef(-0.9f, 0.2f, 0.0f);
float timeHeld = (item->getUseDuration() - (player->getUseItemDuration() - a + 1));
float pow = timeHeld / (float) (BowItem::MAX_DRAW_DURATION);
pow = ((pow * pow) + pow * 2) / 3;
if (pow > 1) pow = 1;
if (pow > 0.1f) {
glTranslatef(0, Mth::sin((timeHeld - 0.1f) * 1.3f) * 0.01f * (pow - 0.1f), 0);
}
glTranslatef(0, 0, pow * 0.1f);
glRotatef(-45 - 290, 0, 0, 1);
glRotatef(-50, 0, 1, 0);
glTranslatef(0, 0.5f, 0);
float ys = 1 + pow * 0.2f;
glScalef(1, 1, ys);
glTranslatef(0, -0.5f, 0);
glRotatef(50, 0, 1, 0);
glRotatef(45 + 290, 0, 0, 1);
}
}
if (item->getItem()->isMirroredArt()) {
glRotatef2(180, 0, 1, 0);
}
glEnableClientState2(GL_VERTEX_ARRAY);
glEnableClientState2(GL_TEXTURE_COORD_ARRAY);
glEnableClientState2(GL_NORMAL_ARRAY);
renderItem(player, item);
glDisableClientState2(GL_NORMAL_ARRAY);
glDisableClientState2(GL_VERTEX_ARRAY);
glDisableClientState2(GL_TEXTURE_COORD_ARRAY);
glPopMatrix2();
} else {
glColor4f2(br, br, br, 1);
glPushMatrix2();
float d = 0.8f;
const float swing = player->getAttackAnim(a);
const float sqrtSwing = Mth::sqrt(swing);
const float swing3 = Mth::sin(swing * swing * Mth::PI);
const float swing1 = Mth::sin(swing * Mth::PI);
const float swing2 = Mth::sin(sqrtSwing * Mth::PI);
glTranslatef2(-swing2 * 0.3f, (float) Mth::sin(Mth::sqrt(swing) * Mth::PI * 2) * 0.4f, -swing1 * 0.4f);
glTranslatef2(0.8f * d, -0.75f * d - (1 - h) * 0.6f, -0.9f * d);
glRotatef2(45, 0, 1, 0);
// glEnable2(GL_RESCALE_NORMAL);
glEnable(GL_NORMALIZE);
glRotatef2(swing2 * 70, 0, 1, 0);
glRotatef2(-swing3 * 20, 0, 0, 1);
// glRotatef2(-swing2 * 80, 1, 0, 0);
mc->textures->loadAndBindTexture(player->getTexture());
glTranslatef2(-1.0f, +3.6f, +3.5f);
glRotatef2(120, 0, 0, 1);
glRotatef2(180 + 20, 1, 0, 0);
glRotatef2(-90 - 45, 0, 1, 0);
glScalef2(1.5f / 24.0f * 16, 1.5f / 24.0f * 16, 1.5f / 24.0f * 16);
glTranslatef2(5.6f, 0, 0);
EntityRenderer* er = EntityRenderDispatcher::getInstance()->getRenderer(mc->player);
HumanoidMobRenderer* playerRenderer = (HumanoidMobRenderer*) er;
float ss = 1;
glScalef2(ss, ss, ss);
playerRenderer->renderHand();
glPopMatrix2();
}
glDisable2(GL_RESCALE_NORMAL);
Lighting::turnOff();
//w.stop();
}
void ItemInHandRenderer::renderScreenEffect( float a )
{
glDisable2(GL_ALPHA_TEST);
if (mc->player->isOnFire()) {
mc->textures->loadAndBindTexture("terrain.png");
renderFire(a);
}
if (mc->player->isInWall()) // Inside a tile
{
int x = Mth::floor(mc->player->x);
int y = Mth::floor(mc->player->y);
int z = Mth::floor(mc->player->z);
mc->textures->loadAndBindTexture("terrain.png");
int tile = mc->level->getTile(x, y, z);
if (Tile::tiles[tile] != NULL) {
renderTex(a, Tile::tiles[tile]->getTexture(2));
}
}
if (mc->player->isUnderLiquid(Material::water)) {
mc->textures->loadAndBindTexture("misc/water.png");
renderWater(a);
}
glEnable2(GL_ALPHA_TEST);
}
void ItemInHandRenderer::itemPlaced()
{
height = 0;
}
void ItemInHandRenderer::itemUsed()
{
height = 0;
}
void ItemInHandRenderer::renderTex( float a, int tex )
{
Tesselator& t = Tesselator::instance;
float br;// = mc->player->getBrightness(a);
br = 0.1f;
glColor4f2(br, br, br, 0.5f);
glPushMatrix2();
float x0 = -1;
float x1 = +1;
float y0 = -1;
float y1 = +1;
float z0 = -0.5f;
float r = 2 / 256.0f;
float u0 = (tex % 16) / 256.0f - r;
float u1 = (tex % 16 + 15.99f) / 256.0f + r;
float v0 = (tex / 16) / 256.0f - r;
float v1 = (tex / 16 + 15.99f) / 256.0f + r;
t.begin();
t.vertexUV(x0, y0, z0, u1, v1);
t.vertexUV(x1, y0, z0, u0, v1);
t.vertexUV(x1, y1, z0, u0, v0);
t.vertexUV(x0, y1, z0, u1, v0);
//t.end();
t.draw();
glPopMatrix2();
glColor4f2(1, 1, 1, 1);
}
void ItemInHandRenderer::renderWater( float a )
{
Tesselator& t = Tesselator::instance;
float br = mc->player->getBrightness(a);
glColor4f2(br, br, br, 0.5f);
glEnable2(GL_BLEND);
glBlendFunc2(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glPushMatrix2();
float size = 4;
float x0 = -1;
float x1 = +1;
float y0 = -1;
float y1 = +1;
float z0 = -0.5f;
float uo = -mc->player->yRot / 64.0f;
float vo = +mc->player->xRot / 64.0f;
t.begin();
t.vertexUV(x0, y0, z0, size + uo, size + vo);
t.vertexUV(x1, y0, z0, 0 + uo, size + vo);
t.vertexUV(x1, y1, z0, 0 + uo, 0 + vo);
t.vertexUV(x0, y1, z0, size + uo, 0 + vo);
//t.end();
t.draw();
glPopMatrix2();
glColor4f2(1, 1, 1, 1);
glDisable2(GL_BLEND);
}
void ItemInHandRenderer::renderFire( float a )
{
Tesselator& t = Tesselator::instance;
glColor4f2(1, 1, 1, 0.9f);
glEnable2(GL_BLEND);
glBlendFunc2(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
float size = 1;
for (int i = 0; i < 2; i++) {
glPushMatrix2();
int tex = ((Tile*)Tile::fire)->tex + i * 16;
int xt = (tex & 0xf) << 4;
int yt = tex & 0xf0;
float u0 = (xt) / 256.0f;
float u1 = (xt + 15.99f) / 256.0f;
float v0 = (yt) / 256.0f;
float v1 = (yt + 15.99f) / 256.0f;
float x0 = (0 - size) / 2;
float x1 = x0 + size;
float y0 = 0 - size / 2;
float y1 = y0 + size;
float z0 = -0.5f;
glTranslatef2(-(i * 2 - 1) * 0.24f, -0.3f, 0);
glRotatef2((i * 2 - 1) * 10.f, 0, 1, 0);
t.begin();
t.vertexUV(x0, y0, z0, u1, v1);
t.vertexUV(x1, y0, z0, u0, v1);
t.vertexUV(x1, y1, z0, u0, v0);
t.vertexUV(x0, y1, z0, u1, v0);
//t.end();
t.draw();
glPopMatrix2();
}
glColor4f2(1, 1, 1, 1);
glDisable2(GL_BLEND);
}
void ItemInHandRenderer::onGraphicsReset()
{
GLuint ids[MaxNumRenderObjects];
glGenBuffers2(MaxNumRenderObjects, ids);
for (int i = 0; i < MaxNumRenderObjects; ++i) {
renderObjects[i].itemId = -1;
renderObjects[i].chunk.vboId = ids[i];
}
}