From b691c43c44ff180d10e7d4a9afc83b98551ff586 Mon Sep 17 00:00:00 2001 From: daoge_cmd <3523206925@qq.com> Date: Sun, 1 Mar 2026 12:16:08 +0800 Subject: Initial commit --- Minecraft.Client/ItemRenderer.cpp | 741 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 741 insertions(+) create mode 100644 Minecraft.Client/ItemRenderer.cpp (limited to 'Minecraft.Client/ItemRenderer.cpp') diff --git a/Minecraft.Client/ItemRenderer.cpp b/Minecraft.Client/ItemRenderer.cpp new file mode 100644 index 00000000..03d0d3a5 --- /dev/null +++ b/Minecraft.Client/ItemRenderer.cpp @@ -0,0 +1,741 @@ +#include "stdafx.h" +#include "ItemRenderer.h" +#include "TileRenderer.h" +#include "entityRenderDispatcher.h" +#include "..\Minecraft.World\JavaMath.h" +#include "..\Minecraft.World\net.minecraft.world.entity.item.h" +#include "..\Minecraft.World\net.minecraft.world.item.h" +#include "..\Minecraft.World\net.minecraft.world.item.alchemy.h" +#include "..\Minecraft.World\net.minecraft.world.level.tile.h" +#include "..\Minecraft.World\StringHelpers.h" +#include "..\Minecraft.World\net.minecraft.world.h" +#include "Options.h" + +ItemRenderer::ItemRenderer() : EntityRenderer() +{ + random = new Random(); + setColor = true; + blitOffset = 0; + + this->shadowRadius = 0.15f; + this->shadowStrength = 0.75f; + + // 4J added + m_bItemFrame= false; +} + +ItemRenderer::~ItemRenderer() +{ + delete random; +} + +void ItemRenderer::render(shared_ptr _itemEntity, double x, double y, double z, float rot, float a) +{ + // 4J - dynamic cast required because we aren't using templates/generics in our version + shared_ptr itemEntity = dynamic_pointer_cast(_itemEntity); + + random->setSeed(187); + shared_ptr item = itemEntity->getItem(); + + glPushMatrix(); + float bob = Mth::sin((itemEntity->age + a) / 10.0f + itemEntity->bobOffs) * 0.1f + 0.1f; + float spin = ((itemEntity->age + a) / 20.0f + itemEntity->bobOffs) * Mth::RADDEG; + + int count = 1; + if (itemEntity->getItem()->count > 1) count = 2; + if (itemEntity->getItem()->count > 5) count = 3; + if (itemEntity->getItem()->count > 20) count = 4; + + glTranslatef((float) x, (float) y + bob, (float) z); + glEnable(GL_RESCALE_NORMAL); + + Tile *tile = Tile::tiles[item->id]; + if (item->getIconType() == Icon::TYPE_TERRAIN && tile != NULL && TileRenderer::canRender(tile->getRenderShape())) + { + glRotatef(spin, 0, 1, 0); + + if (m_bItemFrame) + { + glScalef(1.25f, 1.25f, 1.25f); + glTranslatef(0, 0.05f, 0); + glRotatef(-90, 0, 1, 0); + } + + bindTexture(TN_TERRAIN); // 4J was L"/terrain.png" + float s = 1 / 4.0f; + int shape = tile->getRenderShape(); + if (shape == Tile::SHAPE_CROSS_TEXTURE || shape == Tile::SHAPE_STEM || shape == Tile::SHAPE_LEVER || shape == Tile::SHAPE_TORCH ) + { + s = 0.5f; + } + + glScalef(s, s, s); + for (int i = 0; i < count; i++) + { + glPushMatrix(); + if (i > 0) + { + float xo = (random->nextFloat() * 2 - 1) * 0.2f / s; + float yo = (random->nextFloat() * 2 - 1) * 0.2f / s; + float zo = (random->nextFloat() * 2 - 1) * 0.2f / s; + glTranslatef(xo, yo, zo); + } + // 4J - change brought forward from 1.8.2 + float br = SharedConstants::TEXTURE_LIGHTING ? 1.0f : itemEntity->getBrightness(a); + tileRenderer->renderTile(tile, item->getAuxValue(), br); + glPopMatrix(); + } + } + else if (item->getItem()->hasMultipleSpriteLayers()) + { + if (m_bItemFrame) + { + glScalef(1 / 1.95f, 1 / 1.95f, 1 / 1.95f); + glTranslatef(0, -0.05f, 0); + glDisable(GL_LIGHTING); + } + else + { + glScalef(1 / 2.0f, 1 / 2.0f, 1 / 2.0f); + } + + bindTexture(TN_GUI_ITEMS); // 4J was "/gui/items.png" + + for (int layer = 0; layer <= 1; layer++) + { + random->setSeed(187); + Icon *icon = item->getItem()->getLayerIcon(item->getAuxValue(), layer); + float brightness = SharedConstants::TEXTURE_LIGHTING ? 1 : itemEntity->getBrightness(a); + if (setColor) + { + int col = Item::items[item->id]->getColor(item, layer); + float red = ((col >> 16) & 0xff) / 255.0f; + float g = ((col >> 8) & 0xff) / 255.0f; + float b = ((col) & 0xff) / 255.0f; + + glColor4f(red * brightness, g * brightness, b * brightness, 1); + renderItemBillboard(itemEntity, icon, count, a, red * brightness, g * brightness, b * brightness); + } + else + { + renderItemBillboard(itemEntity, icon, count, a, 1, 1, 1); + } + } + } + else + { + if (m_bItemFrame) + { + glScalef(1 / 1.95f, 1 / 1.95f, 1 / 1.95f); + glTranslatef(0, -0.05f, 0); + glDisable(GL_LIGHTING); + } + else + { + glScalef(1 / 2.0f, 1 / 2.0f, 1 / 2.0f); + } + + // 4J Stu - For rendering the static compass, we give it a non-zero aux value + if(item->id == Item::compass_Id) item->setAuxValue(255); + Icon *icon = item->getIcon(); + if(item->id == Item::compass_Id) item->setAuxValue(0); + if (item->getIconType() == Icon::TYPE_TERRAIN) + { + bindTexture(TN_TERRAIN); // 4J was L"/terrain.png" + } + else + { + bindTexture(TN_GUI_ITEMS); // 4J was L"/gui/items.png" + } + if (setColor) + { + int col = Item::items[item->id]->getColor(item,0); + float red = ((col >> 16) & 0xff) / 255.0f; + float g = ((col >> 8) & 0xff) / 255.0f; + float b = ((col) & 0xff) / 255.0f; + float brightness = SharedConstants::TEXTURE_LIGHTING ? 1 : itemEntity->getBrightness(a); + + glColor4f(red * brightness, g * brightness, b * brightness, 1); + renderItemBillboard(itemEntity, icon, count, a, red * brightness, g * brightness, b * brightness); + } + else + { + renderItemBillboard(itemEntity, icon, count, a, 1, 1, 1); + } + + } + glDisable(GL_RESCALE_NORMAL); + glPopMatrix(); + if( m_bItemFrame ) + { + glEnable(GL_LIGHTING); + } +} + +void ItemRenderer::renderItemBillboard(shared_ptr entity, Icon *icon, int count, float a, float red, float green, float blue) +{ + Tesselator *t = Tesselator::getInstance(); + + if (icon == NULL) icon = entityRenderDispatcher->textures->getMissingIcon(entity->getItem()->getIconType()); + float u0 = icon->getU0(); + float u1 = icon->getU1(); + float v0 = icon->getV0(); + float v1 = icon->getV1(); + + float r = 1.0f; + float xo = 0.5f; + float yo = 0.25f; + + if (entityRenderDispatcher->options->fancyGraphics) + { + // Consider forcing the mipmap LOD level to use, if this is to be rendered from a larger than standard source texture. + int iconWidth = icon->getWidth(); + int LOD = -1; // Default to not doing anything special with LOD forcing + if( iconWidth == 32 ) + { + LOD = 1; // Force LOD level 1 to achieve texture reads from 256x256 map + } + else if( iconWidth == 64 ) + { + LOD = 2; // Force LOD level 2 to achieve texture reads from 256x256 map + } + RenderManager.StateSetForceLOD(LOD); + + glPushMatrix(); + if (m_bItemFrame) + { + glRotatef(180, 0, 1, 0); + } + else + { + glRotatef(((entity->age + a) / 20.0f + entity->bobOffs) * Mth::RADDEG, 0, 1, 0); + } + + float width = 1 / 16.0f; + float margin = 0.35f / 16.0f; + shared_ptr item = entity->getItem(); + int items = item->count; + + if (items < 2) + { + count = 1; + } + else if (items < 16) + { + count = 2; + } + else if (items < 32) + { + count = 3; + } + else + { + count = 4; + } + + glTranslatef(-xo, -yo, -((width + margin) * count / 2)); + + for (int i = 0; i < count; i++) + { + glTranslatef(0, 0, width + margin); + if (item->getIconType() == Icon::TYPE_TERRAIN && Tile::tiles[item->id] != NULL) + { + bindTexture(TN_TERRAIN); // Was L"/terrain.png"); + } + else + { + bindTexture(TN_GUI_ITEMS); //L"/gui/items.png"); + } + glColor4f(red, green, blue, 1); + // 4J Stu - u coords were swapped in Java + //ItemInHandRenderer::renderItem3D(t, u1, v0, u0, v1, icon->getSourceWidth(), icon->getSourceHeight(), width, false); + ItemInHandRenderer::renderItem3D(t, u0, v0, u1, v1, icon->getSourceWidth(), icon->getSourceHeight(), width, false); + + if (item != NULL && item->isFoil()) + { + glDepthFunc(GL_EQUAL); + glDisable(GL_LIGHTING); + entityRenderDispatcher->textures->bindTexture(TN__BLUR__MISC_GLINT); // was L"%blur%/misc/glint.png"); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_COLOR, GL_ONE); + float br = 0.76f; + glColor4f(0.5f * br, 0.25f * br, 0.8f * br, 1); + glMatrixMode(GL_TEXTURE); + glPushMatrix(); + float ss = 1 / 8.0f; + glScalef(ss, ss, ss); + float sx = Minecraft::currentTimeMillis() % (3000) / (3000.0f) * 8; + glTranslatef(sx, 0, 0); + glRotatef(-50, 0, 0, 1); + + ItemInHandRenderer::renderItem3D(t, 0, 0, 1, 1, 255, 255, width, true); + glPopMatrix(); + glPushMatrix(); + glScalef(ss, ss, ss); + sx = Minecraft::currentTimeMillis() % (3000 + 1873) / (3000 + 1873.0f) * 8; + glTranslatef(-sx, 0, 0); + glRotatef(10, 0, 0, 1); + ItemInHandRenderer::renderItem3D(t, 0, 0, 1, 1, 255, 255, width, true); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glDisable(GL_BLEND); + glEnable(GL_LIGHTING); + glDepthFunc(GL_LEQUAL); + } + } + + glPopMatrix(); + + RenderManager.StateSetForceLOD(-1); + } + else + { + for (int i = 0; i < count; i++) + { + glPushMatrix(); + if (i > 0) + { + float _xo = (random->nextFloat() * 2 - 1) * 0.3f; + float _yo = (random->nextFloat() * 2 - 1) * 0.3f; + float _zo = (random->nextFloat() * 2 - 1) * 0.3f; + glTranslatef(_xo, _yo, _zo); + } + if (!m_bItemFrame) glRotatef(180 - entityRenderDispatcher->playerRotY, 0, 1, 0); + glColor4f(red, green, blue, 1); + t->begin(); + t->normal(0, 1, 0); + t->vertexUV((float)(0 - xo), (float)( 0 - yo), (float)( 0), (float)( u0), (float)( v1)); + t->vertexUV((float)(r - xo), (float)( 0 - yo), (float)( 0), (float)( u1), (float)( v1)); + t->vertexUV((float)(r - xo), (float)( 1 - yo), (float)( 0), (float)( u1), (float)( v0)); + t->vertexUV((float)(0 - xo), (float)( 1 - yo), (float)( 0), (float)( u0), (float)( v0)); + t->end(); + + glPopMatrix(); + } +} +} + +void ItemRenderer::renderGuiItem(Font *font, Textures *textures, shared_ptr item, float x, float y, float fScale, float fAlpha) +{ + renderGuiItem(font,textures,item,x,y,fScale,fScale,fAlpha, true); +} + +#ifdef _XBOX +extern IDirect3DDevice9 *g_pD3DDevice; +#endif + +// 4J - this used to take x and y as ints, and no scale and alpha - but this interface is now implemented as a wrapper round this more fully featured one +void ItemRenderer::renderGuiItem(Font *font, Textures *textures, shared_ptr item, float x, float y, float fScaleX,float fScaleY, float fAlpha, bool useCompiled) +{ + int itemId = item->id; + int itemAuxValue = item->getAuxValue(); + Icon *itemIcon = item->getIcon(); + + if (item->getIconType() == Icon::TYPE_TERRAIN && TileRenderer::canRender(Tile::tiles[itemId]->getRenderShape())) + { + PIXBeginNamedEvent(0,"3D gui item render %d\n",itemId); + MemSect(31); + textures->bindTexture(TN_TERRAIN);//L"/terrain.png")); + MemSect(0); + + Tile *tile = Tile::tiles[itemId]; + glPushMatrix(); + // 4J - original code left here for reference +#if 0 + glTranslatef((float)(x), (float)(y), 0.0f); + glScalef(fScale, fScale, fScale); + glTranslatef(-2.0f,3.0f, -3.0f + blitOffset); + glScalef(10.0f, 10.0f, 10.0f); + glTranslatef(1.0f, 0.5f, 8.0f); + glScalef(1.0f, 1.0f, -1.0f); + glRotatef(180.0f + 30.0f, 1.0f, 0.0f, 0.0f); + glRotatef(45.0f, 0.0f, 1.0f, 0.0f); +#else + glTranslatef(x, y, 0.0f); // Translate to screen coords + glScalef(16.0f*fScaleX, 16.0f*fScaleY, 1.0f); // Scale to 0 to 16*scale range + glTranslatef(0.5f,0.5f,0.0f); // Translate to 0 to 1 range + glScalef(0.55f,0.55f, -1.0f); // Scale to occupy full -0.5 to 0.5 bounding region (just touching top & bottom) + // 0.55 comes from 1/(1+sqrt(2)/sqrt(3)) which is determined by the angles that the cube is rotated in an orthographic projection + glRotatef(180.0f + 30.0f, 1.0f, 0.0f, 0.0f); // Rotate round x axis (centre at origin) + glRotatef(45.0f, 0.0f, 1.0f, 0.0f); // Rotate round y axis (centre at origin) +#endif + // 4J-PB - pass the alpha value in - the grass block render has the top surface coloured differently to the rest of the block + glRotatef(-90.0f, 0.0f, 1.0f, 0.0f); + tileRenderer->renderTile(tile, itemAuxValue, 1, fAlpha, useCompiled); + + glPopMatrix(); + PIXEndNamedEvent(); + } + else if (Item::items[itemId]->hasMultipleSpriteLayers()) + { + PIXBeginNamedEvent(0,"Potion gui item render %d\n",itemIcon); + // special double-layered + glDisable(GL_LIGHTING); + textures->bindTexture(TN_GUI_ITEMS); // "/gui/items.png" + + for (int layer = 0; layer <= 1; layer++) + { + Icon *fillingIcon = Item::items[itemId]->getLayerIcon(itemAuxValue, layer); + + int col = Item::items[itemId]->getColor(item, layer); + float r = ((col >> 16) & 0xff) / 255.0f; + float g = ((col >> 8) & 0xff) / 255.0f; + float b = ((col) & 0xff) / 255.0f; + + if (setColor) glColor4f(r, g, b, fAlpha); + // scale the x and y by the scale factor + if((fScaleX!=1.0f) ||(fScaleY!=1.0f)) + { + blit(x, y, fillingIcon, 16 * fScaleX, 16 * fScaleY); + } + else + { + blit((int)x, (int)y, fillingIcon, 16, 16); + } + } + glEnable(GL_LIGHTING); + PIXEndNamedEvent(); + } + else + { + PIXBeginNamedEvent(0,"2D gui item render %d\n",itemIcon); + glDisable(GL_LIGHTING); + MemSect(31); + if (item->getIconType() == Icon::TYPE_TERRAIN) + { + textures->bindTexture(TN_TERRAIN);//L"/terrain.png")); + } + else + { + textures->bindTexture(TN_GUI_ITEMS);//L"/gui/items.png")); +#ifdef _XBOX + // 4J - make sure we've got linear sampling on minification here as non-mipmapped things like this currently + // default to having point sampling, which makes very small icons render rather badly + g_pD3DDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR ); +#endif + + } + MemSect(0); + + if (itemIcon == NULL) + { + itemIcon = textures->getMissingIcon(item->getIconType()); + } + + int col = Item::items[itemId]->getColor(item,0); + float r = ((col >> 16) & 0xff) / 255.0f; + float g = ((col >> 8) & 0xff) / 255.0f; + float b = ((col) & 0xff) / 255.0f; + + if (setColor) glColor4f(r, g, b, fAlpha); + + // scale the x and y by the scale factor + if((fScaleX!=1.0f) ||(fScaleY!=1.0f)) + { + blit(x, y, itemIcon, 16 * fScaleX, 16 * fScaleY); + } + else + { + blit((int)x, (int)y, itemIcon, 16, 16); + } + glEnable(GL_LIGHTING); + PIXEndNamedEvent(); + + } + glEnable(GL_CULL_FACE); + +} + +// 4J - original interface, now just a wrapper for preceding overload +void ItemRenderer::renderGuiItem(Font *font, Textures *textures, shared_ptr item, int x, int y) +{ + renderGuiItem(font, textures, item, (float)x, (float)y, 1.0f, 1.0f ); +} + +// 4J - this used to take x and y as ints, and no scale, alpha or foil - but this interface is now implemented as a wrapper round this more fully featured one +void ItemRenderer::renderAndDecorateItem(Font *font, Textures *textures, const shared_ptr item, float x, float y,float fScale,float fAlpha, bool isFoil) +{ + if(item==NULL) return; + renderAndDecorateItem(font, textures, item, x, y,fScale, fScale, fAlpha, isFoil, true); +} + +// 4J - added isConstantBlended and blendFactor parameters. This is true if the gui item is being rendered from a context where it already has blending enabled to do general interface fading +// (ie from the gui rather than xui). In this case we dno't want to enable/disable blending, and do need to restore the blend state when we are done. +void ItemRenderer::renderAndDecorateItem(Font *font, Textures *textures, const shared_ptr item, float x, float y,float fScaleX, float fScaleY,float fAlpha, bool isFoil, bool isConstantBlended, bool useCompiled) +{ + if (item == NULL) + { + return; + } + + renderGuiItem(font, textures, item, x, y,fScaleX,fScaleY,fAlpha, useCompiled); + + if (isFoil || item->isFoil()) + { + glDepthFunc(GL_GREATER); + glDisable(GL_LIGHTING); + glDepthMask(false); + textures->bindTexture(TN__BLUR__MISC_GLINT); // 4J was "%blur%/misc/glint.png" + blitOffset -= 50; + if( !isConstantBlended ) glEnable(GL_BLEND); + + glBlendFunc(GL_DST_COLOR, GL_ONE); // 4J - changed blend equation from GL_DST_COLOR, GL_DST_COLOR so we can fade this out + + float blendFactor = isConstantBlended ? Gui::currentGuiBlendFactor : 1.0f; + + glColor4f(0.5f * blendFactor, 0.25f * blendFactor, 0.8f * blendFactor, 1); // 4J - scale back colourisation with blendFactor + // scale the x and y by the scale factor + if((fScaleX!=1.0f) ||(fScaleY!=1.0f)) + { + // 4J Stu - Scales were multiples of 20, making 16 to not overlap in xui scenes + blitGlint(x * 431278612 + y * 32178161, x - 2, y - 2, 16 * fScaleX, 16 * fScaleY); + } + else + { + blitGlint(x * 431278612 + y * 32178161, x - 2, y - 2, 20, 20); + } + glColor4f(1.0f, 1.0f, 1.0f, 1); // 4J added + if( !isConstantBlended ) glDisable(GL_BLEND); + + glDepthMask(true); + blitOffset += 50; + glEnable(GL_LIGHTING); + glDepthFunc(GL_LEQUAL); + + if( isConstantBlended ) glBlendFunc(GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA); + } +} + +// 4J - original interface, now just a wrapper for preceding overload +void ItemRenderer::renderAndDecorateItem(Font *font, Textures *textures, const shared_ptr item, int x, int y) +{ + renderAndDecorateItem( font, textures, item, (float)x, (float)y, 1.0f, 1.0f, item->isFoil() ); +} + +// 4J - a few changes here to get x, y, w, h in as floats (for xui rendering accuracy), and to align +// final pixels to the final screen resolution +void ItemRenderer::blitGlint(int id, float x, float y, float w, float h) +{ + float us = 1.0f / 64.0f / 4; + float vs = 1.0f / 64.0f / 4; + + // 4J - calculate what the pixel coordinates will be in final screen coordinates + float sfx = (float)Minecraft::GetInstance()->width / (float)Minecraft::GetInstance()->width_phys; + float sfy = (float)Minecraft::GetInstance()->height / (float)Minecraft::GetInstance()->height_phys; + float xx0 = x * sfx; + float xx1 = ( x + w ) * sfx; + float yy0 = y * sfy; + float yy1 = ( y + h ) * sfy; + // Round to whole pixels - rounding inwards so that we don't overlap any surrounding graphics + xx0 = ceilf(xx0); + xx1 = floorf(xx1); + yy0 = ceilf(yy0); + yy1 = floorf(yy1); + // Offset by half to get actual centre of pixel - again moving inwards to avoid overlap with surrounding graphics + xx0 += 0.5f; + xx1 -= 0.5f; + yy0 += 0.5f; + yy1 -= 0.5f; + // Convert back to game coordinate space + float xx0f = xx0 / sfx; + float xx1f = xx1 / sfx; + float yy0f = yy0 / sfy; + float yy1f = yy1 / sfy; + + for (int i = 0; i < 2; i++) + { + if (i == 0) glBlendFunc(GL_SRC_COLOR, GL_ONE); + if (i == 1) glBlendFunc(GL_SRC_COLOR, GL_ONE); + float sx = Minecraft::currentTimeMillis() % (3000 + i * 1873) / (3000.0f + i * 1873) * 256; + float sy = 0; + Tesselator *t = Tesselator::getInstance(); + float vv = 4; + if (i == 1) vv = -1; + t->begin(); + t->vertexUV(xx0f, yy1f, blitOffset, (sx + h * vv) * us, (sy + h) * vs); + t->vertexUV(xx1f, yy1f, blitOffset, (sx + w + h * vv) * us, (sy + h) * vs); + t->vertexUV(xx1f, yy0f, blitOffset, (sx + w) * us, (sy + 0) * vs); + t->vertexUV(xx0f, yy0f, blitOffset, (sx + 0) * us, (sy + 0) * vs); + t->end(); + } +} + +void ItemRenderer::renderGuiItemDecorations(Font *font, Textures *textures, shared_ptr item, int x, int y, float fAlpha) +{ + renderGuiItemDecorations(font, textures, item, x, y, L"", fAlpha); +} + +void ItemRenderer::renderGuiItemDecorations(Font *font, Textures *textures, shared_ptr item, int x, int y, const wstring &countText, float fAlpha) +{ + if (item == NULL) + { + return; + } + + glEnable(GL_BLEND); + RenderManager.StateSetBlendFactor(0xffffff |(((unsigned int)(fAlpha * 0xff))<<24)); + glBlendFunc(GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA); + if (item->count > 1 || !countText.empty() || item->GetForceNumberDisplay()) + { + MemSect(31); + wstring amount = countText; + if(amount.empty()) + { + int count = item->count; + if(count > 64) + { + amount = _toString(64) + L"+"; + } + else + { + amount = _toString(item->count); + } + } + MemSect(0); + glDisable(GL_LIGHTING); + glDisable(GL_DEPTH_TEST); + font->drawShadow(amount, x + 19 - 2 - font->width(amount), y + 6 + 3, 0xffffff); + glEnable(GL_LIGHTING); + glEnable(GL_DEPTH_TEST); + } + + if (item->isDamaged()) + { + int p = (int) Math::round(13.0 - (double) item->getDamageValue() * 13.0 / (double) item->getMaxDamage()); + int cc = (int) Math::round(255.0 - (double) item->getDamageValue() * 255.0 / (double) item->getMaxDamage()); + glDisable(GL_LIGHTING); + glDisable(GL_DEPTH_TEST); + glDisable(GL_TEXTURE_2D); + + Tesselator *t = Tesselator::getInstance(); + + int ca = (255 - cc) << 16 | (cc) << 8; + int cb = ((255 - cc) / 4) << 16 | (255 / 4) << 8; + fillRect(t, x + 2, y + 13, 13, 2, 0x000000); + fillRect(t, x + 2, y + 13, 12, 1, cb); + fillRect(t, x + 2, y + 13, p, 1, ca); + + glEnable(GL_TEXTURE_2D); + glEnable(GL_LIGHTING); + glEnable(GL_DEPTH_TEST); + glColor4f(1, 1, 1, 1); + } + else if(item->hasPotionStrengthBar()) + { + glDisable(GL_LIGHTING); + glDisable(GL_DEPTH_TEST); + glDisable(GL_TEXTURE_2D); + + Tesselator *t = Tesselator::getInstance(); + + fillRect(t, x + 3, y + 13, 11, 2, 0x000000); + //fillRect(t, x + 2, y + 13, 13, 1, 0x1dabc0); + fillRect(t, x + 3, y + 13, m_iPotionStrengthBarWidth[item->GetPotionStrength()], 2, 0x00e1eb); + fillRect(t, x + 2 + 3, y + 13, 1, 2, 0x000000); + fillRect(t, x + 2 + 3+3, y + 13, 1, 2, 0x000000); + fillRect(t, x + 2 + 3+3+3, y + 13, 1, 2, 0x000000); + + + glEnable(GL_TEXTURE_2D); + glEnable(GL_LIGHTING); + glEnable(GL_DEPTH_TEST); + glColor4f(1, 1, 1, 1); + } + glDisable(GL_BLEND); +} + +const int ItemRenderer::m_iPotionStrengthBarWidth[]= +{ + 3,6,9,11 +}; + +void ItemRenderer::fillRect(Tesselator *t, int x, int y, int w, int h, int c) +{ + t->begin(); + t->color(c); + t->vertex((float)(x + 0), (float)( y + 0), (float)( 0)); + t->vertex((float)(x + 0), (float)( y + h), (float)( 0)); + t->vertex((float)(x + w), (float)( y + h), (float)( 0)); + t->vertex((float)(x + w), (float)( y + 0), (float)( 0)); + t->end(); +} + +// 4J - a few changes here to get x, y, w, h in as floats (for xui rendering accuracy), and to align +// final pixels to the final screen resolution +void ItemRenderer::blit(float x, float y, int sx, int sy, float w, float h) +{ + float us = 1 / 256.0f; + float vs = 1 / 256.0f; + Tesselator *t = Tesselator::getInstance(); + t->begin(); + + // 4J - calculate what the pixel coordinates will be in final screen coordinates + float sfx = (float)Minecraft::GetInstance()->width / (float)Minecraft::GetInstance()->width_phys; + float sfy = (float)Minecraft::GetInstance()->height / (float)Minecraft::GetInstance()->height_phys; + float xx0 = x * sfx; + float xx1 = ( x + w ) * sfx; + float yy0 = y * sfy; + float yy1 = ( y + h ) * sfy; + // Round to whole pixels - rounding inwards so that we don't overlap any surrounding graphics + xx0 = ceilf(xx0); + xx1 = floorf(xx1); + yy0 = ceilf(yy0); + yy1 = floorf(yy1); + // Offset by half to get actual centre of pixel - again moving inwards to avoid overlap with surrounding graphics + xx0 += 0.5f; + xx1 -= 0.5f; + yy0 += 0.5f; + yy1 -= 0.5f; + // Convert back to game coordinate space + float xx0f = xx0 / sfx; + float xx1f = xx1 / sfx; + float yy0f = yy0 / sfy; + float yy1f = yy1 / sfy; + + // 4J - subtracting 0.5f (actual screen pixels, so need to compensate for physical & game width) from each x & y coordinate to compensate for centre of pixels in directx vs openGL + float f = ( 0.5f * (float)Minecraft::GetInstance()->width ) / (float)Minecraft::GetInstance()->width_phys; + + t->vertexUV(xx0f, yy1f, (float)( blitOffset), (float)( (sx + 0) * us), (float)( (sy + 16) * vs)); + t->vertexUV(xx1f, yy1f, (float)( blitOffset), (float)( (sx + 16) * us), (float)( (sy + 16) * vs)); + t->vertexUV(xx1f, yy0f, (float)( blitOffset), (float)( (sx + 16) * us), (float)( (sy + 0) * vs)); + t->vertexUV(xx0f, yy0f, (float)( blitOffset), (float)( (sx + 0) * us), (float)( (sy + 0) * vs)); + t->end(); +} + +void ItemRenderer::blit(float x, float y, Icon *tex, float w, float h) +{ + Tesselator *t = Tesselator::getInstance(); + t->begin(); + + // 4J - calculate what the pixel coordinates will be in final screen coordinates + float sfx = (float)Minecraft::GetInstance()->width / (float)Minecraft::GetInstance()->width_phys; + float sfy = (float)Minecraft::GetInstance()->height / (float)Minecraft::GetInstance()->height_phys; + float xx0 = x * sfx; + float xx1 = ( x + w ) * sfx; + float yy0 = y * sfy; + float yy1 = ( y + h ) * sfy; + // Round to whole pixels - rounding inwards so that we don't overlap any surrounding graphics + xx0 = ceilf(xx0); + xx1 = floorf(xx1); + yy0 = ceilf(yy0); + yy1 = floorf(yy1); + // Offset by half to get actual centre of pixel - again moving inwards to avoid overlap with surrounding graphics + xx0 += 0.5f; + xx1 -= 0.5f; + yy0 += 0.5f; + yy1 -= 0.5f; + // Convert back to game coordinate space + float xx0f = xx0 / sfx; + float xx1f = xx1 / sfx; + float yy0f = yy0 / sfy; + float yy1f = yy1 / sfy; + + // 4J - subtracting 0.5f (actual screen pixels, so need to compensate for physical & game width) from each x & y coordinate to compensate for centre of pixels in directx vs openGL + float f = ( 0.5f * (float)Minecraft::GetInstance()->width ) / (float)Minecraft::GetInstance()->width_phys; + + t->vertexUV(xx0f, yy1f, blitOffset, tex->getU0(true), tex->getV1(true)); + t->vertexUV(xx1f, yy1f, blitOffset, tex->getU1(true), tex->getV1(true)); + t->vertexUV(xx1f, yy0f, blitOffset, tex->getU1(true), tex->getV0(true)); + t->vertexUV(xx0f, yy0f, blitOffset, tex->getU0(true), tex->getV0(true)); + t->end(); +} -- cgit v1.2.3