]> git.lizzy.rs Git - dragonfireclient.git/blob - src/hud.cpp
small drawItemStack cleanup
[dragonfireclient.git] / src / hud.cpp
1 /*
2 Minetest
3 Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
4 Copyright (C) 2010-2013 blue42u, Jonathon Anderson <anderjon@umail.iu.edu>
5 Copyright (C) 2010-2013 kwolekr, Ryan Kwolek <kwolekr@minetest.net>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License along
18 with this program; if not, write to the Free Software Foundation, Inc.,
19 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 */
21
22 #include "hud.h"
23 #include "settings.h"
24 #include "util/numeric.h"
25 #include "log.h"
26 #include "gamedef.h"
27 #include "itemdef.h"
28 #include "inventory.h"
29 #include "client/tile.h"
30 #include "localplayer.h"
31 #include "camera.h"
32 #include "porting.h"
33 #include "fontengine.h"
34 #include "guiscalingfilter.h"
35 #include <IGUIStaticText.h>
36
37 #ifdef HAVE_TOUCHSCREENGUI
38 #include "touchscreengui.h"
39 #endif
40
41 Hud::Hud(video::IVideoDriver *driver, scene::ISceneManager* smgr,
42                 gui::IGUIEnvironment* guienv, IGameDef *gamedef, LocalPlayer *player,
43                 Inventory *inventory) {
44         this->driver      = driver;
45         this->smgr        = smgr;
46         this->guienv      = guienv;
47         this->gamedef     = gamedef;
48         this->player      = player;
49         this->inventory   = inventory;
50
51         m_screensize       = v2u32(0, 0);
52         m_displaycenter    = v2s32(0, 0);
53         m_hotbar_imagesize = floor(HOTBAR_IMAGE_SIZE * porting::getDisplayDensity() + 0.5);
54         m_hotbar_imagesize *= g_settings->getFloat("hud_scaling");
55         m_padding = m_hotbar_imagesize / 12;
56
57         const video::SColor hbar_color(255, 255, 255, 255);
58         for (unsigned int i=0; i < 4; i++ ){
59                 hbar_colors[i] = hbar_color;
60         }
61
62         tsrc = gamedef->getTextureSource();
63
64         v3f crosshair_color = g_settings->getV3F("crosshair_color");
65         u32 cross_r = rangelim(myround(crosshair_color.X), 0, 255);
66         u32 cross_g = rangelim(myround(crosshair_color.Y), 0, 255);
67         u32 cross_b = rangelim(myround(crosshair_color.Z), 0, 255);
68         u32 cross_a = rangelim(g_settings->getS32("crosshair_alpha"), 0, 255);
69         crosshair_argb = video::SColor(cross_a, cross_r, cross_g, cross_b);
70
71         v3f selectionbox_color = g_settings->getV3F("selectionbox_color");
72         u32 sbox_r = rangelim(myround(selectionbox_color.X), 0, 255);
73         u32 sbox_g = rangelim(myround(selectionbox_color.Y), 0, 255);
74         u32 sbox_b = rangelim(myround(selectionbox_color.Z), 0, 255);
75         selectionbox_argb = video::SColor(255, sbox_r, sbox_g, sbox_b);
76
77         use_crosshair_image = tsrc->isKnownSourceImage("crosshair.png");
78
79         hotbar_image = "";
80         use_hotbar_image = false;
81         hotbar_selected_image = "";
82         use_hotbar_selected_image = false;
83 }
84
85 void Hud::drawItem(const ItemStack &item, const core::rect<s32>& rect,
86                 bool selected)
87 {
88         if (selected) {
89                         /* draw hihlighting around selected item */
90                         if (use_hotbar_selected_image) {
91                                 core::rect<s32> imgrect2 = rect;
92                                 imgrect2.UpperLeftCorner.X  -= (m_padding*2);
93                                 imgrect2.UpperLeftCorner.Y  -= (m_padding*2);
94                                 imgrect2.LowerRightCorner.X += (m_padding*2);
95                                 imgrect2.LowerRightCorner.Y += (m_padding*2);
96                                         video::ITexture *texture = tsrc->getTexture(hotbar_selected_image);
97                                         core::dimension2di imgsize(texture->getOriginalSize());
98                                 draw2DImageFilterScaled(driver, texture, imgrect2,
99                                                 core::rect<s32>(core::position2d<s32>(0,0), imgsize),
100                                                 NULL, hbar_colors, true);
101                         } else {
102                                 video::SColor c_outside(255,255,0,0);
103                                 //video::SColor c_outside(255,0,0,0);
104                                 //video::SColor c_inside(255,192,192,192);
105                                 s32 x1 = rect.UpperLeftCorner.X;
106                                 s32 y1 = rect.UpperLeftCorner.Y;
107                                 s32 x2 = rect.LowerRightCorner.X;
108                                 s32 y2 = rect.LowerRightCorner.Y;
109                                 // Black base borders
110                                 driver->draw2DRectangle(c_outside,
111                                         core::rect<s32>(
112                                         v2s32(x1 - m_padding, y1 - m_padding),
113                                         v2s32(x2 + m_padding, y1)
114                                         ), NULL);
115                                 driver->draw2DRectangle(c_outside,
116                                         core::rect<s32>(
117                                         v2s32(x1 - m_padding, y2),
118                                         v2s32(x2 + m_padding, y2 + m_padding)
119                                         ), NULL);
120                                 driver->draw2DRectangle(c_outside,
121                                         core::rect<s32>(
122                                         v2s32(x1 - m_padding, y1),
123                                                 v2s32(x1, y2)
124                                         ), NULL);
125                                 driver->draw2DRectangle(c_outside,
126                                         core::rect<s32>(
127                                                 v2s32(x2, y1),
128                                         v2s32(x2 + m_padding, y2)
129                                         ), NULL);
130                                 /*// Light inside borders
131                                 driver->draw2DRectangle(c_inside,
132                                         core::rect<s32>(
133                                                 v2s32(x1 - padding/2, y1 - padding/2),
134                                                 v2s32(x2 + padding/2, y1)
135                                         ), NULL);
136                                 driver->draw2DRectangle(c_inside,
137                                         core::rect<s32>(
138                                                 v2s32(x1 - padding/2, y2),
139                                                 v2s32(x2 + padding/2, y2 + padding/2)
140                                         ), NULL);
141                                 driver->draw2DRectangle(c_inside,
142                                         core::rect<s32>(
143                                                 v2s32(x1 - padding/2, y1),
144                                                 v2s32(x1, y2)
145                                         ), NULL);
146                                 driver->draw2DRectangle(c_inside,
147                                         core::rect<s32>(
148                                                 v2s32(x2, y1),
149                                                 v2s32(x2 + padding/2, y2)
150                                         ), NULL);
151                                 */
152                         }
153                 }
154
155                 video::SColor bgcolor2(128, 0, 0, 0);
156                 if (!use_hotbar_image)
157                         driver->draw2DRectangle(bgcolor2, rect, NULL);
158                 drawItemStack(driver, g_fontengine->getFont(), item, rect, NULL,
159                         gamedef, selected ? IT_ROT_SELECTED : IT_ROT_NONE);
160         }
161
162 //NOTE: selectitem = 0 -> no selected; selectitem 1-based
163 void Hud::drawItems(v2s32 upperleftpos, s32 itemcount, s32 offset,
164                 InventoryList *mainlist, u16 selectitem, u16 direction)
165 {
166 #ifdef HAVE_TOUCHSCREENGUI
167         if ( (g_touchscreengui) && (offset == 0))
168                 g_touchscreengui->resetHud();
169 #endif
170
171         s32 height  = m_hotbar_imagesize + m_padding * 2;
172         s32 width   = (itemcount - offset) * (m_hotbar_imagesize + m_padding * 2);
173
174         if (direction == HUD_DIR_TOP_BOTTOM || direction == HUD_DIR_BOTTOM_TOP) {
175                 width  = m_hotbar_imagesize + m_padding * 2;
176                 height = (itemcount - offset) * (m_hotbar_imagesize + m_padding * 2);
177         }
178
179         // Position of upper left corner of bar
180         v2s32 pos = upperleftpos;
181
182         if (hotbar_image != player->hotbar_image) {
183                 hotbar_image = player->hotbar_image;
184                 if (hotbar_image != "")
185                         use_hotbar_image = tsrc->isKnownSourceImage(hotbar_image);
186                 else
187                         use_hotbar_image = false;
188         }
189
190         if (hotbar_selected_image != player->hotbar_selected_image) {
191                 hotbar_selected_image = player->hotbar_selected_image;
192                 if (hotbar_selected_image != "")
193                         use_hotbar_selected_image = tsrc->isKnownSourceImage(hotbar_selected_image);
194                 else
195                         use_hotbar_selected_image = false;
196         }
197
198         /* draw customized item background */
199         if (use_hotbar_image) {
200                 core::rect<s32> imgrect2(-m_padding/2, -m_padding/2,
201                                 width+m_padding/2, height+m_padding/2);
202                 core::rect<s32> rect2 = imgrect2 + pos;
203                 video::ITexture *texture = tsrc->getTexture(hotbar_image);
204                 core::dimension2di imgsize(texture->getOriginalSize());
205                 draw2DImageFilterScaled(driver, texture, rect2,
206                         core::rect<s32>(core::position2d<s32>(0,0), imgsize),
207                         NULL, hbar_colors, true);
208         }
209
210         for (s32 i = offset; i < itemcount && (size_t)i < mainlist->getSize(); i++)
211         {
212                 v2s32 steppos;
213                 s32 fullimglen = m_hotbar_imagesize + m_padding * 2;
214
215                 core::rect<s32> imgrect(0, 0, m_hotbar_imagesize, m_hotbar_imagesize);
216
217                 switch (direction) {
218                         case HUD_DIR_RIGHT_LEFT:
219                                 steppos = v2s32(-(m_padding + (i - offset) * fullimglen), m_padding);
220                                 break;
221                         case HUD_DIR_TOP_BOTTOM:
222                                 steppos = v2s32(m_padding, m_padding + (i - offset) * fullimglen);
223                                 break;
224                         case HUD_DIR_BOTTOM_TOP:
225                                 steppos = v2s32(m_padding, -(m_padding + (i - offset) * fullimglen));
226                                 break;
227                         default:
228                                 steppos = v2s32(m_padding + (i - offset) * fullimglen, m_padding);
229                                 break;
230                 }
231
232                 drawItem(mainlist->getItem(i), (imgrect + pos + steppos), (i +1) == selectitem );
233
234 #ifdef HAVE_TOUCHSCREENGUI
235                 if (g_touchscreengui)
236                         g_touchscreengui->registerHudItem(i, (imgrect + pos + steppos));
237 #endif
238         }
239 }
240
241
242 void Hud::drawLuaElements(v3s16 camera_offset) {
243         u32 text_height = g_fontengine->getTextHeight();
244         irr::gui::IGUIFont* font = g_fontengine->getFont();
245         for (size_t i = 0; i != player->maxHudId(); i++) {
246                 HudElement *e = player->getHud(i);
247                 if (!e)
248                         continue;
249
250                 v2s32 pos(floor(e->pos.X * (float) m_screensize.X + 0.5),
251                                 floor(e->pos.Y * (float) m_screensize.Y + 0.5));
252                 switch (e->type) {
253                         case HUD_ELEM_IMAGE: {
254                                 video::ITexture *texture = tsrc->getTexture(e->text);
255                                 if (!texture)
256                                         continue;
257
258                                 const video::SColor color(255, 255, 255, 255);
259                                 const video::SColor colors[] = {color, color, color, color};
260                                 core::dimension2di imgsize(texture->getOriginalSize());
261                                 v2s32 dstsize(imgsize.Width * e->scale.X,
262                                               imgsize.Height * e->scale.Y);
263                                 if (e->scale.X < 0)
264                                         dstsize.X = m_screensize.X * (e->scale.X * -0.01);
265                                 if (e->scale.Y < 0)
266                                         dstsize.Y = m_screensize.Y * (e->scale.Y * -0.01);
267                                 v2s32 offset((e->align.X - 1.0) * dstsize.X / 2,
268                                              (e->align.Y - 1.0) * dstsize.Y / 2);
269                                 core::rect<s32> rect(0, 0, dstsize.X, dstsize.Y);
270                                 rect += pos + offset + v2s32(e->offset.X, e->offset.Y);
271                                 draw2DImageFilterScaled(driver, texture, rect,
272                                         core::rect<s32>(core::position2d<s32>(0,0), imgsize),
273                                         NULL, colors, true);
274                                 break; }
275                         case HUD_ELEM_TEXT: {
276                                 video::SColor color(255, (e->number >> 16) & 0xFF,
277                                                                                  (e->number >> 8)  & 0xFF,
278                                                                                  (e->number >> 0)  & 0xFF);
279                                 core::rect<s32> size(0, 0, e->scale.X, text_height * e->scale.Y);
280                                 std::wstring text = utf8_to_wide(e->text);
281                                 core::dimension2d<u32> textsize = font->getDimension(text.c_str());
282                                 v2s32 offset((e->align.X - 1.0) * (textsize.Width / 2),
283                                              (e->align.Y - 1.0) * (textsize.Height / 2));
284                                 v2s32 offs(e->offset.X, e->offset.Y);
285                                 font->draw(text.c_str(), size + pos + offset + offs, color);
286                                 break; }
287                         case HUD_ELEM_STATBAR: {
288                                 v2s32 offs(e->offset.X, e->offset.Y);
289                                 drawStatbar(pos, HUD_CORNER_UPPER, e->dir, e->text, e->number, offs, e->size);
290                                 break; }
291                         case HUD_ELEM_INVENTORY: {
292                                 InventoryList *inv = inventory->getList(e->text);
293                                 drawItems(pos, e->number, 0, inv, e->item, e->dir);
294                                 break; }
295                         case HUD_ELEM_WAYPOINT: {
296                                 v3f p_pos = player->getPosition() / BS;
297                                 v3f w_pos = e->world_pos * BS;
298                                 float distance = floor(10 * p_pos.getDistanceFrom(e->world_pos)) / 10;
299                                 scene::ICameraSceneNode* camera = smgr->getActiveCamera();
300                                 w_pos -= intToFloat(camera_offset, BS);
301                                 core::matrix4 trans = camera->getProjectionMatrix();
302                                 trans *= camera->getViewMatrix();
303                                 f32 transformed_pos[4] = { w_pos.X, w_pos.Y, w_pos.Z, 1.0f };
304                                 trans.multiplyWith1x4Matrix(transformed_pos);
305                                 if (transformed_pos[3] < 0)
306                                         break;
307                                 f32 zDiv = transformed_pos[3] == 0.0f ? 1.0f :
308                                         core::reciprocal(transformed_pos[3]);
309                                 pos.X = m_screensize.X * (0.5 * transformed_pos[0] * zDiv + 0.5);
310                                 pos.Y = m_screensize.Y * (0.5 - transformed_pos[1] * zDiv * 0.5);
311                                 video::SColor color(255, (e->number >> 16) & 0xFF,
312                                                                                  (e->number >> 8)  & 0xFF,
313                                                                                  (e->number >> 0)  & 0xFF);
314                                 core::rect<s32> size(0, 0, 200, 2 * text_height);
315                                 std::wstring text = utf8_to_wide(e->name);
316                                 font->draw(text.c_str(), size + pos, color);
317                                 std::ostringstream os;
318                                 os << distance << e->text;
319                                 text = utf8_to_wide(os.str());
320                                 pos.Y += text_height;
321                                 font->draw(text.c_str(), size + pos, color);
322                                 break; }
323                         default:
324                                 infostream << "Hud::drawLuaElements: ignoring drawform " << e->type <<
325                                         " of hud element ID " << i << " due to unrecognized type" << std::endl;
326                 }
327         }
328 }
329
330
331 void Hud::drawStatbar(v2s32 pos, u16 corner, u16 drawdir, std::string texture,
332                 s32 count, v2s32 offset, v2s32 size)
333 {
334         const video::SColor color(255, 255, 255, 255);
335         const video::SColor colors[] = {color, color, color, color};
336
337         video::ITexture *stat_texture = tsrc->getTexture(texture);
338         if (!stat_texture)
339                 return;
340
341         core::dimension2di srcd(stat_texture->getOriginalSize());
342         core::dimension2di dstd;
343         if (size == v2s32()) {
344                 dstd = srcd;
345         } else {
346                 double size_factor = g_settings->getFloat("hud_scaling") *
347                                 porting::getDisplayDensity();
348                 dstd.Height = size.Y * size_factor;
349                 dstd.Width  = size.X * size_factor;
350                 offset.X *= size_factor;
351                 offset.Y *= size_factor;
352         }
353
354         v2s32 p = pos;
355         if (corner & HUD_CORNER_LOWER)
356                 p -= dstd.Height;
357
358         p += offset;
359
360         v2s32 steppos;
361         switch (drawdir) {
362                 case HUD_DIR_RIGHT_LEFT:
363                         steppos = v2s32(-1, 0);
364                         break;
365                 case HUD_DIR_TOP_BOTTOM:
366                         steppos = v2s32(0, 1);
367                         break;
368                 case HUD_DIR_BOTTOM_TOP:
369                         steppos = v2s32(0, -1);
370                         break;
371                 default:
372                         steppos = v2s32(1, 0);
373         }
374         steppos.X *= dstd.Width;
375         steppos.Y *= dstd.Height;
376
377         for (s32 i = 0; i < count / 2; i++)
378         {
379                 core::rect<s32> srcrect(0, 0, srcd.Width, srcd.Height);
380                 core::rect<s32> dstrect(0,0, dstd.Width, dstd.Height);
381
382                 dstrect += p;
383                 draw2DImageFilterScaled(driver, stat_texture, dstrect, srcrect, NULL, colors, true);
384                 p += steppos;
385         }
386
387         if (count % 2 == 1)
388         {
389                 core::rect<s32> srcrect(0, 0, srcd.Width / 2, srcd.Height);
390                 core::rect<s32> dstrect(0,0, dstd.Width / 2, dstd.Height);
391
392                 dstrect += p;
393                 draw2DImageFilterScaled(driver, stat_texture, dstrect, srcrect, NULL, colors, true);
394         }
395 }
396
397
398 void Hud::drawHotbar(u16 playeritem) {
399
400         v2s32 centerlowerpos(m_displaycenter.X, m_screensize.Y);
401
402         InventoryList *mainlist = inventory->getList("main");
403         if (mainlist == NULL) {
404                 //silently ignore this we may not be initialized completely
405                 return;
406         }
407
408         s32 hotbar_itemcount = player->hud_hotbar_itemcount;
409         s32 width = hotbar_itemcount * (m_hotbar_imagesize + m_padding * 2);
410         v2s32 pos = centerlowerpos - v2s32(width / 2, m_hotbar_imagesize + m_padding * 3);
411
412         if ( (float) width / (float) porting::getWindowSize().X <=
413                         g_settings->getFloat("hud_hotbar_max_width")) {
414                 if (player->hud_flags & HUD_FLAG_HOTBAR_VISIBLE) {
415                         drawItems(pos, hotbar_itemcount, 0, mainlist, playeritem + 1, 0);
416                 }
417         }
418         else {
419                 pos.X += width/4;
420
421                 v2s32 secondpos = pos;
422                 pos = pos - v2s32(0, m_hotbar_imagesize + m_padding);
423
424                 if (player->hud_flags & HUD_FLAG_HOTBAR_VISIBLE) {
425                         drawItems(pos, hotbar_itemcount/2, 0, mainlist, playeritem + 1, 0);
426                         drawItems(secondpos, hotbar_itemcount, hotbar_itemcount/2, mainlist, playeritem + 1, 0);
427                 }
428         }
429
430         //////////////////////////// compatibility code to be removed //////////////
431         // this is ugly as hell but there's no other way to keep compatibility to
432         // old servers
433         if ((player->hud_flags & HUD_FLAG_HEALTHBAR_VISIBLE)) {
434                 drawStatbar(v2s32(floor(0.5 * (float)m_screensize.X + 0.5),
435                         floor(1 * (float) m_screensize.Y + 0.5)),
436                         HUD_CORNER_UPPER, 0, "heart.png",
437                         player->hp, v2s32((-10*24)-25,-(48+24+10)), v2s32(24,24));
438         }
439
440         if ((player->hud_flags & HUD_FLAG_BREATHBAR_VISIBLE) &&
441                         (player->getBreath() < 11)) {
442                 drawStatbar(v2s32(floor(0.5 * (float)m_screensize.X + 0.5),
443                         floor(1 * (float) m_screensize.Y + 0.5)),
444                         HUD_CORNER_UPPER, 0, "bubble.png",
445                         player->getBreath(), v2s32(25,-(48+24+10)), v2s32(24,24));
446         }
447         ////////////////////////////////////////////////////////////////////////////
448 }
449
450
451 void Hud::drawCrosshair() {
452
453         if (use_crosshair_image) {
454                 video::ITexture *crosshair = tsrc->getTexture("crosshair.png");
455                 v2u32 size  = crosshair->getOriginalSize();
456                 v2s32 lsize = v2s32(m_displaycenter.X - (size.X / 2),
457                                 m_displaycenter.Y - (size.Y / 2));
458                 driver->draw2DImage(crosshair, lsize,
459                                 core::rect<s32>(0, 0, size.X, size.Y),
460                                 0, crosshair_argb, true);
461         } else {
462                 driver->draw2DLine(m_displaycenter - v2s32(10, 0),
463                                 m_displaycenter + v2s32(10, 0), crosshair_argb);
464                 driver->draw2DLine(m_displaycenter - v2s32(0, 10),
465                                 m_displaycenter + v2s32(0, 10), crosshair_argb);
466         }
467 }
468
469
470 void Hud::drawSelectionBoxes(std::vector<aabb3f> &hilightboxes) {
471         for (std::vector<aabb3f>::const_iterator
472                         i = hilightboxes.begin();
473                         i != hilightboxes.end(); ++i) {
474                 driver->draw3DBox(*i, selectionbox_argb);
475         }
476 }
477
478
479 void Hud::resizeHotbar() {
480         if (m_screensize != porting::getWindowSize()) {
481                 m_hotbar_imagesize = floor(HOTBAR_IMAGE_SIZE * porting::getDisplayDensity() + 0.5);
482                 m_hotbar_imagesize *= g_settings->getFloat("hud_scaling");
483                 m_padding = m_hotbar_imagesize / 12;
484                 m_screensize = porting::getWindowSize();
485                 m_displaycenter = v2s32(m_screensize.X/2,m_screensize.Y/2);
486         }
487 }
488
489 struct MeshTimeInfo {
490         s32 time;
491         scene::IMesh *mesh;
492 };
493
494 void drawItemStack(video::IVideoDriver *driver,
495                 gui::IGUIFont *font,
496                 const ItemStack &item,
497                 const core::rect<s32> &rect,
498                 const core::rect<s32> *clip,
499                 IGameDef *gamedef,
500                 ItemRotationKind rotation_kind)
501 {
502         static MeshTimeInfo rotation_time_infos[IT_ROT_NONE];
503         static bool enable_animations =
504                 g_settings->getBool("inventory_items_animations");
505
506         if (item.empty()) {
507                 if (rotation_kind < IT_ROT_NONE) {
508                         rotation_time_infos[rotation_kind].mesh = NULL;
509                 }
510                 return;
511         }
512
513         const ItemDefinition &def = item.getDefinition(gamedef->idef());
514         scene::IMesh* mesh = gamedef->idef()->getWieldMesh(def.name, gamedef);
515
516         if (mesh) {
517                 driver->clearZBuffer();
518                 s32 delta = 0;
519                 if (rotation_kind < IT_ROT_NONE) {
520                         MeshTimeInfo &ti = rotation_time_infos[rotation_kind];
521                         if (mesh != ti.mesh) {
522                                 ti.mesh = mesh;
523                                 ti.time = getTimeMs();
524                         } else {
525                                 delta = porting::getDeltaMs(ti.time, getTimeMs()) % 100000;
526                         }
527                 }
528                 core::rect<s32> oldViewPort = driver->getViewPort();
529                 core::matrix4 oldProjMat = driver->getTransform(video::ETS_PROJECTION);
530                 core::matrix4 oldViewMat = driver->getTransform(video::ETS_VIEW);
531                 core::matrix4 ProjMatrix;
532                 ProjMatrix.buildProjectionMatrixOrthoLH(2, 2, -1, 100);
533                 driver->setTransform(video::ETS_PROJECTION, ProjMatrix);
534                 driver->setTransform(video::ETS_VIEW, ProjMatrix);
535                 core::matrix4 matrix;
536                 matrix.makeIdentity();
537
538                 if (enable_animations) {
539                         float timer_f = (float)delta / 5000.0;
540                         matrix.setRotationDegrees(core::vector3df(0, 360 * timer_f, 0));
541                 }
542
543                 driver->setTransform(video::ETS_WORLD, matrix);
544                 driver->setViewPort(rect);
545
546                 u32 mc = mesh->getMeshBufferCount();
547                 for (u32 j = 0; j < mc; ++j) {
548                         scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
549                         video::SMaterial &material = buf->getMaterial();
550                         material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
551                         material.Lighting = false;
552                         driver->setMaterial(material);
553                         driver->drawMeshBuffer(buf);
554                 }
555
556                 driver->setTransform(video::ETS_VIEW, oldViewMat);
557                 driver->setTransform(video::ETS_PROJECTION, oldProjMat);
558                 driver->setViewPort(oldViewPort);
559         }
560
561         if(def.type == ITEM_TOOL && item.wear != 0)
562         {
563                 // Draw a progressbar
564                 float barheight = rect.getHeight()/16;
565                 float barpad_x = rect.getWidth()/16;
566                 float barpad_y = rect.getHeight()/16;
567                 core::rect<s32> progressrect(
568                         rect.UpperLeftCorner.X + barpad_x,
569                         rect.LowerRightCorner.Y - barpad_y - barheight,
570                         rect.LowerRightCorner.X - barpad_x,
571                         rect.LowerRightCorner.Y - barpad_y);
572
573                 // Shrink progressrect by amount of tool damage
574                 float wear = item.wear / 65535.0;
575                 int progressmid =
576                         wear * progressrect.UpperLeftCorner.X +
577                         (1-wear) * progressrect.LowerRightCorner.X;
578
579                 // Compute progressbar color
580                 //   wear = 0.0: green
581                 //   wear = 0.5: yellow
582                 //   wear = 1.0: red
583                 video::SColor color(255,255,255,255);
584                 int wear_i = MYMIN(floor(wear * 600), 511);
585                 wear_i = MYMIN(wear_i + 10, 511);
586                 if(wear_i <= 255)
587                         color.set(255, wear_i, 255, 0);
588                 else
589                         color.set(255, 255, 511-wear_i, 0);
590
591                 core::rect<s32> progressrect2 = progressrect;
592                 progressrect2.LowerRightCorner.X = progressmid;
593                 driver->draw2DRectangle(color, progressrect2, clip);
594
595                 color = video::SColor(255,0,0,0);
596                 progressrect2 = progressrect;
597                 progressrect2.UpperLeftCorner.X = progressmid;
598                 driver->draw2DRectangle(color, progressrect2, clip);
599         }
600
601         if(font != NULL && item.count >= 2)
602         {
603                 // Get the item count as a string
604                 std::string text = itos(item.count);
605                 v2u32 dim = font->getDimension(utf8_to_wide(text).c_str());
606                 v2s32 sdim(dim.X,dim.Y);
607
608                 core::rect<s32> rect2(
609                         /*rect.UpperLeftCorner,
610                         core::dimension2d<u32>(rect.getWidth(), 15)*/
611                         rect.LowerRightCorner - sdim,
612                         sdim
613                 );
614
615                 video::SColor bgcolor(128,0,0,0);
616                 driver->draw2DRectangle(bgcolor, rect2, clip);
617
618                 video::SColor color(255,255,255,255);
619                 font->draw(text.c_str(), rect2, color, false, false, clip);
620         }
621 }