the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
1#include "stdafx.h"
2#include "ItemRenderer.h"
3#include "TileRenderer.h"
4#include "entityRenderDispatcher.h"
5#include "..\Minecraft.World\JavaMath.h"
6#include "..\Minecraft.World\net.minecraft.world.entity.item.h"
7#include "..\Minecraft.World\net.minecraft.world.item.h"
8#include "..\Minecraft.World\net.minecraft.world.item.alchemy.h"
9#include "..\Minecraft.World\net.minecraft.world.level.tile.h"
10#include "..\Minecraft.World\StringHelpers.h"
11#include "..\Minecraft.World\net.minecraft.world.h"
12#include "Options.h"
13#include "TextureAtlas.h"
14
15#ifdef _XBOX
16extern IDirect3DDevice9 *g_pD3DDevice;
17#endif
18
19ItemRenderer::ItemRenderer() : EntityRenderer()
20{
21 random = new Random();
22 setColor = true;
23 blitOffset = 0;
24
25 shadowRadius = 0.15f;
26 shadowStrength = 0.75f;
27
28 // 4J added
29 m_bItemFrame= false;
30}
31
32ItemRenderer::~ItemRenderer()
33{
34 delete random;
35}
36
37ResourceLocation *ItemRenderer::getTextureLocation(shared_ptr<Entity> entity)
38{
39 shared_ptr<ItemEntity> itemEntity = dynamic_pointer_cast<ItemEntity>(entity);
40 return getTextureLocation(itemEntity->getItem()->getIconType());
41}
42
43ResourceLocation *ItemRenderer::getTextureLocation(int iconType)
44{
45 if (iconType == Icon::TYPE_TERRAIN)
46 {
47 return &TextureAtlas::LOCATION_BLOCKS;//L"/terrain.png"));
48 }
49 else
50 {
51#ifdef _XBOX
52 // 4J - make sure we've got linear sampling on minification here as non-mipmapped things like this currently
53 // default to having point sampling, which makes very small icons render rather badly
54 g_pD3DDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
55#endif
56 return &TextureAtlas::LOCATION_ITEMS;//L"/gui/items.png"));
57 }
58}
59
60void ItemRenderer::render(shared_ptr<Entity> _itemEntity, double x, double y, double z, float rot, float a)
61{
62 // 4J - dynamic cast required because we aren't using templates/generics in our version
63 shared_ptr<ItemEntity> itemEntity = dynamic_pointer_cast<ItemEntity>(_itemEntity);
64 bindTexture(itemEntity);
65
66 random->setSeed(187);
67 shared_ptr<ItemInstance> item = itemEntity->getItem();
68 if (item->getItem() == NULL) return;
69
70 glPushMatrix();
71 float bob = Mth::sin((itemEntity->age + a) / 10.0f + itemEntity->bobOffs) * 0.1f + 0.1f;
72 float spin = ((itemEntity->age + a) / 20.0f + itemEntity->bobOffs) * Mth::RADDEG;
73
74 int count = 1;
75 if (itemEntity->getItem()->count > 1) count = 2;
76 if (itemEntity->getItem()->count > 5) count = 3;
77 if (itemEntity->getItem()->count > 20) count = 4;
78 if (itemEntity->getItem()->count > 40) count = 5;
79
80 glTranslatef((float) x, (float) y + bob, (float) z);
81 glEnable(GL_RESCALE_NORMAL);
82
83 Tile *tile = Tile::tiles[item->id];
84
85 if (item->getIconType() == Icon::TYPE_TERRAIN && tile != NULL && TileRenderer::canRender(tile->getRenderShape()))
86 {
87 glRotatef(spin, 0, 1, 0);
88
89 if (m_bItemFrame)
90 {
91 glScalef(1.25f, 1.25f, 1.25f);
92 glTranslatef(0, 0.05f, 0);
93 glRotatef(-90, 0, 1, 0);
94 }
95
96 float s = 1 / 4.0f;
97 int shape = tile->getRenderShape();
98 if (shape == Tile::SHAPE_CROSS_TEXTURE || shape == Tile::SHAPE_STEM || shape == Tile::SHAPE_LEVER || shape == Tile::SHAPE_TORCH )
99 {
100 s = 0.5f;
101 }
102
103 glScalef(s, s, s);
104 for (int i = 0; i < count; i++)
105 {
106 glPushMatrix();
107 if (i > 0)
108 {
109 float xo = (random->nextFloat() * 2 - 1) * 0.2f / s;
110 float yo = (random->nextFloat() * 2 - 1) * 0.2f / s;
111 float zo = (random->nextFloat() * 2 - 1) * 0.2f / s;
112 glTranslatef(xo, yo, zo);
113 }
114 // 4J - change brought forward from 1.8.2
115 float br = SharedConstants::TEXTURE_LIGHTING ? 1.0f : itemEntity->getBrightness(a);
116 tileRenderer->renderTile(tile, item->getAuxValue(), br);
117 glPopMatrix();
118 }
119 }
120 else if (item->getIconType() == Icon::TYPE_ITEM && item->getItem()->hasMultipleSpriteLayers())
121 {
122 if (m_bItemFrame)
123 {
124 glScalef(1 / 1.95f, 1 / 1.95f, 1 / 1.95f);
125 glTranslatef(0, -0.05f, 0);
126 glDisable(GL_LIGHTING);
127 }
128 else
129 {
130 glScalef(1 / 2.0f, 1 / 2.0f, 1 / 2.0f);
131 }
132
133 bindTexture(&TextureAtlas::LOCATION_ITEMS); // 4J was "/gui/items.png"
134
135 for (int layer = 0; layer <= 1; layer++)
136 {
137 random->setSeed(187);
138 Icon *icon = item->getItem()->getLayerIcon(item->getAuxValue(), layer);
139 float brightness = SharedConstants::TEXTURE_LIGHTING ? 1 : itemEntity->getBrightness(a);
140 if (setColor)
141 {
142 int col = Item::items[item->id]->getColor(item, layer);
143 float red = ((col >> 16) & 0xff) / 255.0f;
144 float g = ((col >> 8) & 0xff) / 255.0f;
145 float b = ((col) & 0xff) / 255.0f;
146
147 glColor4f(red * brightness, g * brightness, b * brightness, 1);
148 renderItemBillboard(itemEntity, icon, count, a, red * brightness, g * brightness, b * brightness);
149 }
150 else
151 {
152 renderItemBillboard(itemEntity, icon, count, a, 1, 1, 1);
153 }
154 }
155 }
156 else
157 {
158 if (m_bItemFrame)
159 {
160 glScalef(1 / 1.95f, 1 / 1.95f, 1 / 1.95f);
161 glTranslatef(0, -0.05f, 0);
162 glDisable(GL_LIGHTING);
163 }
164 else
165 {
166 glScalef(1 / 2.0f, 1 / 2.0f, 1 / 2.0f);
167 }
168
169 // 4J Stu - For rendering the static compass, we give it a non-zero aux value
170 if(item->id == Item::compass_Id) item->setAuxValue(255);
171 if(item->id == Item::compass_Id) item->setAuxValue(0);
172
173 Icon *icon = item->getIcon();
174 if (setColor)
175 {
176 int col = Item::items[item->id]->getColor(item,0);
177 float red = ((col >> 16) & 0xff) / 255.0f;
178 float g = ((col >> 8) & 0xff) / 255.0f;
179 float b = ((col) & 0xff) / 255.0f;
180 float brightness = SharedConstants::TEXTURE_LIGHTING ? 1 : itemEntity->getBrightness(a);
181
182 glColor4f(red * brightness, g * brightness, b * brightness, 1);
183 renderItemBillboard(itemEntity, icon, count, a, red * brightness, g * brightness, b * brightness);
184 }
185 else
186 {
187 renderItemBillboard(itemEntity, icon, count, a, 1, 1, 1);
188 }
189
190 }
191 glDisable(GL_RESCALE_NORMAL);
192 glPopMatrix();
193 if( m_bItemFrame )
194 {
195 glEnable(GL_LIGHTING);
196 }
197}
198
199void ItemRenderer::renderItemBillboard(shared_ptr<ItemEntity> entity, Icon *icon, int count, float a, float red, float green, float blue)
200{
201 Tesselator *t = Tesselator::getInstance();
202
203 if (icon == NULL) icon = entityRenderDispatcher->textures->getMissingIcon(entity->getItem()->getIconType());
204 float u0 = icon->getU0();
205 float u1 = icon->getU1();
206 float v0 = icon->getV0();
207 float v1 = icon->getV1();
208
209 float r = 1.0f;
210 float xo = 0.5f;
211 float yo = 0.25f;
212
213 if (entityRenderDispatcher->options->fancyGraphics)
214 {
215 // Consider forcing the mipmap LOD level to use, if this is to be rendered from a larger than standard source texture.
216 int iconWidth = icon->getWidth();
217 int LOD = -1; // Default to not doing anything special with LOD forcing
218 if( iconWidth == 32 )
219 {
220 LOD = 1; // Force LOD level 1 to achieve texture reads from 256x256 map
221 }
222 else if( iconWidth == 64 )
223 {
224 LOD = 2; // Force LOD level 2 to achieve texture reads from 256x256 map
225 }
226 RenderManager.StateSetForceLOD(LOD);
227
228 glPushMatrix();
229 if (m_bItemFrame)
230 {
231 glRotatef(180, 0, 1, 0);
232 }
233 else
234 {
235 glRotatef(((entity->age + a) / 20.0f + entity->bobOffs) * Mth::RADDEG, 0, 1, 0);
236 }
237
238 float width = 1 / 16.0f;
239 float margin = 0.35f / 16.0f;
240 shared_ptr<ItemInstance> item = entity->getItem();
241 int items = item->count;
242
243 if (items < 2)
244 {
245 count = 1;
246 }
247 else if (items < 16)
248 {
249 count = 2;
250 }
251 else if (items < 32)
252 {
253 count = 3;
254 }
255 else
256 {
257 count = 4;
258 }
259
260 glTranslatef(-xo, -yo, -((width + margin) * count / 2));
261
262 for (int i = 0; i < count; i++)
263 {
264 glTranslatef(0, 0, width + margin);
265
266 bool bIsTerrain = false;
267 if (item->getIconType() == Icon::TYPE_TERRAIN && Tile::tiles[item->id] != NULL)
268 {
269 bIsTerrain = true;
270 bindTexture(&TextureAtlas::LOCATION_BLOCKS); // TODO: Do this sanely by Icon
271 }
272 else
273 {
274 bindTexture(&TextureAtlas::LOCATION_ITEMS); // TODO: Do this sanely by Icon
275 }
276
277 glColor4f(red, green, blue, 1);
278 // 4J Stu - u coords were swapped in Java
279 //ItemInHandRenderer::renderItem3D(t, u1, v0, u0, v1, icon->getSourceWidth(), icon->getSourceHeight(), width, false);
280 ItemInHandRenderer::renderItem3D(t, u0, v0, u1, v1, icon->getSourceWidth(), icon->getSourceHeight(), width, false, bIsTerrain);
281
282 if (item != NULL && item->isFoil())
283 {
284 glDepthFunc(GL_EQUAL);
285 glDisable(GL_LIGHTING);
286 entityRenderDispatcher->textures->bindTexture(&ItemInHandRenderer::ENCHANT_GLINT_LOCATION);
287 glEnable(GL_BLEND);
288 glBlendFunc(GL_SRC_COLOR, GL_ONE);
289 float br = 0.76f;
290 glColor4f(0.5f * br, 0.25f * br, 0.8f * br, 1);
291 glMatrixMode(GL_TEXTURE);
292 glPushMatrix();
293 float ss = 1 / 8.0f;
294 glScalef(ss, ss, ss);
295 float sx = Minecraft::currentTimeMillis() % (3000) / (3000.0f) * 8;
296 glTranslatef(sx, 0, 0);
297 glRotatef(-50, 0, 0, 1);
298
299 ItemInHandRenderer::renderItem3D(t, 0, 0, 1, 1, 255, 255, width, true, bIsTerrain);
300 glPopMatrix();
301 glPushMatrix();
302 glScalef(ss, ss, ss);
303 sx = Minecraft::currentTimeMillis() % (3000 + 1873) / (3000 + 1873.0f) * 8;
304 glTranslatef(-sx, 0, 0);
305 glRotatef(10, 0, 0, 1);
306 ItemInHandRenderer::renderItem3D(t, 0, 0, 1, 1, 255, 255, width, true, bIsTerrain);
307 glPopMatrix();
308 glMatrixMode(GL_MODELVIEW);
309 glDisable(GL_BLEND);
310 glEnable(GL_LIGHTING);
311 glDepthFunc(GL_LEQUAL);
312 }
313 }
314
315 glPopMatrix();
316
317 RenderManager.StateSetForceLOD(-1);
318 }
319 else
320 {
321 for (int i = 0; i < count; i++)
322 {
323 glPushMatrix();
324 if (i > 0)
325 {
326 float _xo = (random->nextFloat() * 2 - 1) * 0.3f;
327 float _yo = (random->nextFloat() * 2 - 1) * 0.3f;
328 float _zo = (random->nextFloat() * 2 - 1) * 0.3f;
329 glTranslatef(_xo, _yo, _zo);
330 }
331 if (!m_bItemFrame) glRotatef(180 - entityRenderDispatcher->playerRotY, 0, 1, 0);
332 glColor4f(red, green, blue, 1);
333 t->begin();
334 t->normal(0, 1, 0);
335 t->vertexUV((float)(0 - xo), (float)( 0 - yo), (float)( 0), (float)( u0), (float)( v1));
336 t->vertexUV((float)(r - xo), (float)( 0 - yo), (float)( 0), (float)( u1), (float)( v1));
337 t->vertexUV((float)(r - xo), (float)( 1 - yo), (float)( 0), (float)( u1), (float)( v0));
338 t->vertexUV((float)(0 - xo), (float)( 1 - yo), (float)( 0), (float)( u0), (float)( v0));
339 t->end();
340
341 glPopMatrix();
342 }
343}
344}
345
346void ItemRenderer::renderGuiItem(Font *font, Textures *textures, shared_ptr<ItemInstance> item, float x, float y, float fScale, float fAlpha)
347{
348 renderGuiItem(font,textures,item,x,y,fScale,fScale,fAlpha, true);
349}
350
351// 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
352void ItemRenderer::renderGuiItem(Font *font, Textures *textures, shared_ptr<ItemInstance> item, float x, float y, float fScaleX,float fScaleY, float fAlpha, bool useCompiled)
353{
354 int itemId = item->id;
355 int itemAuxValue = item->getAuxValue();
356 Icon *itemIcon = item->getIcon();
357
358 if (item->getIconType() == Icon::TYPE_TERRAIN && TileRenderer::canRender(Tile::tiles[itemId]->getRenderShape()))
359 {
360 PIXBeginNamedEvent(0,"3D gui item render %d\n",itemId);
361 MemSect(31);
362 textures->bindTexture(&TextureAtlas::LOCATION_BLOCKS);
363 MemSect(0);
364
365 Tile *tile = Tile::tiles[itemId];
366 glPushMatrix();
367 // 4J - original code left here for reference
368#if 0
369 glTranslatef((float)(x), (float)(y), 0.0f);
370 glScalef(fScale, fScale, fScale);
371 glTranslatef(-2.0f,3.0f, -3.0f + blitOffset);
372 glScalef(10.0f, 10.0f, 10.0f);
373 glTranslatef(1.0f, 0.5f, 8.0f);
374 glScalef(1.0f, 1.0f, -1.0f);
375 glRotatef(180.0f + 30.0f, 1.0f, 0.0f, 0.0f);
376 glRotatef(45.0f, 0.0f, 1.0f, 0.0f);
377#else
378 glTranslatef(x, y, 0.0f); // Translate to screen coords
379 glScalef(16.0f*fScaleX, 16.0f*fScaleY, 1.0f); // Scale to 0 to 16*scale range
380 glTranslatef(0.5f,0.5f,0.0f); // Translate to 0 to 1 range
381 glScalef(0.55f,0.55f, -1.0f); // Scale to occupy full -0.5 to 0.5 bounding region (just touching top & bottom)
382 // 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
383 glRotatef(180.0f + 30.0f, 1.0f, 0.0f, 0.0f); // Rotate round x axis (centre at origin)
384 glRotatef(45.0f, 0.0f, 1.0f, 0.0f); // Rotate round y axis (centre at origin)
385#endif
386 // 4J-PB - pass the alpha value in - the grass block render has the top surface coloured differently to the rest of the block
387 glRotatef(-90.0f, 0.0f, 1.0f, 0.0f);
388 tileRenderer->renderTile(tile, itemAuxValue, 1, fAlpha, useCompiled);
389
390 glPopMatrix();
391 PIXEndNamedEvent();
392 }
393 else if (Item::items[itemId]->hasMultipleSpriteLayers())
394 {
395 PIXBeginNamedEvent(0,"Potion gui item render %d\n",itemIcon);
396 // special double-layered
397 glDisable(GL_LIGHTING);
398
399 ResourceLocation *location = getTextureLocation(item->getIconType());
400 textures->bindTexture(location);
401
402 for (int layer = 0; layer <= 1; layer++)
403 {
404 Icon *fillingIcon = Item::items[itemId]->getLayerIcon(itemAuxValue, layer);
405
406 int col = Item::items[itemId]->getColor(item, layer);
407 float r = ((col >> 16) & 0xff) / 255.0f;
408 float g = ((col >> 8) & 0xff) / 255.0f;
409 float b = ((col) & 0xff) / 255.0f;
410
411 if (setColor) glColor4f(r, g, b, fAlpha);
412 // scale the x and y by the scale factor
413 if((fScaleX!=1.0f) ||(fScaleY!=1.0f))
414 {
415 blit(x, y, fillingIcon, 16 * fScaleX, 16 * fScaleY);
416 }
417 else
418 {
419 blit((int)x, (int)y, fillingIcon, 16, 16);
420 }
421 }
422 glEnable(GL_LIGHTING);
423 PIXEndNamedEvent();
424 }
425 else
426 {
427 PIXBeginNamedEvent(0,"2D gui item render %d\n",itemIcon);
428 glDisable(GL_LIGHTING);
429 MemSect(31);
430 if (item->getIconType() == Icon::TYPE_TERRAIN)
431 {
432 textures->bindTexture(&TextureAtlas::LOCATION_BLOCKS);//L"/terrain.png"));
433 }
434 else
435 {
436 textures->bindTexture(&TextureAtlas::LOCATION_ITEMS);//L"/gui/items.png"));
437#ifdef _XBOX
438 // 4J - make sure we've got linear sampling on minification here as non-mipmapped things like this currently
439 // default to having point sampling, which makes very small icons render rather badly
440 g_pD3DDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
441#endif
442
443 }
444 MemSect(0);
445
446 if (itemIcon == NULL)
447 {
448 itemIcon = textures->getMissingIcon(item->getIconType());
449 }
450
451 int col = Item::items[itemId]->getColor(item,0);
452 float r = ((col >> 16) & 0xff) / 255.0f;
453 float g = ((col >> 8) & 0xff) / 255.0f;
454 float b = ((col) & 0xff) / 255.0f;
455
456 if (setColor) glColor4f(r, g, b, fAlpha);
457
458 // scale the x and y by the scale factor
459 if((fScaleX!=1.0f) ||(fScaleY!=1.0f))
460 {
461 blit(x, y, itemIcon, 16 * fScaleX, 16 * fScaleY);
462 }
463 else
464 {
465 blit((int)x, (int)y, itemIcon, 16, 16);
466 }
467 glEnable(GL_LIGHTING);
468 PIXEndNamedEvent();
469
470 }
471 glEnable(GL_CULL_FACE);
472
473}
474
475// 4J - original interface, now just a wrapper for preceding overload
476void ItemRenderer::renderGuiItem(Font *font, Textures *textures, shared_ptr<ItemInstance> item, int x, int y)
477{
478 renderGuiItem(font, textures, item, (float)x, (float)y, 1.0f, 1.0f );
479}
480
481// 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
482void ItemRenderer::renderAndDecorateItem(Font *font, Textures *textures, const shared_ptr<ItemInstance> item, float x, float y,float fScale,float fAlpha, bool isFoil)
483{
484 if(item==NULL) return;
485 renderAndDecorateItem(font, textures, item, x, y,fScale, fScale, fAlpha, isFoil, true);
486}
487
488// 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
489// (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.
490void ItemRenderer::renderAndDecorateItem(Font *font, Textures *textures, const shared_ptr<ItemInstance> item, float x, float y,float fScaleX, float fScaleY,float fAlpha, bool isFoil, bool isConstantBlended, bool useCompiled)
491{
492 if (item == NULL)
493 {
494 return;
495 }
496
497 renderGuiItem(font, textures, item, x, y,fScaleX,fScaleY,fAlpha, useCompiled);
498
499 if (isFoil || item->isFoil())
500 {
501 glDepthFunc(GL_GREATER);
502 glDisable(GL_LIGHTING);
503 glDepthMask(false);
504 textures->bindTexture(&ItemInHandRenderer::ENCHANT_GLINT_LOCATION); // 4J was "%blur%/misc/glint.png"
505 blitOffset -= 50;
506 if( !isConstantBlended ) glEnable(GL_BLEND);
507
508 glBlendFunc(GL_DST_COLOR, GL_ONE); // 4J - changed blend equation from GL_DST_COLOR, GL_DST_COLOR so we can fade this out
509
510 float blendFactor = isConstantBlended ? Gui::currentGuiBlendFactor : 1.0f;
511
512 glColor4f(0.5f * blendFactor, 0.25f * blendFactor, 0.8f * blendFactor, 1); // 4J - scale back colourisation with blendFactor
513 // scale the x and y by the scale factor
514 if((fScaleX!=1.0f) ||(fScaleY!=1.0f))
515 {
516 // 4J Stu - Scales were multiples of 20, making 16 to not overlap in xui scenes
517 blitGlint(x * 431278612 + y * 32178161, x - 2, y - 2, 16 * fScaleX, 16 * fScaleY);
518 }
519 else
520 {
521 blitGlint(x * 431278612 + y * 32178161, x - 2, y - 2, 20, 20);
522 }
523 glColor4f(1.0f, 1.0f, 1.0f, 1); // 4J added
524 if( !isConstantBlended ) glDisable(GL_BLEND);
525
526 glDepthMask(true);
527 blitOffset += 50;
528 glEnable(GL_LIGHTING);
529 glDepthFunc(GL_LEQUAL);
530
531 if( isConstantBlended ) glBlendFunc(GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA);
532 }
533}
534
535// 4J - original interface, now just a wrapper for preceding overload
536void ItemRenderer::renderAndDecorateItem(Font *font, Textures *textures, const shared_ptr<ItemInstance> item, int x, int y)
537{
538 renderAndDecorateItem( font, textures, item, (float)x, (float)y, 1.0f, 1.0f, item->isFoil() );
539}
540
541// 4J - a few changes here to get x, y, w, h in as floats (for xui rendering accuracy), and to align
542// final pixels to the final screen resolution
543void ItemRenderer::blitGlint(int id, float x, float y, float w, float h)
544{
545 float us = 1.0f / 64.0f / 4;
546 float vs = 1.0f / 64.0f / 4;
547
548 // 4J - calculate what the pixel coordinates will be in final screen coordinates
549 float sfx = (float)Minecraft::GetInstance()->width / (float)Minecraft::GetInstance()->width_phys;
550 float sfy = (float)Minecraft::GetInstance()->height / (float)Minecraft::GetInstance()->height_phys;
551 float xx0 = x * sfx;
552 float xx1 = ( x + w ) * sfx;
553 float yy0 = y * sfy;
554 float yy1 = ( y + h ) * sfy;
555 // Round to whole pixels - rounding inwards so that we don't overlap any surrounding graphics
556 xx0 = ceilf(xx0);
557 xx1 = floorf(xx1);
558 yy0 = ceilf(yy0);
559 yy1 = floorf(yy1);
560 // Offset by half to get actual centre of pixel - again moving inwards to avoid overlap with surrounding graphics
561 xx0 += 0.5f;
562 xx1 -= 0.5f;
563 yy0 += 0.5f;
564 yy1 -= 0.5f;
565 // Convert back to game coordinate space
566 float xx0f = xx0 / sfx;
567 float xx1f = xx1 / sfx;
568 float yy0f = yy0 / sfy;
569 float yy1f = yy1 / sfy;
570
571 for (int i = 0; i < 2; i++)
572 {
573 if (i == 0) glBlendFunc(GL_SRC_COLOR, GL_ONE);
574 if (i == 1) glBlendFunc(GL_SRC_COLOR, GL_ONE);
575 float sx = Minecraft::currentTimeMillis() % (3000 + i * 1873) / (3000.0f + i * 1873) * 256;
576 float sy = 0;
577 Tesselator *t = Tesselator::getInstance();
578 float vv = 4;
579 if (i == 1) vv = -1;
580 t->begin();
581 t->vertexUV(xx0f, yy1f, blitOffset, (sx + h * vv) * us, (sy + h) * vs);
582 t->vertexUV(xx1f, yy1f, blitOffset, (sx + w + h * vv) * us, (sy + h) * vs);
583 t->vertexUV(xx1f, yy0f, blitOffset, (sx + w) * us, (sy + 0) * vs);
584 t->vertexUV(xx0f, yy0f, blitOffset, (sx + 0) * us, (sy + 0) * vs);
585 t->end();
586 }
587}
588
589void ItemRenderer::renderGuiItemDecorations(Font *font, Textures *textures, shared_ptr<ItemInstance> item, int x, int y, float fAlpha)
590{
591 renderGuiItemDecorations(font, textures, item, x, y, L"", fAlpha);
592}
593
594void ItemRenderer::renderGuiItemDecorations(Font *font, Textures *textures, shared_ptr<ItemInstance> item, int x, int y, const wstring &countText, float fAlpha)
595{
596 if (item == NULL)
597 {
598 return;
599 }
600
601 if (item->count > 1 || !countText.empty() || item->GetForceNumberDisplay())
602 {
603 MemSect(31);
604 wstring amount = countText;
605 if(amount.empty())
606 {
607 int count = item->count;
608 if(count > 64)
609 {
610 amount = _toString<int>(64) + L"+";
611 }
612 else
613 {
614 amount = _toString<int>(item->count);
615 }
616 }
617 MemSect(0);
618 glDisable(GL_LIGHTING);
619 glDisable(GL_DEPTH_TEST);
620 font->drawShadow(amount, x + 19 - 2 - font->width(amount), y + 6 + 3, 0xffffff |(((unsigned int)(fAlpha * 0xff))<<24));
621 glEnable(GL_LIGHTING);
622 glEnable(GL_DEPTH_TEST);
623 }
624
625 if (item->isDamaged())
626 {
627 int p = (int) Math::round(13.0 - (double) item->getDamageValue() * 13.0 / (double) item->getMaxDamage());
628 int cc = (int) Math::round(255.0 - (double) item->getDamageValue() * 255.0 / (double) item->getMaxDamage());
629 glDisable(GL_LIGHTING);
630 glDisable(GL_DEPTH_TEST);
631 glDisable(GL_TEXTURE_2D);
632
633 Tesselator *t = Tesselator::getInstance();
634
635 int ca = (255 - cc) << 16 | (cc) << 8;
636 int cb = ((255 - cc) / 4) << 16 | (255 / 4) << 8;
637 fillRect(t, x + 2, y + 13, 13, 2, 0x000000);
638 fillRect(t, x + 2, y + 13, 12, 1, cb);
639 fillRect(t, x + 2, y + 13, p, 1, ca);
640
641 glEnable(GL_TEXTURE_2D);
642 glEnable(GL_LIGHTING);
643 glEnable(GL_DEPTH_TEST);
644 glColor4f(1, 1, 1, 1);
645 }
646 else if(item->hasPotionStrengthBar())
647 {
648 glDisable(GL_LIGHTING);
649 glDisable(GL_DEPTH_TEST);
650 glDisable(GL_TEXTURE_2D);
651
652 Tesselator *t = Tesselator::getInstance();
653
654 fillRect(t, x + 3, y + 13, 11, 2, 0x000000);
655 //fillRect(t, x + 2, y + 13, 13, 1, 0x1dabc0);
656 fillRect(t, x + 3, y + 13, m_iPotionStrengthBarWidth[item->GetPotionStrength()], 2, 0x00e1eb);
657 fillRect(t, x + 2 + 3, y + 13, 1, 2, 0x000000);
658 fillRect(t, x + 2 + 3+3, y + 13, 1, 2, 0x000000);
659 fillRect(t, x + 2 + 3+3+3, y + 13, 1, 2, 0x000000);
660
661
662 glEnable(GL_TEXTURE_2D);
663 glEnable(GL_LIGHTING);
664 glEnable(GL_DEPTH_TEST);
665 glColor4f(1, 1, 1, 1);
666 }
667 glDisable(GL_BLEND);
668}
669
670const int ItemRenderer::m_iPotionStrengthBarWidth[]=
671{
672 3,6,9,11
673};
674
675void ItemRenderer::fillRect(Tesselator *t, int x, int y, int w, int h, int c)
676{
677 t->begin();
678 t->color(c);
679 t->vertex((float)(x + 0), (float)( y + 0), (float)( 0));
680 t->vertex((float)(x + 0), (float)( y + h), (float)( 0));
681 t->vertex((float)(x + w), (float)( y + h), (float)( 0));
682 t->vertex((float)(x + w), (float)( y + 0), (float)( 0));
683 t->end();
684}
685
686// 4J - a few changes here to get x, y, w, h in as floats (for xui rendering accuracy), and to align
687// final pixels to the final screen resolution
688void ItemRenderer::blit(float x, float y, int sx, int sy, float w, float h)
689{
690 float us = 1 / 256.0f;
691 float vs = 1 / 256.0f;
692 Tesselator *t = Tesselator::getInstance();
693 t->begin();
694
695 // 4J - calculate what the pixel coordinates will be in final screen coordinates
696 float sfx = (float)Minecraft::GetInstance()->width / (float)Minecraft::GetInstance()->width_phys;
697 float sfy = (float)Minecraft::GetInstance()->height / (float)Minecraft::GetInstance()->height_phys;
698 float xx0 = x * sfx;
699 float xx1 = ( x + w ) * sfx;
700 float yy0 = y * sfy;
701 float yy1 = ( y + h ) * sfy;
702 // Round to whole pixels - rounding inwards so that we don't overlap any surrounding graphics
703 xx0 = ceilf(xx0);
704 xx1 = floorf(xx1);
705 yy0 = ceilf(yy0);
706 yy1 = floorf(yy1);
707 // Offset by half to get actual centre of pixel - again moving inwards to avoid overlap with surrounding graphics
708 xx0 += 0.5f;
709 xx1 -= 0.5f;
710 yy0 += 0.5f;
711 yy1 -= 0.5f;
712 // Convert back to game coordinate space
713 float xx0f = xx0 / sfx;
714 float xx1f = xx1 / sfx;
715 float yy0f = yy0 / sfy;
716 float yy1f = yy1 / sfy;
717
718 // 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
719 float f = ( 0.5f * (float)Minecraft::GetInstance()->width ) / (float)Minecraft::GetInstance()->width_phys;
720
721 t->vertexUV(xx0f, yy1f, (float)( blitOffset), (float)( (sx + 0) * us), (float)( (sy + 16) * vs));
722 t->vertexUV(xx1f, yy1f, (float)( blitOffset), (float)( (sx + 16) * us), (float)( (sy + 16) * vs));
723 t->vertexUV(xx1f, yy0f, (float)( blitOffset), (float)( (sx + 16) * us), (float)( (sy + 0) * vs));
724 t->vertexUV(xx0f, yy0f, (float)( blitOffset), (float)( (sx + 0) * us), (float)( (sy + 0) * vs));
725 t->end();
726}
727
728void ItemRenderer::blit(float x, float y, Icon *tex, float w, float h)
729{
730 Tesselator *t = Tesselator::getInstance();
731 t->begin();
732
733 // 4J - calculate what the pixel coordinates will be in final screen coordinates
734 float sfx = (float)Minecraft::GetInstance()->width / (float)Minecraft::GetInstance()->width_phys;
735 float sfy = (float)Minecraft::GetInstance()->height / (float)Minecraft::GetInstance()->height_phys;
736 float xx0 = x * sfx;
737 float xx1 = ( x + w ) * sfx;
738 float yy0 = y * sfy;
739 float yy1 = ( y + h ) * sfy;
740 // Round to whole pixels - rounding inwards so that we don't overlap any surrounding graphics
741 xx0 = ceilf(xx0);
742 xx1 = floorf(xx1);
743 yy0 = ceilf(yy0);
744 yy1 = floorf(yy1);
745 // Offset by half to get actual centre of pixel - again moving inwards to avoid overlap with surrounding graphics
746 xx0 += 0.5f;
747 xx1 -= 0.5f;
748 yy0 += 0.5f;
749 yy1 -= 0.5f;
750 // Convert back to game coordinate space
751 float xx0f = xx0 / sfx;
752 float xx1f = xx1 / sfx;
753 float yy0f = yy0 / sfy;
754 float yy1f = yy1 / sfy;
755
756 // 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
757 float f = ( 0.5f * (float)Minecraft::GetInstance()->width ) / (float)Minecraft::GetInstance()->width_phys;
758
759 t->vertexUV(xx0f, yy1f, blitOffset, tex->getU0(true), tex->getV1(true));
760 t->vertexUV(xx1f, yy1f, blitOffset, tex->getU1(true), tex->getV1(true));
761 t->vertexUV(xx1f, yy0f, blitOffset, tex->getU1(true), tex->getV0(true));
762 t->vertexUV(xx0f, yy0f, blitOffset, tex->getU0(true), tex->getV0(true));
763 t->end();
764}