Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Use meshes to display inventory items
  • Loading branch information
RealBadAngel authored and est31 committed Feb 7, 2016
1 parent bf884e3 commit 6cd2b3b
Show file tree
Hide file tree
Showing 10 changed files with 281 additions and 155 deletions.
3 changes: 3 additions & 0 deletions builtin/settingtypes.txt
Expand Up @@ -508,6 +508,9 @@ directional_colored_fog (Colored fog) bool true
# set to the nearest valid value.
ambient_occlusion_gamma (Ambient occlusion gamma) float 2.2 0.25 4.0

# Enables animation of inventory items.
inventory_items_animations (Inventory items animations) bool false

[**Menus]

# Use a cloud animation for the main menu background.
Expand Down
3 changes: 3 additions & 0 deletions minetest.conf.example
Expand Up @@ -588,6 +588,9 @@
# type: float min: 0.25 max: 4
# ambient_occlusion_gamma = 2.2

# Enable animation of inventory items.
# inventory_items_animations = false

### Menus

# Use a cloud animation for the main menu background.
Expand Down
1 change: 1 addition & 0 deletions src/defaultsettings.cpp
Expand Up @@ -138,6 +138,7 @@ void set_default_settings(Settings *settings)
settings->setDefault("console_alpha", "200");
settings->setDefault("selectionbox_color", "(0,0,0)");
settings->setDefault("enable_node_highlighting", "false");
settings->setDefault("inventory_items_animations", "false");
settings->setDefault("crosshair_color", "(255,255,255)");
settings->setDefault("crosshair_alpha", "255");
settings->setDefault("hud_scaling", "1.0");
Expand Down
79 changes: 45 additions & 34 deletions src/guiFormSpecMenu.cpp
Expand Up @@ -572,7 +572,7 @@ void GUIFormSpecMenu::parseItemImage(parserData* data,std::string element)

if(!data->explicit_size)
warningstream<<"invalid use of item_image without a size[] element"<<std::endl;
m_itemimages.push_back(ImageDrawSpec(name, pos, geom));
m_itemimages.push_back(ImageDrawSpec("", name, pos, geom));
return;
}
errorstream<< "Invalid ItemImage element(" << parts.size() << "): '" << element << "'" << std::endl;
Expand Down Expand Up @@ -1483,7 +1483,6 @@ void GUIFormSpecMenu::parseItemImageButton(parserData* data,std::string element)
IItemDefManager *idef = m_gamedef->idef();
ItemStack item;
item.deSerialize(item_name, idef);
video::ITexture *texture = idef->getInventoryTexture(item.getDefinition(idef).name, m_gamedef);

m_tooltips[name] =
TooltipSpec(item.getDefinition(idef).description,
Expand All @@ -1505,13 +1504,17 @@ void GUIFormSpecMenu::parseItemImageButton(parserData* data,std::string element)
}

e->setUseAlphaChannel(true);
e->setImage(guiScalingImageButton(Environment->getVideoDriver(), texture, geom.X, geom.Y));
e->setPressedImage(guiScalingImageButton(Environment->getVideoDriver(), texture, geom.X, geom.Y));
e->setImage(guiScalingImageButton(Environment->getVideoDriver(), NULL, geom.X, geom.Y));
e->setPressedImage(guiScalingImageButton(Environment->getVideoDriver(), NULL, geom.X, geom.Y));
e->setScaleImage(true);
spec.ftype = f_Button;
rect+=data->basepos-padding;
spec.rect=rect;
m_fields.push_back(spec);
pos = padding + AbsoluteRect.UpperLeftCorner;
pos.X += stof(v_pos[0]) * (float) spacing.X;
pos.Y += stof(v_pos[1]) * (float) spacing.Y;
m_itemimages.push_back(ImageDrawSpec("", item_name, pos, geom));
return;
}
errorstream<< "Invalid ItemImagebutton element(" << parts.size() << "): '" << element << "'" << std::endl;
Expand Down Expand Up @@ -2151,7 +2154,8 @@ GUIFormSpecMenu::ItemSpec GUIFormSpecMenu::getItemAtPos(v2s32 p) const
return ItemSpec(InventoryLocation(), "", -1);
}

