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"
27 #include "inventory.h"
28 #include "client/tile.h"
29 #include "localplayer.h"
32 #include "fontengine.h"
33 #include "guiscalingfilter.h"
35 #include <IGUIStaticText.h>
37 #ifdef HAVE_TOUCHSCREENGUI
38 #include "touchscreengui.h"
41 Hud::Hud(video::IVideoDriver *driver, scene::ISceneManager* smgr,
42 gui::IGUIEnvironment* guienv, Client *client, LocalPlayer *player,
45 this->driver = driver;
47 this->guienv = guienv;
48 this->client = client;
49 this->player = player;
50 this->inventory = inventory;
52 m_hud_scaling = g_settings->getFloat("hud_scaling");
53 m_screensize = v2u32(0, 0);
54 m_displaycenter = v2s32(0, 0);
55 m_hotbar_imagesize = floor(HOTBAR_IMAGE_SIZE * porting::getDisplayDensity() + 0.5);
56 m_hotbar_imagesize *= m_hud_scaling;
57 m_padding = m_hotbar_imagesize / 12;
59 for (unsigned int i = 0; i < 4; i++)
60 hbar_colors[i] = video::SColor(255, 255, 255, 255);
62 tsrc = client->getTextureSource();
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);
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);
77 use_crosshair_image = tsrc->isKnownSourceImage("crosshair.png");
80 use_hotbar_image = false;
81 hotbar_selected_image = "";
82 use_hotbar_selected_image = false;
84 m_selection_mesh = NULL;
85 m_selection_boxes.clear();
88 m_selection_pos = v3f(0.0, 0.0, 0.0);
89 std::string mode = g_settings->get("node_highlighting");
90 m_selection_material.Lighting = false;
92 if (g_settings->getBool("enable_shaders")) {
93 IShaderSource *shdrsrc = client->getShaderSource();
94 u16 shader_id = shdrsrc->getShader(
95 mode == "halo" ? "selection_shader" : "default_shader", 1, 1);
96 m_selection_material.MaterialType = shdrsrc->getShaderInfo(shader_id).material;
98 m_selection_material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
102 m_use_selection_mesh = false;
103 m_selection_material.Thickness =
104 rangelim(g_settings->getS16("selectionbox_width"), 1, 5);
105 } else if (mode == "halo") {
106 m_use_selection_mesh = true;
107 m_selection_material.setTexture(0, tsrc->getTextureForMesh("halo.png"));
108 m_selection_material.setFlag(video::EMF_BACK_FACE_CULLING, true);
110 m_selection_material.MaterialType = video::EMT_SOLID;
116 if (m_selection_mesh)
117 m_selection_mesh->drop();
120 void Hud::drawItem(const ItemStack &item, const core::rect<s32>& rect,
124 /* draw hihlighting around selected item */
125 if (use_hotbar_selected_image) {
126 core::rect<s32> imgrect2 = rect;
127 imgrect2.UpperLeftCorner.X -= (m_padding*2);
128 imgrect2.UpperLeftCorner.Y -= (m_padding*2);
129 imgrect2.LowerRightCorner.X += (m_padding*2);
130 imgrect2.LowerRightCorner.Y += (m_padding*2);
131 video::ITexture *texture = tsrc->getTexture(hotbar_selected_image);
132 core::dimension2di imgsize(texture->getOriginalSize());
133 draw2DImageFilterScaled(driver, texture, imgrect2,
134 core::rect<s32>(core::position2d<s32>(0,0), imgsize),
135 NULL, hbar_colors, true);
137 video::SColor c_outside(255,255,0,0);
138 //video::SColor c_outside(255,0,0,0);
139 //video::SColor c_inside(255,192,192,192);
140 s32 x1 = rect.UpperLeftCorner.X;
141 s32 y1 = rect.UpperLeftCorner.Y;
142 s32 x2 = rect.LowerRightCorner.X;
143 s32 y2 = rect.LowerRightCorner.Y;
144 // Black base borders
145 driver->draw2DRectangle(c_outside,
147 v2s32(x1 - m_padding, y1 - m_padding),
148 v2s32(x2 + m_padding, y1)
150 driver->draw2DRectangle(c_outside,
152 v2s32(x1 - m_padding, y2),
153 v2s32(x2 + m_padding, y2 + m_padding)
155 driver->draw2DRectangle(c_outside,
157 v2s32(x1 - m_padding, y1),
160 driver->draw2DRectangle(c_outside,
163 v2s32(x2 + m_padding, y2)
165 /*// Light inside borders
166 driver->draw2DRectangle(c_inside,
168 v2s32(x1 - padding/2, y1 - padding/2),
169 v2s32(x2 + padding/2, y1)
171 driver->draw2DRectangle(c_inside,
173 v2s32(x1 - padding/2, y2),
174 v2s32(x2 + padding/2, y2 + padding/2)
176 driver->draw2DRectangle(c_inside,
178 v2s32(x1 - padding/2, y1),
181 driver->draw2DRectangle(c_inside,
184 v2s32(x2 + padding/2, y2)
190 video::SColor bgcolor2(128, 0, 0, 0);
191 if (!use_hotbar_image)
192 driver->draw2DRectangle(bgcolor2, rect, NULL);
193 drawItemStack(driver, g_fontengine->getFont(), item, rect, NULL,
194 client, selected ? IT_ROT_SELECTED : IT_ROT_NONE);
197 //NOTE: selectitem = 0 -> no selected; selectitem 1-based
198 void Hud::drawItems(v2s32 upperleftpos, v2s32 screen_offset, s32 itemcount,
199 s32 inv_offset, InventoryList *mainlist, u16 selectitem, u16 direction)
201 #ifdef HAVE_TOUCHSCREENGUI
202 if (g_touchscreengui && inv_offset == 0)
203 g_touchscreengui->resetHud();
206 s32 height = m_hotbar_imagesize + m_padding * 2;
207 s32 width = (itemcount - inv_offset) * (m_hotbar_imagesize + m_padding * 2);
209 if (direction == HUD_DIR_TOP_BOTTOM || direction == HUD_DIR_BOTTOM_TOP) {
215 // Position of upper left corner of bar
216 v2s32 pos = screen_offset;
217 pos.X *= m_hud_scaling * porting::getDisplayDensity();
218 pos.Y *= m_hud_scaling * porting::getDisplayDensity();
221 // Store hotbar_image in member variable, used by drawItem()
222 if (hotbar_image != player->hotbar_image) {
223 hotbar_image = player->hotbar_image;
224 if (hotbar_image != "")
225 use_hotbar_image = tsrc->isKnownSourceImage(hotbar_image);
227 use_hotbar_image = false;
230 // Store hotbar_selected_image in member variable, used by drawItem()
231 if (hotbar_selected_image != player->hotbar_selected_image) {
232 hotbar_selected_image = player->hotbar_selected_image;
233 if (hotbar_selected_image != "")
234 use_hotbar_selected_image = tsrc->isKnownSourceImage(hotbar_selected_image);
236 use_hotbar_selected_image = false;
239 // draw customized item background
240 if (use_hotbar_image) {
241 core::rect<s32> imgrect2(-m_padding/2, -m_padding/2,
242 width+m_padding/2, height+m_padding/2);
243 core::rect<s32> rect2 = imgrect2 + pos;
244 video::ITexture *texture = tsrc->getTexture(hotbar_image);
245 core::dimension2di imgsize(texture->getOriginalSize());
246 draw2DImageFilterScaled(driver, texture, rect2,
247 core::rect<s32>(core::position2d<s32>(0,0), imgsize),
248 NULL, hbar_colors, true);
252 core::rect<s32> imgrect(0, 0, m_hotbar_imagesize, m_hotbar_imagesize);
253 for (s32 i = inv_offset; i < itemcount && (size_t)i < mainlist->getSize(); i++) {
254 s32 fullimglen = m_hotbar_imagesize + m_padding * 2;
258 case HUD_DIR_RIGHT_LEFT:
259 steppos = v2s32(-(m_padding + (i - inv_offset) * fullimglen), m_padding);
261 case HUD_DIR_TOP_BOTTOM:
262 steppos = v2s32(m_padding, m_padding + (i - inv_offset) * fullimglen);
264 case HUD_DIR_BOTTOM_TOP:
265 steppos = v2s32(m_padding, -(m_padding + (i - inv_offset) * fullimglen));
268 steppos = v2s32(m_padding + (i - inv_offset) * fullimglen, m_padding);
272 drawItem(mainlist->getItem(i), (imgrect + pos + steppos), (i + 1) == selectitem);
274 #ifdef HAVE_TOUCHSCREENGUI
275 if (g_touchscreengui)
276 g_touchscreengui->registerHudItem(i, (imgrect + pos + steppos));
282 void Hud::drawLuaElements(const v3s16 &camera_offset)
284 u32 text_height = g_fontengine->getTextHeight();
285 irr::gui::IGUIFont* font = g_fontengine->getFont();
286 for (size_t i = 0; i != player->maxHudId(); i++) {
287 HudElement *e = player->getHud(i);
291 v2s32 pos(floor(e->pos.X * (float) m_screensize.X + 0.5),
292 floor(e->pos.Y * (float) m_screensize.Y + 0.5));
294 case HUD_ELEM_IMAGE: {
295 video::ITexture *texture = tsrc->getTexture(e->text);
299 const video::SColor color(255, 255, 255, 255);
300 const video::SColor colors[] = {color, color, color, color};
301 core::dimension2di imgsize(texture->getOriginalSize());
302 v2s32 dstsize(imgsize.Width * e->scale.X,
303 imgsize.Height * e->scale.Y);
305 dstsize.X = m_screensize.X * (e->scale.X * -0.01);
307 dstsize.Y = m_screensize.Y * (e->scale.Y * -0.01);
308 v2s32 offset((e->align.X - 1.0) * dstsize.X / 2,
309 (e->align.Y - 1.0) * dstsize.Y / 2);
310 core::rect<s32> rect(0, 0, dstsize.X, dstsize.Y);
311 rect += pos + offset + v2s32(e->offset.X, e->offset.Y);
312 draw2DImageFilterScaled(driver, texture, rect,
313 core::rect<s32>(core::position2d<s32>(0,0), imgsize),
316 case HUD_ELEM_TEXT: {
317 video::SColor color(255, (e->number >> 16) & 0xFF,
318 (e->number >> 8) & 0xFF,
319 (e->number >> 0) & 0xFF);
320 core::rect<s32> size(0, 0, e->scale.X, text_height * e->scale.Y);
321 std::wstring text = unescape_enriched(utf8_to_wide(e->text));
322 core::dimension2d<u32> textsize = font->getDimension(text.c_str());
323 v2s32 offset((e->align.X - 1.0) * (textsize.Width / 2),
324 (e->align.Y - 1.0) * (textsize.Height / 2));
325 v2s32 offs(e->offset.X, e->offset.Y);
326 font->draw(text.c_str(), size + pos + offset + offs, color);
328 case HUD_ELEM_STATBAR: {
329 v2s32 offs(e->offset.X, e->offset.Y);
330 drawStatbar(pos, HUD_CORNER_UPPER, e->dir, e->text, e->number, offs, e->size);
332 case HUD_ELEM_INVENTORY: {
333 InventoryList *inv = inventory->getList(e->text);
334 drawItems(pos, v2s32(e->offset.X, e->offset.Y), e->number, 0,
335 inv, e->item, e->dir);
337 case HUD_ELEM_WAYPOINT: {
338 v3f p_pos = player->getPosition() / BS;
339 v3f w_pos = e->world_pos * BS;
340 float distance = floor(10 * p_pos.getDistanceFrom(e->world_pos)) / 10;
341 scene::ICameraSceneNode* camera = smgr->getActiveCamera();
342 w_pos -= intToFloat(camera_offset, BS);
343 core::matrix4 trans = camera->getProjectionMatrix();
344 trans *= camera->getViewMatrix();
345 f32 transformed_pos[4] = { w_pos.X, w_pos.Y, w_pos.Z, 1.0f };
346 trans.multiplyWith1x4Matrix(transformed_pos);
347 if (transformed_pos[3] < 0)
349 f32 zDiv = transformed_pos[3] == 0.0f ? 1.0f :
350 core::reciprocal(transformed_pos[3]);
351 pos.X = m_screensize.X * (0.5 * transformed_pos[0] * zDiv + 0.5);
352 pos.Y = m_screensize.Y * (0.5 - transformed_pos[1] * zDiv * 0.5);
353 video::SColor color(255, (e->number >> 16) & 0xFF,
354 (e->number >> 8) & 0xFF,
355 (e->number >> 0) & 0xFF);
356 core::rect<s32> size(0, 0, 200, 2 * text_height);
357 std::wstring text = unescape_enriched(utf8_to_wide(e->name));
358 font->draw(text.c_str(), size + pos, color);
359 std::ostringstream os;
360 os << distance << e->text;
361 text = unescape_enriched(utf8_to_wide(os.str()));
362 pos.Y += text_height;
363 font->draw(text.c_str(), size + pos, color);
366 infostream << "Hud::drawLuaElements: ignoring drawform " << e->type <<
367 " of hud element ID " << i << " due to unrecognized type" << std::endl;
373 void Hud::drawStatbar(v2s32 pos, u16 corner, u16 drawdir, std::string texture,
374 s32 count, v2s32 offset, v2s32 size)
376 const video::SColor color(255, 255, 255, 255);
377 const video::SColor colors[] = {color, color, color, color};
379 video::ITexture *stat_texture = tsrc->getTexture(texture);
383 core::dimension2di srcd(stat_texture->getOriginalSize());
384 core::dimension2di dstd;
385 if (size == v2s32()) {
388 float size_factor = m_hud_scaling * porting::getDisplayDensity();
389 dstd.Height = size.Y * size_factor;
390 dstd.Width = size.X * size_factor;
391 offset.X *= size_factor;
392 offset.Y *= size_factor;
396 if (corner & HUD_CORNER_LOWER)
403 case HUD_DIR_RIGHT_LEFT:
404 steppos = v2s32(-1, 0);
406 case HUD_DIR_TOP_BOTTOM:
407 steppos = v2s32(0, 1);
409 case HUD_DIR_BOTTOM_TOP:
410 steppos = v2s32(0, -1);
413 steppos = v2s32(1, 0);
415 steppos.X *= dstd.Width;
416 steppos.Y *= dstd.Height;
418 for (s32 i = 0; i < count / 2; i++)
420 core::rect<s32> srcrect(0, 0, srcd.Width, srcd.Height);
421 core::rect<s32> dstrect(0,0, dstd.Width, dstd.Height);
424 draw2DImageFilterScaled(driver, stat_texture, dstrect, srcrect, NULL, colors, true);
430 core::rect<s32> srcrect(0, 0, srcd.Width / 2, srcd.Height);
431 core::rect<s32> dstrect(0,0, dstd.Width / 2, dstd.Height);
434 draw2DImageFilterScaled(driver, stat_texture, dstrect, srcrect, NULL, colors, true);
439 void Hud::drawHotbar(u16 playeritem) {
441 v2s32 centerlowerpos(m_displaycenter.X, m_screensize.Y);
443 InventoryList *mainlist = inventory->getList("main");
444 if (mainlist == NULL) {
445 //silently ignore this we may not be initialized completely
449 s32 hotbar_itemcount = player->hud_hotbar_itemcount;
450 s32 width = hotbar_itemcount * (m_hotbar_imagesize + m_padding * 2);
451 v2s32 pos = centerlowerpos - v2s32(width / 2, m_hotbar_imagesize + m_padding * 3);
453 if ( (float) width / (float) porting::getWindowSize().X <=
454 g_settings->getFloat("hud_hotbar_max_width")) {
455 if (player->hud_flags & HUD_FLAG_HOTBAR_VISIBLE) {
456 drawItems(pos, v2s32(0, 0), hotbar_itemcount, 0, mainlist, playeritem + 1, 0);
461 v2s32 secondpos = pos;
462 pos = pos - v2s32(0, m_hotbar_imagesize + m_padding);
464 if (player->hud_flags & HUD_FLAG_HOTBAR_VISIBLE) {
465 drawItems(pos, v2s32(0, 0), hotbar_itemcount / 2, 0,
466 mainlist, playeritem + 1, 0);
467 drawItems(secondpos, v2s32(0, 0), hotbar_itemcount,
468 hotbar_itemcount / 2, mainlist, playeritem + 1, 0);
472 //////////////////////////// compatibility code to be removed //////////////
473 // this is ugly as hell but there's no other way to keep compatibility to
475 if ((player->hud_flags & HUD_FLAG_HEALTHBAR_VISIBLE)) {
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, "heart.png",
479 player->hp, v2s32((-10*24)-25,-(48+24+10)), v2s32(24,24));
482 if ((player->hud_flags & HUD_FLAG_BREATHBAR_VISIBLE) &&
483 (player->getBreath() < 11)) {
484 drawStatbar(v2s32(floor(0.5 * (float)m_screensize.X + 0.5),
485 floor(1 * (float) m_screensize.Y + 0.5)),
486 HUD_CORNER_UPPER, 0, "bubble.png",
487 player->getBreath(), v2s32(25,-(48+24+10)), v2s32(24,24));
489 ////////////////////////////////////////////////////////////////////////////
493 void Hud::drawCrosshair()
495 if (use_crosshair_image) {
496 video::ITexture *crosshair = tsrc->getTexture("crosshair.png");
497 v2u32 size = crosshair->getOriginalSize();
498 v2s32 lsize = v2s32(m_displaycenter.X - (size.X / 2),
499 m_displaycenter.Y - (size.Y / 2));
500 driver->draw2DImage(crosshair, lsize,
501 core::rect<s32>(0, 0, size.X, size.Y),
502 0, crosshair_argb, true);
504 driver->draw2DLine(m_displaycenter - v2s32(10, 0),
505 m_displaycenter + v2s32(10, 0), crosshair_argb);
506 driver->draw2DLine(m_displaycenter - v2s32(0, 10),
507 m_displaycenter + v2s32(0, 10), crosshair_argb);
511 void Hud::setSelectionPos(const v3f &pos, const v3s16 &camera_offset)
513 m_camera_offset = camera_offset;
514 m_selection_pos = pos;
515 m_selection_pos_with_offset = pos - intToFloat(camera_offset, BS);
518 void Hud::drawSelectionMesh()
520 if (!m_use_selection_mesh) {
521 // Draw 3D selection boxes
522 video::SMaterial oldmaterial = driver->getMaterial2D();
523 driver->setMaterial(m_selection_material);
524 for (std::vector<aabb3f>::const_iterator
525 i = m_selection_boxes.begin();
526 i != m_selection_boxes.end(); ++i) {
528 i->MinEdge + m_selection_pos_with_offset,
529 i->MaxEdge + m_selection_pos_with_offset);
531 u32 r = (selectionbox_argb.getRed() *
532 m_selection_mesh_color.getRed() / 255);
533 u32 g = (selectionbox_argb.getGreen() *
534 m_selection_mesh_color.getGreen() / 255);
535 u32 b = (selectionbox_argb.getBlue() *
536 m_selection_mesh_color.getBlue() / 255);
537 driver->draw3DBox(box, video::SColor(255, r, g, b));
539 driver->setMaterial(oldmaterial);
540 } else if (m_selection_mesh) {
541 // Draw selection mesh
542 video::SMaterial oldmaterial = driver->getMaterial2D();
543 driver->setMaterial(m_selection_material);
544 setMeshColor(m_selection_mesh, m_selection_mesh_color);
545 video::SColor face_color(0,
546 MYMIN(255, m_selection_mesh_color.getRed() * 1.5),
547 MYMIN(255, m_selection_mesh_color.getGreen() * 1.5),
548 MYMIN(255, m_selection_mesh_color.getBlue() * 1.5));
549 setMeshColorByNormal(m_selection_mesh, m_selected_face_normal,
551 scene::IMesh* mesh = cloneMesh(m_selection_mesh);
552 translateMesh(mesh, m_selection_pos_with_offset);
553 u32 mc = m_selection_mesh->getMeshBufferCount();
554 for (u32 i = 0; i < mc; i++) {
555 scene::IMeshBuffer *buf = mesh->getMeshBuffer(i);
556 driver->drawMeshBuffer(buf);
559 driver->setMaterial(oldmaterial);
563 void Hud::updateSelectionMesh(const v3s16 &camera_offset)
565 m_camera_offset = camera_offset;
566 if (!m_use_selection_mesh)
569 if (m_selection_mesh) {
570 m_selection_mesh->drop();
571 m_selection_mesh = NULL;
574 if (!m_selection_boxes.size()) {
579 // New pointed object, create new mesh.
581 // Texture UV coordinates for selection boxes
582 static f32 texture_uv[24] = {
591 // Use single halo box instead of multiple overlapping boxes.
592 // Temporary solution - problem can be solved with multiple
593 // rendering targets, or some method to remove inner surfaces.
594 // Thats because of halo transparency.
596 aabb3f halo_box(100.0, 100.0, 100.0, -100.0, -100.0, -100.0);
597 m_halo_boxes.clear();
599 for (std::vector<aabb3f>::iterator
600 i = m_selection_boxes.begin();
601 i != m_selection_boxes.end(); ++i) {
602 halo_box.addInternalBox(*i);
605 m_halo_boxes.push_back(halo_box);
606 m_selection_mesh = convertNodeboxesToMesh(
607 m_halo_boxes, texture_uv, 0.5);
610 void Hud::resizeHotbar() {
611 if (m_screensize != porting::getWindowSize()) {
612 m_hotbar_imagesize = floor(HOTBAR_IMAGE_SIZE * porting::getDisplayDensity() + 0.5);
613 m_hotbar_imagesize *= m_hud_scaling;
614 m_padding = m_hotbar_imagesize / 12;
615 m_screensize = porting::getWindowSize();
616 m_displaycenter = v2s32(m_screensize.X/2,m_screensize.Y/2);
620 struct MeshTimeInfo {
625 void drawItemStack(video::IVideoDriver *driver,
627 const ItemStack &item,
628 const core::rect<s32> &rect,
629 const core::rect<s32> *clip,
631 ItemRotationKind rotation_kind)
633 static MeshTimeInfo rotation_time_infos[IT_ROT_NONE];
634 static bool enable_animations =
635 g_settings->getBool("inventory_items_animations");
638 if (rotation_kind < IT_ROT_NONE) {
639 rotation_time_infos[rotation_kind].mesh = NULL;
644 const ItemDefinition &def = item.getDefinition(client->idef());
645 scene::IMesh* mesh = client->idef()->getWieldMesh(def.name, client);
648 driver->clearZBuffer();
650 if (rotation_kind < IT_ROT_NONE) {
651 MeshTimeInfo &ti = rotation_time_infos[rotation_kind];
652 if (mesh != ti.mesh) {
654 ti.time = getTimeMs();
656 delta = porting::getDeltaMs(ti.time, getTimeMs()) % 100000;
659 core::rect<s32> oldViewPort = driver->getViewPort();
660 core::matrix4 oldProjMat = driver->getTransform(video::ETS_PROJECTION);
661 core::matrix4 oldViewMat = driver->getTransform(video::ETS_VIEW);
662 core::matrix4 ProjMatrix;
663 ProjMatrix.buildProjectionMatrixOrthoLH(2, 2, -1, 100);
664 driver->setTransform(video::ETS_PROJECTION, ProjMatrix);
665 driver->setTransform(video::ETS_VIEW, ProjMatrix);
666 core::matrix4 matrix;
667 matrix.makeIdentity();
669 if (enable_animations) {
670 float timer_f = (float)delta / 5000.0;
671 matrix.setRotationDegrees(core::vector3df(0, 360 * timer_f, 0));
674 driver->setTransform(video::ETS_WORLD, matrix);
675 driver->setViewPort(rect);
677 u32 mc = mesh->getMeshBufferCount();
678 for (u32 j = 0; j < mc; ++j) {
679 scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
680 video::SMaterial &material = buf->getMaterial();
681 material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
682 material.Lighting = false;
683 driver->setMaterial(material);
684 driver->drawMeshBuffer(buf);
687 driver->setTransform(video::ETS_VIEW, oldViewMat);
688 driver->setTransform(video::ETS_PROJECTION, oldProjMat);
689 driver->setViewPort(oldViewPort);
692 if(def.type == ITEM_TOOL && item.wear != 0)
694 // Draw a progressbar
695 float barheight = rect.getHeight()/16;
696 float barpad_x = rect.getWidth()/16;
697 float barpad_y = rect.getHeight()/16;
698 core::rect<s32> progressrect(
699 rect.UpperLeftCorner.X + barpad_x,
700 rect.LowerRightCorner.Y - barpad_y - barheight,
701 rect.LowerRightCorner.X - barpad_x,
702 rect.LowerRightCorner.Y - barpad_y);
704 // Shrink progressrect by amount of tool damage
705 float wear = item.wear / 65535.0;
707 wear * progressrect.UpperLeftCorner.X +
708 (1-wear) * progressrect.LowerRightCorner.X;
710 // Compute progressbar color
712 // wear = 0.5: yellow
714 video::SColor color(255,255,255,255);
715 int wear_i = MYMIN(floor(wear * 600), 511);
716 wear_i = MYMIN(wear_i + 10, 511);
718 color.set(255, wear_i, 255, 0);
720 color.set(255, 255, 511-wear_i, 0);
722 core::rect<s32> progressrect2 = progressrect;
723 progressrect2.LowerRightCorner.X = progressmid;
724 driver->draw2DRectangle(color, progressrect2, clip);
726 color = video::SColor(255,0,0,0);
727 progressrect2 = progressrect;
728 progressrect2.UpperLeftCorner.X = progressmid;
729 driver->draw2DRectangle(color, progressrect2, clip);
732 if(font != NULL && item.count >= 2)
734 // Get the item count as a string
735 std::string text = itos(item.count);
736 v2u32 dim = font->getDimension(utf8_to_wide(text).c_str());
737 v2s32 sdim(dim.X,dim.Y);
739 core::rect<s32> rect2(
740 /*rect.UpperLeftCorner,
741 core::dimension2d<u32>(rect.getWidth(), 15)*/
742 rect.LowerRightCorner - sdim,
746 video::SColor bgcolor(128,0,0,0);
747 driver->draw2DRectangle(bgcolor, rect2, clip);
749 video::SColor color(255,255,255,255);
750 font->draw(text.c_str(), rect2, color, false, false, clip);