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"
25 #include "util/string.h"
29 #include "inventory.h"
30 #include "client/tile.h"
31 #include "localplayer.h"
34 #include "fontengine.h"
35 #include "guiscalingfilter.h"
37 #include <IGUIStaticText.h>
39 #ifdef HAVE_TOUCHSCREENGUI
40 #include "touchscreengui.h"
43 Hud::Hud(video::IVideoDriver *driver, scene::ISceneManager* smgr,
44 gui::IGUIEnvironment* guienv, IGameDef *gamedef, LocalPlayer *player,
47 this->driver = driver;
49 this->guienv = guienv;
50 this->gamedef = gamedef;
51 this->player = player;
52 this->inventory = inventory;
54 m_hud_scaling = g_settings->getFloat("hud_scaling");
55 m_screensize = v2u32(0, 0);
56 m_displaycenter = v2s32(0, 0);
57 m_hotbar_imagesize = floor(HOTBAR_IMAGE_SIZE * porting::getDisplayDensity() + 0.5);
58 m_hotbar_imagesize *= m_hud_scaling;
59 m_padding = m_hotbar_imagesize / 12;
61 for (unsigned int i = 0; i < 4; i++)
62 hbar_colors[i] = video::SColor(255, 255, 255, 255);
64 tsrc = gamedef->getTextureSource();
66 v3f crosshair_color = g_settings->getV3F("crosshair_color");
67 u32 cross_r = rangelim(myround(crosshair_color.X), 0, 255);
68 u32 cross_g = rangelim(myround(crosshair_color.Y), 0, 255);
69 u32 cross_b = rangelim(myround(crosshair_color.Z), 0, 255);
70 u32 cross_a = rangelim(g_settings->getS32("crosshair_alpha"), 0, 255);
71 crosshair_argb = video::SColor(cross_a, cross_r, cross_g, cross_b);
73 v3f selectionbox_color = g_settings->getV3F("selectionbox_color");
74 u32 sbox_r = rangelim(myround(selectionbox_color.X), 0, 255);
75 u32 sbox_g = rangelim(myround(selectionbox_color.Y), 0, 255);
76 u32 sbox_b = rangelim(myround(selectionbox_color.Z), 0, 255);
77 selectionbox_argb = video::SColor(255, sbox_r, sbox_g, sbox_b);
79 use_crosshair_image = tsrc->isKnownSourceImage("crosshair.png");
82 use_hotbar_image = false;
83 hotbar_selected_image = "";
84 use_hotbar_selected_image = false;
86 m_selection_mesh = NULL;
87 m_selection_boxes.clear();
90 m_selection_pos = v3f(0.0, 0.0, 0.0);
91 std::string mode = g_settings->get("node_highlighting");
92 m_selection_material.Lighting = false;
94 if (g_settings->getBool("enable_shaders")) {
95 IShaderSource *shdrsrc = gamedef->getShaderSource();
96 u16 shader_id = shdrsrc->getShader(
97 mode == "halo" ? "selection_shader" : "default_shader", 1, 1);
98 m_selection_material.MaterialType = shdrsrc->getShaderInfo(shader_id).material;
100 m_selection_material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
104 m_use_selection_mesh = false;
105 m_selection_material.Thickness =
106 rangelim(g_settings->getS16("selectionbox_width"), 1, 5);
107 } else if (mode == "halo") {
108 m_use_selection_mesh = true;
109 m_selection_material.setTexture(0, tsrc->getTextureForMesh("halo.png"));
110 m_selection_material.setFlag(video::EMF_BACK_FACE_CULLING, true);
112 m_selection_material.MaterialType = video::EMT_SOLID;
118 if (m_selection_mesh)
119 m_selection_mesh->drop();
122 void Hud::drawItem(const ItemStack &item, const core::rect<s32>& rect,
126 /* draw hihlighting around selected item */
127 if (use_hotbar_selected_image) {
128 core::rect<s32> imgrect2 = rect;
129 imgrect2.UpperLeftCorner.X -= (m_padding*2);
130 imgrect2.UpperLeftCorner.Y -= (m_padding*2);
131 imgrect2.LowerRightCorner.X += (m_padding*2);
132 imgrect2.LowerRightCorner.Y += (m_padding*2);
133 video::ITexture *texture = tsrc->getTexture(hotbar_selected_image);
134 core::dimension2di imgsize(texture->getOriginalSize());
135 draw2DImageFilterScaled(driver, texture, imgrect2,
136 core::rect<s32>(core::position2d<s32>(0,0), imgsize),
137 NULL, hbar_colors, true);
139 video::SColor c_outside(255,255,0,0);
140 //video::SColor c_outside(255,0,0,0);
141 //video::SColor c_inside(255,192,192,192);
142 s32 x1 = rect.UpperLeftCorner.X;
143 s32 y1 = rect.UpperLeftCorner.Y;
144 s32 x2 = rect.LowerRightCorner.X;
145 s32 y2 = rect.LowerRightCorner.Y;
146 // Black base borders
147 driver->draw2DRectangle(c_outside,
149 v2s32(x1 - m_padding, y1 - m_padding),
150 v2s32(x2 + m_padding, y1)
152 driver->draw2DRectangle(c_outside,
154 v2s32(x1 - m_padding, y2),
155 v2s32(x2 + m_padding, y2 + m_padding)
157 driver->draw2DRectangle(c_outside,
159 v2s32(x1 - m_padding, y1),
162 driver->draw2DRectangle(c_outside,
165 v2s32(x2 + m_padding, y2)
167 /*// Light inside borders
168 driver->draw2DRectangle(c_inside,
170 v2s32(x1 - padding/2, y1 - padding/2),
171 v2s32(x2 + padding/2, y1)
173 driver->draw2DRectangle(c_inside,
175 v2s32(x1 - padding/2, y2),
176 v2s32(x2 + padding/2, y2 + padding/2)
178 driver->draw2DRectangle(c_inside,
180 v2s32(x1 - padding/2, y1),
183 driver->draw2DRectangle(c_inside,
186 v2s32(x2 + padding/2, y2)
192 video::SColor bgcolor2(128, 0, 0, 0);
193 if (!use_hotbar_image)
194 driver->draw2DRectangle(bgcolor2, rect, NULL);
195 drawItemStack(driver, g_fontengine->getFont(), item, rect, NULL,
196 gamedef, selected ? IT_ROT_SELECTED : IT_ROT_NONE);
199 //NOTE: selectitem = 0 -> no selected; selectitem 1-based
200 void Hud::drawItems(v2s32 upperleftpos, v2s32 screen_offset, s32 itemcount,
201 s32 inv_offset, InventoryList *mainlist, u16 selectitem, u16 direction)
203 #ifdef HAVE_TOUCHSCREENGUI
204 if (g_touchscreengui && inv_offset == 0)
205 g_touchscreengui->resetHud();
208 s32 height = m_hotbar_imagesize + m_padding * 2;
209 s32 width = (itemcount - inv_offset) * (m_hotbar_imagesize + m_padding * 2);
211 if (direction == HUD_DIR_TOP_BOTTOM || direction == HUD_DIR_BOTTOM_TOP) {
217 // Position of upper left corner of bar
218 v2s32 pos = screen_offset;
219 pos.X *= m_hud_scaling * porting::getDisplayDensity();
220 pos.Y *= m_hud_scaling * porting::getDisplayDensity();
223 // Store hotbar_image in member variable, used by drawItem()
224 if (hotbar_image != player->hotbar_image) {
225 hotbar_image = player->hotbar_image;
226 if (hotbar_image != "")
227 use_hotbar_image = tsrc->isKnownSourceImage(hotbar_image);
229 use_hotbar_image = false;
232 // Store hotbar_selected_image in member variable, used by drawItem()
233 if (hotbar_selected_image != player->hotbar_selected_image) {
234 hotbar_selected_image = player->hotbar_selected_image;
235 if (hotbar_selected_image != "")
236 use_hotbar_selected_image = tsrc->isKnownSourceImage(hotbar_selected_image);
238 use_hotbar_selected_image = false;
241 // draw customized item background
242 if (use_hotbar_image) {
243 core::rect<s32> imgrect2(-m_padding/2, -m_padding/2,
244 width+m_padding/2, height+m_padding/2);
245 core::rect<s32> rect2 = imgrect2 + pos;
246 video::ITexture *texture = tsrc->getTexture(hotbar_image);
247 core::dimension2di imgsize(texture->getOriginalSize());
248 draw2DImageFilterScaled(driver, texture, rect2,
249 core::rect<s32>(core::position2d<s32>(0,0), imgsize),
250 NULL, hbar_colors, true);
254 core::rect<s32> imgrect(0, 0, m_hotbar_imagesize, m_hotbar_imagesize);
255 for (s32 i = inv_offset; i < itemcount && (size_t)i < mainlist->getSize(); i++) {
256 s32 fullimglen = m_hotbar_imagesize + m_padding * 2;
260 case HUD_DIR_RIGHT_LEFT:
261 steppos = v2s32(-(m_padding + (i - inv_offset) * fullimglen), m_padding);
263 case HUD_DIR_TOP_BOTTOM:
264 steppos = v2s32(m_padding, m_padding + (i - inv_offset) * fullimglen);
266 case HUD_DIR_BOTTOM_TOP:
267 steppos = v2s32(m_padding, -(m_padding + (i - inv_offset) * fullimglen));
270 steppos = v2s32(m_padding + (i - inv_offset) * fullimglen, m_padding);
274 drawItem(mainlist->getItem(i), (imgrect + pos + steppos), (i + 1) == selectitem);
276 #ifdef HAVE_TOUCHSCREENGUI
277 if (g_touchscreengui)
278 g_touchscreengui->registerHudItem(i, (imgrect + pos + steppos));
284 void Hud::drawLuaElements(const v3s16 &camera_offset)
286 u32 text_height = g_fontengine->getTextHeight();
287 irr::gui::IGUIFont* font = g_fontengine->getFont();
288 for (size_t i = 0; i != player->maxHudId(); i++) {
289 HudElement *e = player->getHud(i);
293 v2s32 pos(floor(e->pos.X * (float) m_screensize.X + 0.5),
294 floor(e->pos.Y * (float) m_screensize.Y + 0.5));
296 case HUD_ELEM_IMAGE: {
297 video::ITexture *texture = tsrc->getTexture(e->text);
301 const video::SColor color(255, 255, 255, 255);
302 const video::SColor colors[] = {color, color, color, color};
303 core::dimension2di imgsize(texture->getOriginalSize());
304 v2s32 dstsize(imgsize.Width * e->scale.X,
305 imgsize.Height * e->scale.Y);
307 dstsize.X = m_screensize.X * (e->scale.X * -0.01);
309 dstsize.Y = m_screensize.Y * (e->scale.Y * -0.01);
310 v2s32 offset((e->align.X - 1.0) * dstsize.X / 2,
311 (e->align.Y - 1.0) * dstsize.Y / 2);
312 core::rect<s32> rect(0, 0, dstsize.X, dstsize.Y);
313 rect += pos + offset + v2s32(e->offset.X, e->offset.Y);
314 draw2DImageFilterScaled(driver, texture, rect,
315 core::rect<s32>(core::position2d<s32>(0,0), imgsize),
318 case HUD_ELEM_TEXT: {
319 video::SColor color(255, (e->number >> 16) & 0xFF,
320 (e->number >> 8) & 0xFF,
321 (e->number >> 0) & 0xFF);
322 core::rect<s32> size(0, 0, e->scale.X, text_height * e->scale.Y);
323 std::wstring text = unescape_enriched(utf8_to_wide(e->text));
324 core::dimension2d<u32> textsize = font->getDimension(text.c_str());
325 v2s32 offset((e->align.X - 1.0) * (textsize.Width / 2),
326 (e->align.Y - 1.0) * (textsize.Height / 2));
327 v2s32 offs(e->offset.X, e->offset.Y);
328 font->draw(text.c_str(), size + pos + offset + offs, color);
330 case HUD_ELEM_STATBAR: {
331 v2s32 offs(e->offset.X, e->offset.Y);
332 drawStatbar(pos, HUD_CORNER_UPPER, e->dir, e->text, e->number, offs, e->size);
334 case HUD_ELEM_INVENTORY: {
335 InventoryList *inv = inventory->getList(e->text);
336 drawItems(pos, v2s32(e->offset.X, e->offset.Y), e->number, 0,
337 inv, e->item, e->dir);
339 case HUD_ELEM_WAYPOINT: {
340 v3f p_pos = player->getPosition() / BS;
341 v3f w_pos = e->world_pos * BS;
342 float distance = floor(10 * p_pos.getDistanceFrom(e->world_pos)) / 10;
343 scene::ICameraSceneNode* camera = smgr->getActiveCamera();
344 w_pos -= intToFloat(camera_offset, BS);
345 core::matrix4 trans = camera->getProjectionMatrix();
346 trans *= camera->getViewMatrix();
347 f32 transformed_pos[4] = { w_pos.X, w_pos.Y, w_pos.Z, 1.0f };
348 trans.multiplyWith1x4Matrix(transformed_pos);
349 if (transformed_pos[3] < 0)
351 f32 zDiv = transformed_pos[3] == 0.0f ? 1.0f :
352 core::reciprocal(transformed_pos[3]);
353 pos.X = m_screensize.X * (0.5 * transformed_pos[0] * zDiv + 0.5);
354 pos.Y = m_screensize.Y * (0.5 - transformed_pos[1] * zDiv * 0.5);
355 video::SColor color(255, (e->number >> 16) & 0xFF,
356 (e->number >> 8) & 0xFF,
357 (e->number >> 0) & 0xFF);
358 core::rect<s32> size(0, 0, 200, 2 * text_height);
359 std::wstring text = unescape_enriched(utf8_to_wide(e->name));
360 font->draw(text.c_str(), size + pos, color);
361 std::ostringstream os;
362 os << distance << e->text;
363 text = unescape_enriched(utf8_to_wide(os.str()));
364 pos.Y += text_height;
365 font->draw(text.c_str(), size + pos, color);
368 infostream << "Hud::drawLuaElements: ignoring drawform " << e->type <<
369 " of hud element ID " << i << " due to unrecognized type" << std::endl;
375 void Hud::drawStatbar(v2s32 pos, u16 corner, u16 drawdir, std::string texture,
376 s32 count, v2s32 offset, v2s32 size)
378 const video::SColor color(255, 255, 255, 255);
379 const video::SColor colors[] = {color, color, color, color};
381 video::ITexture *stat_texture = tsrc->getTexture(texture);
385 core::dimension2di srcd(stat_texture->getOriginalSize());
386 core::dimension2di dstd;
387 if (size == v2s32()) {
390 float size_factor = m_hud_scaling * porting::getDisplayDensity();
391 dstd.Height = size.Y * size_factor;
392 dstd.Width = size.X * size_factor;
393 offset.X *= size_factor;
394 offset.Y *= size_factor;
398 if (corner & HUD_CORNER_LOWER)
405 case HUD_DIR_RIGHT_LEFT:
406 steppos = v2s32(-1, 0);
408 case HUD_DIR_TOP_BOTTOM:
409 steppos = v2s32(0, 1);
411 case HUD_DIR_BOTTOM_TOP:
412 steppos = v2s32(0, -1);
415 steppos = v2s32(1, 0);
417 steppos.X *= dstd.Width;
418 steppos.Y *= dstd.Height;
420 for (s32 i = 0; i < count / 2; i++)
422 core::rect<s32> srcrect(0, 0, srcd.Width, srcd.Height);
423 core::rect<s32> dstrect(0,0, dstd.Width, dstd.Height);
426 draw2DImageFilterScaled(driver, stat_texture, dstrect, srcrect, NULL, colors, true);
432 core::rect<s32> srcrect(0, 0, srcd.Width / 2, srcd.Height);
433 core::rect<s32> dstrect(0,0, dstd.Width / 2, dstd.Height);
436 draw2DImageFilterScaled(driver, stat_texture, dstrect, srcrect, NULL, colors, true);
441 void Hud::drawHotbar(u16 playeritem) {
443 v2s32 centerlowerpos(m_displaycenter.X, m_screensize.Y);
445 InventoryList *mainlist = inventory->getList("main");
446 if (mainlist == NULL) {
447 //silently ignore this we may not be initialized completely
451 s32 hotbar_itemcount = player->hud_hotbar_itemcount;
452 s32 width = hotbar_itemcount * (m_hotbar_imagesize + m_padding * 2);
453 v2s32 pos = centerlowerpos - v2s32(width / 2, m_hotbar_imagesize + m_padding * 3);
455 if ( (float) width / (float) porting::getWindowSize().X <=
456 g_settings->getFloat("hud_hotbar_max_width")) {
457 if (player->hud_flags & HUD_FLAG_HOTBAR_VISIBLE) {
458 drawItems(pos, v2s32(0, 0), hotbar_itemcount, 0, mainlist, playeritem + 1, 0);
463 v2s32 secondpos = pos;
464 pos = pos - v2s32(0, m_hotbar_imagesize + m_padding);
466 if (player->hud_flags & HUD_FLAG_HOTBAR_VISIBLE) {
467 drawItems(pos, v2s32(0, 0), hotbar_itemcount / 2, 0,
468 mainlist, playeritem + 1, 0);
469 drawItems(secondpos, v2s32(0, 0), hotbar_itemcount,
470 hotbar_itemcount / 2, mainlist, playeritem + 1, 0);
474 //////////////////////////// compatibility code to be removed //////////////
475 // this is ugly as hell but there's no other way to keep compatibility to
477 if ((player->hud_flags & HUD_FLAG_HEALTHBAR_VISIBLE)) {
478 drawStatbar(v2s32(floor(0.5 * (float)m_screensize.X + 0.5),
479 floor(1 * (float) m_screensize.Y + 0.5)),
480 HUD_CORNER_UPPER, 0, "heart.png",
481 player->hp, v2s32((-10*24)-25,-(48+24+10)), v2s32(24,24));
484 if ((player->hud_flags & HUD_FLAG_BREATHBAR_VISIBLE) &&
485 (player->getBreath() < 11)) {
486 drawStatbar(v2s32(floor(0.5 * (float)m_screensize.X + 0.5),
487 floor(1 * (float) m_screensize.Y + 0.5)),
488 HUD_CORNER_UPPER, 0, "bubble.png",
489 player->getBreath(), v2s32(25,-(48+24+10)), v2s32(24,24));
491 ////////////////////////////////////////////////////////////////////////////
495 void Hud::drawCrosshair()
497 if (use_crosshair_image) {
498 video::ITexture *crosshair = tsrc->getTexture("crosshair.png");
499 v2u32 size = crosshair->getOriginalSize();
500 v2s32 lsize = v2s32(m_displaycenter.X - (size.X / 2),
501 m_displaycenter.Y - (size.Y / 2));
502 driver->draw2DImage(crosshair, lsize,
503 core::rect<s32>(0, 0, size.X, size.Y),
504 0, crosshair_argb, true);
506 driver->draw2DLine(m_displaycenter - v2s32(10, 0),
507 m_displaycenter + v2s32(10, 0), crosshair_argb);
508 driver->draw2DLine(m_displaycenter - v2s32(0, 10),
509 m_displaycenter + v2s32(0, 10), crosshair_argb);
513 void Hud::setSelectionPos(const v3f &pos, const v3s16 &camera_offset)
515 m_camera_offset = camera_offset;
516 m_selection_pos = pos;
517 m_selection_pos_with_offset = pos - intToFloat(camera_offset, BS);
520 void Hud::drawSelectionMesh()
522 if (!m_use_selection_mesh) {
523 // Draw 3D selection boxes
524 video::SMaterial oldmaterial = driver->getMaterial2D();
525 driver->setMaterial(m_selection_material);
526 for (std::vector<aabb3f>::const_iterator
527 i = m_selection_boxes.begin();
528 i != m_selection_boxes.end(); ++i) {
530 i->MinEdge + m_selection_pos_with_offset,
531 i->MaxEdge + m_selection_pos_with_offset);
533 u32 r = (selectionbox_argb.getRed() *
534 m_selection_mesh_color.getRed() / 255);
535 u32 g = (selectionbox_argb.getGreen() *
536 m_selection_mesh_color.getGreen() / 255);
537 u32 b = (selectionbox_argb.getBlue() *
538 m_selection_mesh_color.getBlue() / 255);
539 driver->draw3DBox(box, video::SColor(255, r, g, b));
541 driver->setMaterial(oldmaterial);
542 } else if (m_selection_mesh) {
543 // Draw selection mesh
544 video::SMaterial oldmaterial = driver->getMaterial2D();
545 driver->setMaterial(m_selection_material);
546 setMeshColor(m_selection_mesh, m_selection_mesh_color);
547 scene::IMesh* mesh = cloneMesh(m_selection_mesh);
548 translateMesh(mesh, m_selection_pos_with_offset);
549 u32 mc = m_selection_mesh->getMeshBufferCount();
550 for (u32 i = 0; i < mc; i++) {
551 scene::IMeshBuffer *buf = mesh->getMeshBuffer(i);
552 driver->drawMeshBuffer(buf);
555 driver->setMaterial(oldmaterial);
559 void Hud::updateSelectionMesh(const v3s16 &camera_offset)
561 m_camera_offset = camera_offset;
562 if (!m_use_selection_mesh)
565 if (m_selection_mesh) {
566 m_selection_mesh->drop();
567 m_selection_mesh = NULL;
570 if (!m_selection_boxes.size()) {
575 // New pointed object, create new mesh.
577 // Texture UV coordinates for selection boxes
578 static f32 texture_uv[24] = {
587 // Use single halo box instead of multiple overlapping boxes.
588 // Temporary solution - problem can be solved with multiple
589 // rendering targets, or some method to remove inner surfaces.
590 // Thats because of halo transparency.
592 aabb3f halo_box(100.0, 100.0, 100.0, -100.0, -100.0, -100.0);
593 m_halo_boxes.clear();
595 for (std::vector<aabb3f>::iterator
596 i = m_selection_boxes.begin();
597 i != m_selection_boxes.end(); ++i) {
598 halo_box.addInternalBox(*i);
601 m_halo_boxes.push_back(halo_box);
602 m_selection_mesh = convertNodeboxesToMesh(
603 m_halo_boxes, texture_uv, 0.5);
606 void Hud::resizeHotbar() {
607 if (m_screensize != porting::getWindowSize()) {
608 m_hotbar_imagesize = floor(HOTBAR_IMAGE_SIZE * porting::getDisplayDensity() + 0.5);
609 m_hotbar_imagesize *= m_hud_scaling;
610 m_padding = m_hotbar_imagesize / 12;
611 m_screensize = porting::getWindowSize();
612 m_displaycenter = v2s32(m_screensize.X/2,m_screensize.Y/2);
616 struct MeshTimeInfo {
621 void drawItemStack(video::IVideoDriver *driver,
623 const ItemStack &item,
624 const core::rect<s32> &rect,
625 const core::rect<s32> *clip,
627 ItemRotationKind rotation_kind)
629 static MeshTimeInfo rotation_time_infos[IT_ROT_NONE];
630 static bool enable_animations =
631 g_settings->getBool("inventory_items_animations");
634 if (rotation_kind < IT_ROT_NONE) {
635 rotation_time_infos[rotation_kind].mesh = NULL;
640 const ItemDefinition &def = item.getDefinition(gamedef->idef());
641 scene::IMesh* mesh = gamedef->idef()->getWieldMesh(def.name, gamedef);
644 driver->clearZBuffer();
646 if (rotation_kind < IT_ROT_NONE) {
647 MeshTimeInfo &ti = rotation_time_infos[rotation_kind];
648 if (mesh != ti.mesh) {
650 ti.time = getTimeMs();
652 delta = porting::getDeltaMs(ti.time, getTimeMs()) % 100000;
655 core::rect<s32> oldViewPort = driver->getViewPort();
656 core::matrix4 oldProjMat = driver->getTransform(video::ETS_PROJECTION);
657 core::matrix4 oldViewMat = driver->getTransform(video::ETS_VIEW);
658 core::matrix4 ProjMatrix;
659 ProjMatrix.buildProjectionMatrixOrthoLH(2, 2, -1, 100);
660 driver->setTransform(video::ETS_PROJECTION, ProjMatrix);
661 driver->setTransform(video::ETS_VIEW, ProjMatrix);
662 core::matrix4 matrix;
663 matrix.makeIdentity();
665 if (enable_animations) {
666 float timer_f = (float)delta / 5000.0;
667 matrix.setRotationDegrees(core::vector3df(0, 360 * timer_f, 0));
670 driver->setTransform(video::ETS_WORLD, matrix);
671 driver->setViewPort(rect);
673 u32 mc = mesh->getMeshBufferCount();
674 for (u32 j = 0; j < mc; ++j) {
675 scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
676 video::SMaterial &material = buf->getMaterial();
677 material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
678 material.Lighting = false;
679 driver->setMaterial(material);
680 driver->drawMeshBuffer(buf);
683 driver->setTransform(video::ETS_VIEW, oldViewMat);
684 driver->setTransform(video::ETS_PROJECTION, oldProjMat);
685 driver->setViewPort(oldViewPort);
688 if(def.type == ITEM_TOOL && item.wear != 0)
690 // Draw a progressbar
691 float barheight = rect.getHeight()/16;
692 float barpad_x = rect.getWidth()/16;
693 float barpad_y = rect.getHeight()/16;
694 core::rect<s32> progressrect(
695 rect.UpperLeftCorner.X + barpad_x,
696 rect.LowerRightCorner.Y - barpad_y - barheight,
697 rect.LowerRightCorner.X - barpad_x,
698 rect.LowerRightCorner.Y - barpad_y);
700 // Shrink progressrect by amount of tool damage
701 float wear = item.wear / 65535.0;
703 wear * progressrect.UpperLeftCorner.X +
704 (1-wear) * progressrect.LowerRightCorner.X;
706 // Compute progressbar color
708 // wear = 0.5: yellow
710 video::SColor color(255,255,255,255);
711 int wear_i = MYMIN(floor(wear * 600), 511);
712 wear_i = MYMIN(wear_i + 10, 511);
714 color.set(255, wear_i, 255, 0);
716 color.set(255, 255, 511-wear_i, 0);
718 core::rect<s32> progressrect2 = progressrect;
719 progressrect2.LowerRightCorner.X = progressmid;
720 driver->draw2DRectangle(color, progressrect2, clip);
722 color = video::SColor(255,0,0,0);
723 progressrect2 = progressrect;
724 progressrect2.UpperLeftCorner.X = progressmid;
725 driver->draw2DRectangle(color, progressrect2, clip);
728 if(font != NULL && item.count >= 2)
730 // Get the item count as a string
731 std::string text = itos(item.count);
732 v2u32 dim = font->getDimension(utf8_to_wide(text).c_str());
733 v2s32 sdim(dim.X,dim.Y);
735 core::rect<s32> rect2(
736 /*rect.UpperLeftCorner,
737 core::dimension2d<u32>(rect.getWidth(), 15)*/
738 rect.LowerRightCorner - sdim,
742 video::SColor bgcolor(128,0,0,0);
743 driver->draw2DRectangle(bgcolor, rect2, clip);
745 video::SColor color(255,255,255,255);
746 font->draw(text.c_str(), rect2, color, false, false, clip);