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>
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.
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.
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.
24 #include "util/numeric.h"
28 #include "inventory.h"
29 #include "client/tile.h"
30 #include "localplayer.h"
33 #include "fontengine.h"
34 #include "guiscalingfilter.h"
36 #include <IGUIStaticText.h>
38 #ifdef HAVE_TOUCHSCREENGUI
39 #include "touchscreengui.h"
42 Hud::Hud(video::IVideoDriver *driver, scene::ISceneManager* smgr,
43 gui::IGUIEnvironment* guienv, IGameDef *gamedef, LocalPlayer *player,
44 Inventory *inventory) {
45 this->driver = driver;
47 this->guienv = guienv;
48 this->gamedef = gamedef;
49 this->player = player;
50 this->inventory = inventory;
52 m_screensize = v2u32(0, 0);
53 m_displaycenter = v2s32(0, 0);
54 m_hotbar_imagesize = floor(HOTBAR_IMAGE_SIZE * porting::getDisplayDensity() + 0.5);
55 m_hotbar_imagesize *= g_settings->getFloat("hud_scaling");
56 m_padding = m_hotbar_imagesize / 12;
58 const video::SColor hbar_color(255, 255, 255, 255);
59 for (unsigned int i=0; i < 4; i++ ){
60 hbar_colors[i] = hbar_color;
63 tsrc = gamedef->getTextureSource();
65 v3f crosshair_color = g_settings->getV3F("crosshair_color");
66 u32 cross_r = rangelim(myround(crosshair_color.X), 0, 255);
67 u32 cross_g = rangelim(myround(crosshair_color.Y), 0, 255);
68 u32 cross_b = rangelim(myround(crosshair_color.Z), 0, 255);
69 u32 cross_a = rangelim(g_settings->getS32("crosshair_alpha"), 0, 255);
70 crosshair_argb = video::SColor(cross_a, cross_r, cross_g, cross_b);
72 v3f selectionbox_color = g_settings->getV3F("selectionbox_color");
73 u32 sbox_r = rangelim(myround(selectionbox_color.X), 0, 255);
74 u32 sbox_g = rangelim(myround(selectionbox_color.Y), 0, 255);
75 u32 sbox_b = rangelim(myround(selectionbox_color.Z), 0, 255);
76 selectionbox_argb = video::SColor(255, sbox_r, sbox_g, sbox_b);
78 use_crosshair_image = tsrc->isKnownSourceImage("crosshair.png");
81 use_hotbar_image = false;
82 hotbar_selected_image = "";
83 use_hotbar_selected_image = false;
85 m_selection_mesh = NULL;
86 m_selection_boxes.clear();
87 m_selection_pos = v3f(0.0, 0.0, 0.0);
88 std::string mode = g_settings->get("node_highlighting");
89 m_selection_material.Lighting = false;
91 if (g_settings->getBool("enable_shaders")) {
92 IShaderSource *shdrsrc = gamedef->getShaderSource();
93 u16 shader_id = shdrsrc->getShader(
94 mode == "halo" ? "selection_shader" : "default_shader", 1, 1);
95 m_selection_material.MaterialType = shdrsrc->getShaderInfo(shader_id).material;
97 m_selection_material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
101 m_use_selection_mesh = false;
102 m_selection_material.Thickness =
103 rangelim(g_settings->getS16("selectionbox_width"), 1, 5);
104 } else if (mode == "halo") {
105 m_use_selection_mesh = true;
106 m_selection_material.setTexture(0, tsrc->getTextureForMesh("halo.png"));
107 m_selection_material.setFlag(video::EMF_BACK_FACE_CULLING, true);
109 m_selection_material.MaterialType = video::EMT_SOLID;
115 if (m_selection_mesh)
116 m_selection_mesh->drop();
119 void Hud::drawItem(const ItemStack &item, const core::rect<s32>& rect,
123 /* draw hihlighting around selected item */
124 if (use_hotbar_selected_image) {
125 core::rect<s32> imgrect2 = rect;
126 imgrect2.UpperLeftCorner.X -= (m_padding*2);
127 imgrect2.UpperLeftCorner.Y -= (m_padding*2);
128 imgrect2.LowerRightCorner.X += (m_padding*2);
129 imgrect2.LowerRightCorner.Y += (m_padding*2);
130 video::ITexture *texture = tsrc->getTexture(hotbar_selected_image);
131 core::dimension2di imgsize(texture->getOriginalSize());
132 draw2DImageFilterScaled(driver, texture, imgrect2,
133 core::rect<s32>(core::position2d<s32>(0,0), imgsize),
134 NULL, hbar_colors, true);
136 video::SColor c_outside(255,255,0,0);
137 //video::SColor c_outside(255,0,0,0);
138 //video::SColor c_inside(255,192,192,192);
139 s32 x1 = rect.UpperLeftCorner.X;
140 s32 y1 = rect.UpperLeftCorner.Y;
141 s32 x2 = rect.LowerRightCorner.X;
142 s32 y2 = rect.LowerRightCorner.Y;
143 // Black base borders
144 driver->draw2DRectangle(c_outside,
146 v2s32(x1 - m_padding, y1 - m_padding),
147 v2s32(x2 + m_padding, y1)
149 driver->draw2DRectangle(c_outside,
151 v2s32(x1 - m_padding, y2),
152 v2s32(x2 + m_padding, y2 + m_padding)
154 driver->draw2DRectangle(c_outside,
156 v2s32(x1 - m_padding, y1),
159 driver->draw2DRectangle(c_outside,
162 v2s32(x2 + m_padding, y2)
164 /*// Light inside borders
165 driver->draw2DRectangle(c_inside,
167 v2s32(x1 - padding/2, y1 - padding/2),
168 v2s32(x2 + padding/2, y1)
170 driver->draw2DRectangle(c_inside,
172 v2s32(x1 - padding/2, y2),
173 v2s32(x2 + padding/2, y2 + padding/2)
175 driver->draw2DRectangle(c_inside,
177 v2s32(x1 - padding/2, y1),
180 driver->draw2DRectangle(c_inside,
183 v2s32(x2 + padding/2, y2)
189 video::SColor bgcolor2(128, 0, 0, 0);
190 if (!use_hotbar_image)
191 driver->draw2DRectangle(bgcolor2, rect, NULL);
192 drawItemStack(driver, g_fontengine->getFont(), item, rect, NULL,
193 gamedef, selected ? IT_ROT_SELECTED : IT_ROT_NONE);
196 //NOTE: selectitem = 0 -> no selected; selectitem 1-based
197 void Hud::drawItems(v2s32 upperleftpos, s32 itemcount, s32 offset,
198 InventoryList *mainlist, u16 selectitem, u16 direction)
200 #ifdef HAVE_TOUCHSCREENGUI
201 if ( (g_touchscreengui) && (offset == 0))
202 g_touchscreengui->resetHud();
205 s32 height = m_hotbar_imagesize + m_padding * 2;
206 s32 width = (itemcount - offset) * (m_hotbar_imagesize + m_padding * 2);
208 if (direction == HUD_DIR_TOP_BOTTOM || direction == HUD_DIR_BOTTOM_TOP) {
209 width = m_hotbar_imagesize + m_padding * 2;
210 height = (itemcount - offset) * (m_hotbar_imagesize + m_padding * 2);
213 // Position of upper left corner of bar
214 v2s32 pos = upperleftpos;
216 if (hotbar_image != player->hotbar_image) {
217 hotbar_image = player->hotbar_image;
218 if (hotbar_image != "")
219 use_hotbar_image = tsrc->isKnownSourceImage(hotbar_image);
221 use_hotbar_image = false;
224 if (hotbar_selected_image != player->hotbar_selected_image) {
225 hotbar_selected_image = player->hotbar_selected_image;
226 if (hotbar_selected_image != "")
227 use_hotbar_selected_image = tsrc->isKnownSourceImage(hotbar_selected_image);
229 use_hotbar_selected_image = false;
232 /* draw customized item background */
233 if (use_hotbar_image) {
234 core::rect<s32> imgrect2(-m_padding/2, -m_padding/2,
235 width+m_padding/2, height+m_padding/2);
236 core::rect<s32> rect2 = imgrect2 + pos;
237 video::ITexture *texture = tsrc->getTexture(hotbar_image);
238 core::dimension2di imgsize(texture->getOriginalSize());
239 draw2DImageFilterScaled(driver, texture, rect2,
240 core::rect<s32>(core::position2d<s32>(0,0), imgsize),
241 NULL, hbar_colors, true);
244 for (s32 i = offset; i < itemcount && (size_t)i < mainlist->getSize(); i++)
247 s32 fullimglen = m_hotbar_imagesize + m_padding * 2;
249 core::rect<s32> imgrect(0, 0, m_hotbar_imagesize, m_hotbar_imagesize);
252 case HUD_DIR_RIGHT_LEFT:
253 steppos = v2s32(-(m_padding + (i - offset) * fullimglen), m_padding);
255 case HUD_DIR_TOP_BOTTOM:
256 steppos = v2s32(m_padding, m_padding + (i - offset) * fullimglen);
258 case HUD_DIR_BOTTOM_TOP:
259 steppos = v2s32(m_padding, -(m_padding + (i - offset) * fullimglen));
262 steppos = v2s32(m_padding + (i - offset) * fullimglen, m_padding);
266 drawItem(mainlist->getItem(i), (imgrect + pos + steppos), (i +1) == selectitem );
268 #ifdef HAVE_TOUCHSCREENGUI
269 if (g_touchscreengui)
270 g_touchscreengui->registerHudItem(i, (imgrect + pos + steppos));
276 void Hud::drawLuaElements(const v3s16 &camera_offset) {
277 u32 text_height = g_fontengine->getTextHeight();
278 irr::gui::IGUIFont* font = g_fontengine->getFont();
279 for (size_t i = 0; i != player->maxHudId(); i++) {
280 HudElement *e = player->getHud(i);
284 v2s32 pos(floor(e->pos.X * (float) m_screensize.X + 0.5),
285 floor(e->pos.Y * (float) m_screensize.Y + 0.5));
287 case HUD_ELEM_IMAGE: {
288 video::ITexture *texture = tsrc->getTexture(e->text);
292 const video::SColor color(255, 255, 255, 255);
293 const video::SColor colors[] = {color, color, color, color};
294 core::dimension2di imgsize(texture->getOriginalSize());
295 v2s32 dstsize(imgsize.Width * e->scale.X,
296 imgsize.Height * e->scale.Y);
298 dstsize.X = m_screensize.X * (e->scale.X * -0.01);
300 dstsize.Y = m_screensize.Y * (e->scale.Y * -0.01);
301 v2s32 offset((e->align.X - 1.0) * dstsize.X / 2,
302 (e->align.Y - 1.0) * dstsize.Y / 2);
303 core::rect<s32> rect(0, 0, dstsize.X, dstsize.Y);
304 rect += pos + offset + v2s32(e->offset.X, e->offset.Y);
305 draw2DImageFilterScaled(driver, texture, rect,
306 core::rect<s32>(core::position2d<s32>(0,0), imgsize),
309 case HUD_ELEM_TEXT: {
310 video::SColor color(255, (e->number >> 16) & 0xFF,
311 (e->number >> 8) & 0xFF,
312 (e->number >> 0) & 0xFF);
313 core::rect<s32> size(0, 0, e->scale.X, text_height * e->scale.Y);
314 std::wstring text = utf8_to_wide(e->text);
315 core::dimension2d<u32> textsize = font->getDimension(text.c_str());
316 v2s32 offset((e->align.X - 1.0) * (textsize.Width / 2),
317 (e->align.Y - 1.0) * (textsize.Height / 2));
318 v2s32 offs(e->offset.X, e->offset.Y);
319 font->draw(text.c_str(), size + pos + offset + offs, color);
321 case HUD_ELEM_STATBAR: {
322 v2s32 offs(e->offset.X, e->offset.Y);
323 drawStatbar(pos, HUD_CORNER_UPPER, e->dir, e->text, e->number, offs, e->size);
325 case HUD_ELEM_INVENTORY: {
326 InventoryList *inv = inventory->getList(e->text);
327 drawItems(pos, e->number, 0, inv, e->item, e->dir);
329 case HUD_ELEM_WAYPOINT: {
330 v3f p_pos = player->getPosition() / BS;
331 v3f w_pos = e->world_pos * BS;
332 float distance = floor(10 * p_pos.getDistanceFrom(e->world_pos)) / 10;
333 scene::ICameraSceneNode* camera = smgr->getActiveCamera();
334 w_pos -= intToFloat(camera_offset, BS);
335 core::matrix4 trans = camera->getProjectionMatrix();
336 trans *= camera->getViewMatrix();
337 f32 transformed_pos[4] = { w_pos.X, w_pos.Y, w_pos.Z, 1.0f };
338 trans.multiplyWith1x4Matrix(transformed_pos);
339 if (transformed_pos[3] < 0)
341 f32 zDiv = transformed_pos[3] == 0.0f ? 1.0f :
342 core::reciprocal(transformed_pos[3]);
343 pos.X = m_screensize.X * (0.5 * transformed_pos[0] * zDiv + 0.5);
344 pos.Y = m_screensize.Y * (0.5 - transformed_pos[1] * zDiv * 0.5);
345 video::SColor color(255, (e->number >> 16) & 0xFF,
346 (e->number >> 8) & 0xFF,
347 (e->number >> 0) & 0xFF);
348 core::rect<s32> size(0, 0, 200, 2 * text_height);
349 std::wstring text = utf8_to_wide(e->name);
350 font->draw(text.c_str(), size + pos, color);
351 std::ostringstream os;
352 os << distance << e->text;
353 text = utf8_to_wide(os.str());
354 pos.Y += text_height;
355 font->draw(text.c_str(), size + pos, color);
358 infostream << "Hud::drawLuaElements: ignoring drawform " << e->type <<
359 " of hud element ID " << i << " due to unrecognized type" << std::endl;
365 void Hud::drawStatbar(v2s32 pos, u16 corner, u16 drawdir, std::string texture,
366 s32 count, v2s32 offset, v2s32 size)
368 const video::SColor color(255, 255, 255, 255);
369 const video::SColor colors[] = {color, color, color, color};
371 video::ITexture *stat_texture = tsrc->getTexture(texture);
375 core::dimension2di srcd(stat_texture->getOriginalSize());
376 core::dimension2di dstd;
377 if (size == v2s32()) {
380 double size_factor = g_settings->getFloat("hud_scaling") *
381 porting::getDisplayDensity();
382 dstd.Height = size.Y * size_factor;
383 dstd.Width = size.X * size_factor;
384 offset.X *= size_factor;
385 offset.Y *= size_factor;
389 if (corner & HUD_CORNER_LOWER)
396 case HUD_DIR_RIGHT_LEFT:
397 steppos = v2s32(-1, 0);
399 case HUD_DIR_TOP_BOTTOM:
400 steppos = v2s32(0, 1);
402 case HUD_DIR_BOTTOM_TOP:
403 steppos = v2s32(0, -1);
406 steppos = v2s32(1, 0);
408 steppos.X *= dstd.Width;
409 steppos.Y *= dstd.Height;
411 for (s32 i = 0; i < count / 2; i++)
413 core::rect<s32> srcrect(0, 0, srcd.Width, srcd.Height);
414 core::rect<s32> dstrect(0,0, dstd.Width, dstd.Height);
417 draw2DImageFilterScaled(driver, stat_texture, dstrect, srcrect, NULL, colors, true);
423 core::rect<s32> srcrect(0, 0, srcd.Width / 2, srcd.Height);
424 core::rect<s32> dstrect(0,0, dstd.Width / 2, dstd.Height);
427 draw2DImageFilterScaled(driver, stat_texture, dstrect, srcrect, NULL, colors, true);
432 void Hud::drawHotbar(u16 playeritem) {
434 v2s32 centerlowerpos(m_displaycenter.X, m_screensize.Y);
436 InventoryList *mainlist = inventory->getList("main");
437 if (mainlist == NULL) {
438 //silently ignore this we may not be initialized completely
442 s32 hotbar_itemcount = player->hud_hotbar_itemcount;
443 s32 width = hotbar_itemcount * (m_hotbar_imagesize + m_padding * 2);
444 v2s32 pos = centerlowerpos - v2s32(width / 2, m_hotbar_imagesize + m_padding * 3);
446 if ( (float) width / (float) porting::getWindowSize().X <=
447 g_settings->getFloat("hud_hotbar_max_width")) {
448 if (player->hud_flags & HUD_FLAG_HOTBAR_VISIBLE) {
449 drawItems(pos, hotbar_itemcount, 0, mainlist, playeritem + 1, 0);
455 v2s32 secondpos = pos;
456 pos = pos - v2s32(0, m_hotbar_imagesize + m_padding);
458 if (player->hud_flags & HUD_FLAG_HOTBAR_VISIBLE) {
459 drawItems(pos, hotbar_itemcount/2, 0, mainlist, playeritem + 1, 0);
460 drawItems(secondpos, hotbar_itemcount, hotbar_itemcount/2, mainlist, playeritem + 1, 0);
464 //////////////////////////// compatibility code to be removed //////////////
465 // this is ugly as hell but there's no other way to keep compatibility to
467 if ((player->hud_flags & HUD_FLAG_HEALTHBAR_VISIBLE)) {
468 drawStatbar(v2s32(floor(0.5 * (float)m_screensize.X + 0.5),
469 floor(1 * (float) m_screensize.Y + 0.5)),
470 HUD_CORNER_UPPER, 0, "heart.png",
471 player->hp, v2s32((-10*24)-25,-(48+24+10)), v2s32(24,24));
474 if ((player->hud_flags & HUD_FLAG_BREATHBAR_VISIBLE) &&
475 (player->getBreath() < 11)) {
476 drawStatbar(v2s32(floor(0.5 * (float)m_screensize.X + 0.5),
477 floor(1 * (float) m_screensize.Y + 0.5)),
478 HUD_CORNER_UPPER, 0, "bubble.png",
479 player->getBreath(), v2s32(25,-(48+24+10)), v2s32(24,24));
481 ////////////////////////////////////////////////////////////////////////////
485 void Hud::drawCrosshair() {
487 if (use_crosshair_image) {
488 video::ITexture *crosshair = tsrc->getTexture("crosshair.png");
489 v2u32 size = crosshair->getOriginalSize();
490 v2s32 lsize = v2s32(m_displaycenter.X - (size.X / 2),
491 m_displaycenter.Y - (size.Y / 2));
492 driver->draw2DImage(crosshair, lsize,
493 core::rect<s32>(0, 0, size.X, size.Y),
494 0, crosshair_argb, true);
496 driver->draw2DLine(m_displaycenter - v2s32(10, 0),
497 m_displaycenter + v2s32(10, 0), crosshair_argb);
498 driver->draw2DLine(m_displaycenter - v2s32(0, 10),
499 m_displaycenter + v2s32(0, 10), crosshair_argb);
503 void Hud::setSelectionPos(const v3f &pos, const v3s16 &camera_offset)
505 m_camera_offset = camera_offset;
506 m_selection_pos = pos;
507 m_selection_pos_with_offset = pos - intToFloat(camera_offset, BS);
510 void Hud::drawSelectionMesh()
512 if (!m_use_selection_mesh) {
513 // Draw 3D selection boxes
514 video::SMaterial oldmaterial = driver->getMaterial2D();
515 driver->setMaterial(m_selection_material);
516 for (std::vector<aabb3f>::const_iterator
517 i = m_selection_boxes.begin();
518 i != m_selection_boxes.end(); ++i) {
520 i->MinEdge + m_selection_pos_with_offset,
521 i->MaxEdge + m_selection_pos_with_offset);
523 u32 r = (selectionbox_argb.getRed() *
524 m_selection_mesh_color.getRed() / 255);
525 u32 g = (selectionbox_argb.getGreen() *
526 m_selection_mesh_color.getGreen() / 255);
527 u32 b = (selectionbox_argb.getBlue() *
528 m_selection_mesh_color.getBlue() / 255);
529 driver->draw3DBox(box, video::SColor(255, r, g, b));
531 driver->setMaterial(oldmaterial);
532 } else if (m_selection_mesh) {
533 // Draw selection mesh
534 video::SMaterial oldmaterial = driver->getMaterial2D();
535 driver->setMaterial(m_selection_material);
536 setMeshColor(m_selection_mesh, m_selection_mesh_color);
537 scene::IMesh* mesh = cloneMesh(m_selection_mesh);
538 translateMesh(mesh, m_selection_pos_with_offset);
539 u32 mc = m_selection_mesh->getMeshBufferCount();
540 for (u32 i = 0; i < mc; i++) {
541 scene::IMeshBuffer *buf = mesh->getMeshBuffer(i);
542 driver->drawMeshBuffer(buf);
545 driver->setMaterial(oldmaterial);
549 void Hud::updateSelectionMesh(const v3s16 &camera_offset)
551 m_camera_offset = camera_offset;
552 if (!m_use_selection_mesh)
555 if (m_selection_mesh) {
556 m_selection_mesh->drop();
557 m_selection_mesh = NULL;
560 if (!m_selection_boxes.size()) {
565 // New pointed object, create new mesh.
567 // Texture UV coordinates for selection boxes
568 static f32 texture_uv[24] = {
577 m_selection_mesh = convertNodeboxesToMesh(m_selection_boxes, texture_uv);
579 // scale final halo mesh
580 scaleMesh(m_selection_mesh, v3f(1.08, 1.08, 1.08));
583 void Hud::resizeHotbar() {
584 if (m_screensize != porting::getWindowSize()) {
585 m_hotbar_imagesize = floor(HOTBAR_IMAGE_SIZE * porting::getDisplayDensity() + 0.5);
586 m_hotbar_imagesize *= g_settings->getFloat("hud_scaling");
587 m_padding = m_hotbar_imagesize / 12;
588 m_screensize = porting::getWindowSize();
589 m_displaycenter = v2s32(m_screensize.X/2,m_screensize.Y/2);
593 struct MeshTimeInfo {
598 void drawItemStack(video::IVideoDriver *driver,
600 const ItemStack &item,
601 const core::rect<s32> &rect,
602 const core::rect<s32> *clip,
604 ItemRotationKind rotation_kind)
606 static MeshTimeInfo rotation_time_infos[IT_ROT_NONE];
607 static bool enable_animations =
608 g_settings->getBool("inventory_items_animations");
611 if (rotation_kind < IT_ROT_NONE) {
612 rotation_time_infos[rotation_kind].mesh = NULL;
617 const ItemDefinition &def = item.getDefinition(gamedef->idef());
618 scene::IMesh* mesh = gamedef->idef()->getWieldMesh(def.name, gamedef);
621 driver->clearZBuffer();
623 if (rotation_kind < IT_ROT_NONE) {
624 MeshTimeInfo &ti = rotation_time_infos[rotation_kind];
625 if (mesh != ti.mesh) {
627 ti.time = getTimeMs();
629 delta = porting::getDeltaMs(ti.time, getTimeMs()) % 100000;
632 core::rect<s32> oldViewPort = driver->getViewPort();
633 core::matrix4 oldProjMat = driver->getTransform(video::ETS_PROJECTION);
634 core::matrix4 oldViewMat = driver->getTransform(video::ETS_VIEW);
635 core::matrix4 ProjMatrix;
636 ProjMatrix.buildProjectionMatrixOrthoLH(2, 2, -1, 100);
637 driver->setTransform(video::ETS_PROJECTION, ProjMatrix);
638 driver->setTransform(video::ETS_VIEW, ProjMatrix);
639 core::matrix4 matrix;
640 matrix.makeIdentity();
642 if (enable_animations) {
643 float timer_f = (float)delta / 5000.0;
644 matrix.setRotationDegrees(core::vector3df(0, 360 * timer_f, 0));
647 driver->setTransform(video::ETS_WORLD, matrix);
648 driver->setViewPort(rect);
650 u32 mc = mesh->getMeshBufferCount();
651 for (u32 j = 0; j < mc; ++j) {
652 scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
653 video::SMaterial &material = buf->getMaterial();
654 material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
655 material.Lighting = false;
656 driver->setMaterial(material);
657 driver->drawMeshBuffer(buf);
660 driver->setTransform(video::ETS_VIEW, oldViewMat);
661 driver->setTransform(video::ETS_PROJECTION, oldProjMat);
662 driver->setViewPort(oldViewPort);
665 if(def.type == ITEM_TOOL && item.wear != 0)
667 // Draw a progressbar
668 float barheight = rect.getHeight()/16;
669 float barpad_x = rect.getWidth()/16;
670 float barpad_y = rect.getHeight()/16;
671 core::rect<s32> progressrect(
672 rect.UpperLeftCorner.X + barpad_x,
673 rect.LowerRightCorner.Y - barpad_y - barheight,
674 rect.LowerRightCorner.X - barpad_x,
675 rect.LowerRightCorner.Y - barpad_y);
677 // Shrink progressrect by amount of tool damage
678 float wear = item.wear / 65535.0;
680 wear * progressrect.UpperLeftCorner.X +
681 (1-wear) * progressrect.LowerRightCorner.X;
683 // Compute progressbar color
685 // wear = 0.5: yellow
687 video::SColor color(255,255,255,255);
688 int wear_i = MYMIN(floor(wear * 600), 511);
689 wear_i = MYMIN(wear_i + 10, 511);
691 color.set(255, wear_i, 255, 0);
693 color.set(255, 255, 511-wear_i, 0);
695 core::rect<s32> progressrect2 = progressrect;
696 progressrect2.LowerRightCorner.X = progressmid;
697 driver->draw2DRectangle(color, progressrect2, clip);
699 color = video::SColor(255,0,0,0);
700 progressrect2 = progressrect;
701 progressrect2.UpperLeftCorner.X = progressmid;
702 driver->draw2DRectangle(color, progressrect2, clip);
705 if(font != NULL && item.count >= 2)
707 // Get the item count as a string
708 std::string text = itos(item.count);
709 v2u32 dim = font->getDimension(utf8_to_wide(text).c_str());
710 v2s32 sdim(dim.X,dim.Y);
712 core::rect<s32> rect2(
713 /*rect.UpperLeftCorner,
714 core::dimension2d<u32>(rect.getWidth(), 15)*/
715 rect.LowerRightCorner - sdim,
719 video::SColor bgcolor(128,0,0,0);
720 driver->draw2DRectangle(bgcolor, rect2, clip);
722 video::SColor color(255,255,255,255);
723 font->draw(text.c_str(), rect2, color, false, false, clip);