void GUIFormSpecMenu::drawList(const ListDrawSpec &s, int phase)
void GUIFormSpecMenu::drawList(const ListDrawSpec &s, int phase,
bool &item_hovered)
{
video::IVideoDriver* driver = Environment->getVideoDriver();

Expand Down Expand Up @@ -2193,12 +2197,13 @@ void GUIFormSpecMenu::drawList(const ListDrawSpec &s, int phase)
&& m_selected_item->i == item_i;
bool hovering = rect.isPointInside(m_pointer);

if(phase == 0)
{
if(hovering)
if (phase == 0) {
if (hovering) {
item_hovered = true;
driver->draw2DRectangle(m_slotbg_h, rect, &AbsoluteClippingRect);
else
} else {
driver->draw2DRectangle(m_slotbg_n, rect, &AbsoluteClippingRect);
}
}

//Draw inv slot borders
Expand Down Expand Up @@ -2232,7 +2237,8 @@ void GUIFormSpecMenu::drawList(const ListDrawSpec &s, int phase)
if(!item.empty())
{
drawItemStack(driver, m_font, item,
rect, &AbsoluteClippingRect, m_gamedef);
rect, &AbsoluteClippingRect, m_gamedef,
selected, hovering, false);
}

// Draw tooltip
Expand Down Expand Up @@ -2273,11 +2279,15 @@ void GUIFormSpecMenu::drawList(const ListDrawSpec &s, int phase)

void GUIFormSpecMenu::drawSelectedItem()
{
if(!m_selected_item)
return;

video::IVideoDriver* driver = Environment->getVideoDriver();

if (!m_selected_item) {
drawItemStack(driver, m_font, ItemStack(),
core::rect<s32>(v2s32(0, 0), v2s32(0, 0)),
NULL, m_gamedef, false, false, true);
return;
}

Inventory *inv = m_invmgr->getInventory(m_selected_item->inventoryloc);
sanity_check(inv);
InventoryList *list = inv->getList(m_selected_item->listname);
Expand All @@ -2287,7 +2297,7 @@ void GUIFormSpecMenu::drawSelectedItem()

core::rect<s32> imgrect(0,0,imgsize.X,imgsize.Y);
core::rect<s32> rect = imgrect + (m_pointer - imgrect.getCenter());
drawItemStack(driver, m_font, stack, rect, NULL, m_gamedef);
drawItemStack(driver, m_font, stack, rect, NULL, m_gamedef, false, false, true);
}

void GUIFormSpecMenu::drawMenu()
Expand Down Expand Up @@ -2369,6 +2379,12 @@ void GUIFormSpecMenu::drawMenu()

driver->draw2DRectangle(todraw, rect, 0);
}

/*
Call base class
*/
gui::IGUIElement::draw();

/*
Draw images
*/
Expand Down Expand Up @@ -2413,36 +2429,31 @@ void GUIFormSpecMenu::drawMenu()
const ImageDrawSpec &spec = m_itemimages[i];
IItemDefManager *idef = m_gamedef->idef();
ItemStack item;
item.deSerialize(spec.name, idef);
video::ITexture *texture = idef->getInventoryTexture(item.getDefinition(idef).name, m_gamedef);
// Image size on screen
item.deSerialize(spec.item_name, idef);
core::rect<s32> imgrect(0, 0, spec.geom.X, spec.geom.Y);
// Image rectangle on screen
// Viewport rectangle on screen
core::rect<s32> rect = imgrect + spec.pos;
const video::SColor color(255,255,255,255);
const video::SColor colors[] = {color,color,color,color};
draw2DImageFilterScaled(driver, texture, rect,
core::rect<s32>(core::position2d<s32>(0,0),
core::dimension2di(texture->getOriginalSize())),
NULL/*&AbsoluteClippingRect*/, colors, true);
drawItemStack(driver, m_font, item, rect, &AbsoluteClippingRect,
m_gamedef, false, false, false);
}

/*
Draw items
Phase 0: Item slot rectangles
Phase 1: Item images; prepare tooltip
*/
int start_phase=0;
for(int phase=start_phase; phase<=1; phase++)
for(u32 i=0; i<m_inventorylists.size(); i++)
{
drawList(m_inventorylists[i], phase);
bool item_hovered = false;
int start_phase = 0;
for (int phase = start_phase; phase <= 1; phase++) {
for (u32 i = 0; i < m_inventorylists.size(); i++) {
drawList(m_inventorylists[i], phase, item_hovered);
}
}
if (!item_hovered) {
drawItemStack(driver, m_font, ItemStack(),
core::rect<s32>(v2s32(0, 0), v2s32(0, 0)),
NULL, m_gamedef, false, true, false);
}

/*
Call base class
*/
gui::IGUIElement::draw();

/* TODO find way to show tooltips on touchscreen */
#ifndef HAVE_TOUCHSCREENGUI
Expand Down
20 changes: 17 additions & 3 deletions src/guiFormSpecMenu.h
Expand Up @@ -143,21 +143,32 @@ class GUIFormSpecMenu : public GUIModalMenu
{
}
ImageDrawSpec(const std::string &a_name,
v2s32 a_pos, v2s32 a_geom):
const std::string &a_item_name,
const v2s32 &a_pos, const v2s32 &a_geom):
name(a_name),
item_name (a_item_name),
pos(a_pos),
geom(a_geom)
{
scale = true;
}
ImageDrawSpec(const std::string &a_name,
v2s32 a_pos):
const v2s32 &a_pos, const v2s32 &a_geom):
name(a_name),
pos(a_pos),
geom(a_geom)
{
scale = true;
}
ImageDrawSpec(const std::string &a_name,
const v2s32 &a_pos):
name(a_name),
pos(a_pos)
{
scale = false;
}
std::string name;
std::string item_name;
v2s32 pos;
v2s32 geom;
bool scale;
Expand Down Expand Up @@ -282,7 +293,7 @@ class GUIFormSpecMenu : public GUIModalMenu
void regenerateGui(v2u32 screensize);

ItemSpec getItemAtPos(v2s32 p) const;
void drawList(const ListDrawSpec &s, int phase);
void drawList(const ListDrawSpec &s, int phase, bool &item_hovered);
void drawSelectedItem();
void drawMenu();
void updateSelectedItem();
Expand Down Expand Up @@ -334,6 +345,8 @@ class GUIFormSpecMenu : public GUIModalMenu
std::vector<std::pair<FieldSpec,gui::IGUIScrollBar*> > m_scrollbars;

ItemSpec *m_selected_item;
f32 m_timer1;
f32 m_timer2;
u32 m_selected_amount;
bool m_selected_dragging;

Expand Down Expand Up @@ -373,6 +386,7 @@ class GUIFormSpecMenu : public GUIModalMenu
TextDest *m_text_dst;
unsigned int m_formspec_version;
std::string m_focused_element;
bool m_selection_active;

typedef struct {
bool explicit_size;
Expand Down
99 changes: 84 additions & 15 deletions src/hud.cpp
Expand Up @@ -82,8 +82,9 @@ Hud::Hud(video::IVideoDriver *driver, scene::ISceneManager* smgr,
use_hotbar_selected_image = false;
}

void Hud::drawItem(const ItemStack &item, const core::rect<s32>& rect, bool selected) {

void Hud::drawItem(const ItemStack &item, const core::rect<s32>& rect,
bool selected)
{
if (selected) {
/* draw hihlighting around selected item */
if (use_hotbar_selected_image) {
Expand Down Expand Up @@ -154,7 +155,8 @@ void Hud::drawItem(const ItemStack &item, const core::rect<s32>& rect, bool sele
video::SColor bgcolor2(128, 0, 0, 0);
if (!use_hotbar_image)
driver->draw2DRectangle(bgcolor2, rect, NULL);
drawItemStack(driver, g_fontengine->getFont(), item, rect, NULL, gamedef);
drawItemStack(driver, g_fontengine->getFont(), item, rect, NULL,
gamedef, selected, false, false);
}

//NOTE: selectitem = 0 -> no selected; selectitem 1-based
Expand Down Expand Up @@ -489,23 +491,90 @@ void drawItemStack(video::IVideoDriver *driver,
const ItemStack &item,
const core::rect<s32> &rect,
const core::rect<s32> *clip,
IGameDef *gamedef)
IGameDef *gamedef,
bool selected,
bool hovered,
bool dragged)
{
if(item.empty())
static s32 hovered_time;
static s32 selected_time;
static s32 dragged_time;
static scene::IMesh *hovered_mesh;
static scene::IMesh *selected_mesh;
static scene::IMesh *dragged_mesh;
bool enable_animations =
g_settings->getBool("inventory_items_animations");

if (item.empty()) {
if (selected) {
selected_mesh = NULL;
} else if (hovered) {
hovered_mesh = NULL;
} else if (dragged) {
dragged_mesh = NULL;
}
return;
}

const ItemDefinition &def = item.getDefinition(gamedef->idef());
video::ITexture *texture = gamedef->idef()->getInventoryTexture(def.name, gamedef);
scene::IMesh* mesh = gamedef->idef()->getWieldMesh(def.name, gamedef);

if (mesh) {
driver->clearZBuffer();
s32 delta = 0;
if (selected) {
if (mesh != selected_mesh) {
selected_mesh = mesh;
selected_time = getTimeMs();
} else {
delta = porting::getDeltaMs(selected_time, getTimeMs()) % 100000;
}
} else if (hovered) {
if (mesh != hovered_mesh) {
hovered_mesh = mesh;
hovered_time = getTimeMs();
} else {
delta = porting::getDeltaMs(hovered_time, getTimeMs()) % 100000;
}
} else if (dragged) {
if (mesh != dragged_mesh) {
dragged_mesh = mesh;
dragged_time = getTimeMs();
} else {
delta = porting::getDeltaMs(dragged_time, getTimeMs()) % 100000;
}
}
core::rect<s32> oldViewPort = driver->getViewPort();
core::matrix4 oldProjMat = driver->getTransform(video::ETS_PROJECTION);
core::matrix4 oldViewMat = driver->getTransform(video::ETS_VIEW);
core::matrix4 ProjMatrix;
ProjMatrix.buildProjectionMatrixOrthoLH(2, 2, -1, 100);
driver->setTransform(video::ETS_PROJECTION, ProjMatrix);
driver->setTransform(video::ETS_VIEW, ProjMatrix);
core::matrix4 matrix;
matrix.makeIdentity();

if (enable_animations) {
float timer_f = (float)delta / 5000.0;
matrix.setRotationDegrees(core::vector3df(0, 360 * timer_f, 0));
}

// Draw the inventory texture
if(texture != NULL)
{
const video::SColor color(255,255,255,255);
const video::SColor colors[] = {color,color,color,color};
draw2DImageFilterScaled(driver, texture, rect,
core::rect<s32>(core::position2d<s32>(0,0),
core::dimension2di(texture->getOriginalSize())),
clip, colors, true);
driver->setTransform(video::ETS_WORLD, matrix);
driver->setViewPort(rect);

u32 mc = mesh->getMeshBufferCount();
for (u32 j = 0; j < mc; ++j) {
scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
video::SMaterial &material = buf->getMaterial();
material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
material.Lighting = false;
driver->setMaterial(material);
driver->drawMeshBuffer(buf);
}

driver->setTransform(video::ETS_VIEW, oldViewMat);
driver->setTransform(video::ETS_PROJECTION, oldProjMat);
driver->setViewPort(oldViewPort);
}

if(def.type == ITEM_TOOL && item.wear != 0)
Expand Down

0 comments on commit 6cd2b3b

Please sign in to comment.