diff --git a/src/framework/graphics/graphics.cpp b/src/framework/graphics/graphics.cpp index 0f284e8f..531d2074 100644 --- a/src/framework/graphics/graphics.cpp +++ b/src/framework/graphics/graphics.cpp @@ -19,7 +19,6 @@ void Graphics::init() glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); glShadeModel(GL_SMOOTH); glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); logInfo("GPU ", glGetString(GL_RENDERER)); @@ -30,6 +29,7 @@ void Graphics::init() m_emptyTexture = TexturePtr(new Texture); bindColor(Color::white); + bindBlendFunc(BLEND_NORMAL); } void Graphics::terminate() @@ -285,6 +285,18 @@ void Graphics::bindTexture(const TexturePtr& texture) glBindTexture(GL_TEXTURE_2D, texture->getId()); } +void Graphics::bindBlendFunc(BlendFuncType blendType) +{ + switch(blendType) { + case BLEND_NORMAL: + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + break; + case BLEND_COLORIZING: + glBlendFunc(GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA); + break; + } +} + void Graphics::startDrawing() { assert(!m_drawing); diff --git a/src/framework/graphics/graphics.h b/src/framework/graphics/graphics.h index c863a106..0719d692 100644 --- a/src/framework/graphics/graphics.h +++ b/src/framework/graphics/graphics.h @@ -3,6 +3,11 @@ #include "declarations.h" +enum BlendFuncType { + BLEND_NORMAL, + BLEND_COLORIZING +}; + class Graphics { public: @@ -29,6 +34,7 @@ public: void bindColor(const Color& color); void bindTexture(const TexturePtr& texture); + void bindBlendFunc(BlendFuncType blendType); // drawing API void drawTexturedRect(const Rect& screenCoords, diff --git a/src/otclient/core/const.h b/src/otclient/core/const.h index b85790b6..569835b9 100644 --- a/src/otclient/core/const.h +++ b/src/otclient/core/const.h @@ -33,4 +33,12 @@ enum Direction { DIRECTION_WEST }; +enum SpriteMask { + SpriteMaskRed = 0, + SpriteMaskGreen, + SpriteMaskBlue, + SpriteMaskYellow, + SpriteMaskNone = 255 +}; + #endif diff --git a/src/otclient/core/creature.cpp b/src/otclient/core/creature.cpp index 2c3c3405..37d8fa8f 100644 --- a/src/otclient/core/creature.cpp +++ b/src/otclient/core/creature.cpp @@ -22,28 +22,174 @@ void Creature::draw(int x, int y) // draw outfit internalDraw(x, y, 0, m_direction, 0, 0, anim); - // draw addons - //for(int a = 0; a < m_outfit.addons; ++a) { - //internalDraw(x, y, 0, m_direction, m_outfit.addons & (1 << a), 0, anim); - //} - //glPushAttrib(GL_CURRENT_BIT | GL_COLOR_BUFFER_BIT); + // draw outfit colors + glBlendFunc(GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA); - //glBlendFunc(GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA); + // TODO: move this shit hahaha + static const Color outfitColors[] = { + Color(255,255,255), + Color(255,212,191), + Color(255,233,191), + Color(255,255,191), + Color(233,255,191), + Color(212,255,191), + Color(191,255,191), + Color(191,255,212), + Color(191,255,233), + Color(191,255,255), + Color(191,233,255), + Color(191,212,255), + Color(191,191,255), + Color(212,191,255), + Color(233,191,255), + Color(255,191,255), + Color(255,191,233), + Color(255,191,212), + Color(255,191,191), - //Color colors[4] = {Color::yellow, Color::red, Color::green, Color::blue}; + Color(128,128,128), + Color(191,159,143), + Color(191,175,143), + Color(191,191,143), + Color(175,191,143), + Color(159,191,143), + Color(143,191,143), + Color(143,191,159), + Color(143,191,175), + Color(143,191,191), + Color(143,175,191), + Color(143,159,191), + Color(143,143,191), + Color(159,143,191), + Color(175,143,191), + Color(191,143,191), + Color(191,143,175), + Color(191,143,159), + Color(191,143,143), - //for(int i = 0; i < 4; ++i) { + Color(182,182,182), + Color(191,127,95), + Color(191,159,95), + Color(191,191,95), + Color(159,191,95), + Color(127,191,95), + Color(95,191,95), + Color(95,191,127), + Color(95,191,159), + Color(95,191,191), + Color(95,159,191), + Color(95,127,191), + Color(95,95,191), + Color(127,95,191), + Color(159,95,191), + Color(191,95,191), + Color(191,95,159), + Color(191,95,127), + Color(191,95,95), + Color(145,145,145), + Color(191,106,63), + Color(191,148,63), + Color(191,191,63), + Color(148,191,63), + Color(107,191,63), + Color(63,191,63), + Color(63,191,106), + Color(63,191,148), + Color(63,191,191), + Color(63,148,191), + Color(63,106,191), + Color(63,63,191), + Color(106,63,191), + Color(148,63,191), + Color(191,63,191), + Color(191,63,148), + Color(191,63,106), + Color(191,63,63), - /*g_graphics.bindColor(colors[i]); - internalDraw(creatureAttributes->width*32 - 32, creatureAttributes->height*32 - 32, 1, m_direction, 0, 0, 0); - framebuffer.unbind(); + Color(109,109,109), + Color(255,85,0), + Color(255,170,0), + Color(255,255,0), + Color(170,255,0), + Color(84,255,0), + Color(0,255,0), + Color(0,255,84), + Color(0,255,170), + Color(0,255,255), + Color(0,169,255), + Color(0,85,255), + Color(0,0,255), + Color(85,0,255), + Color(169,0,255), + Color(254,0,255), + Color(255,0,170), + Color(255,0,85), + Color(255,0,0), + Color(72,72,72), + Color(191,63,0), + Color(191,127,0), + Color(191,191,0), + Color(127,191,0), + Color(63,191,0), + Color(0,191,0), + Color(0,191,63), + Color(0,191,127), + Color(0,191,191), + Color(0,127,191), + Color(0,63,191), + Color(0,0,191), + Color(63,0,191), + Color(127,0,191), + Color(191,0,191), + Color(191,0,127), + Color(191,0,63), + Color(191,0,0), - g_graphics.bindColor(Color::green);*/ - //framebuffer.draw(x, y, creatureAttributes->width*32, creatureAttributes->height*32); - //} - //glPopAttrib(); + Color(36,36,36), + Color(127,42,0), + Color(127,85,0), + Color(127,127,0), + Color(85,127,0), + Color(42,127,0), + Color(0,127,0), + Color(0,127,42), + Color(0,127,85), + Color(0,127,127), + Color(0,84,127), + Color(0,42,127), + Color(0,0,127), + Color(42,0,127), + Color(84,0,127), + Color(127,0,127), + Color(191,0,85), + Color(127,0,42), + Color(127,0,0) + }; + + const ThingAttributes& attributes = getAttributes(); + if(attributes.blendframes > 1) { + g_graphics.bindBlendFunc(BLEND_COLORIZING); + + for(int mask = 0; mask < 4; ++mask) { + + int outfitColorId = 0; + if(mask == SpriteMaskYellow) + outfitColorId = m_outfit.head; + else if(mask == SpriteMaskRed) + outfitColorId = m_outfit.body; + else if(mask == SpriteMaskBlue) + outfitColorId = m_outfit.legs; + else if(mask == SpriteMaskGreen) + outfitColorId = m_outfit.feet; + + g_graphics.bindColor(outfitColors[outfitColorId]); + internalDraw(x, y, 1, m_direction, 0, 0, anim); + } + + g_graphics.bindBlendFunc(BLEND_NORMAL); + } } const ThingAttributes& Creature::getAttributes() diff --git a/src/otclient/core/spritemanager.cpp b/src/otclient/core/spritemanager.cpp index 2b2085c3..061a866a 100644 --- a/src/otclient/core/spritemanager.cpp +++ b/src/otclient/core/spritemanager.cpp @@ -107,3 +107,28 @@ TexturePtr SpriteManager::getSpriteTexture(int id) return texture; } + +TexturePtr SpriteManager::getSpriteMask(int id, SpriteMask mask) +{ + TexturePtr tex = getSpriteTexture(id); + auto pixels = tex->getPixels(); + + static RGBA maskColors[4] = { Color::red.rgba(), Color::green.rgba(), Color::blue.rgba(), Color::yellow.rgba() }; + RGBA maskColor = maskColors[mask]; + RGBA whiteColor = Color::white.rgba(); + RGBA alphaColor = Color::alpha.rgba(); + + // convert pixels + // masked color -> white color + // any other color -> alpha color + for(int i=0;i<4096;i+=4) { + RGBA& currentColor = *(RGBA*)&pixels[i]; + if(currentColor == maskColor) + currentColor = whiteColor; + else + currentColor = alphaColor; + } + + //TODO: cache sprites mask into a texture + return TexturePtr(new Texture(32, 32, 4, &pixels[0])); +} diff --git a/src/otclient/core/spritemanager.h b/src/otclient/core/spritemanager.h index 0d5692d0..8e533637 100644 --- a/src/otclient/core/spritemanager.h +++ b/src/otclient/core/spritemanager.h @@ -1,7 +1,7 @@ #ifndef SPRITEMANAGER_H #define SPRITEMANAGER_H -#include +#include "declarations.h" #include class SpriteManager @@ -14,7 +14,9 @@ public: uint32 getSignature() { return m_signature; } int getSpritesCount() { return m_spritesCount; } + TexturePtr getSpriteTexture(int id); + TexturePtr getSpriteMask(int id, SpriteMask mask); private: TexturePtr loadSprite(int id); diff --git a/src/otclient/core/thing.cpp b/src/otclient/core/thing.cpp index 2204987f..2d9e3a0d 100644 --- a/src/otclient/core/thing.cpp +++ b/src/otclient/core/thing.cpp @@ -6,7 +6,7 @@ Thing::Thing(ThingType type) : m_id(0), m_type(type) { } -void Thing::internalDraw(int x, int y, int blendframes, int xdiv, int ydiv, int zdiv, int anim) +void Thing::internalDraw(int x, int y, int blendframes, int xdiv, int ydiv, int zdiv, int anim, SpriteMask mask) { const ThingAttributes& attributes = getAttributes(); @@ -24,11 +24,16 @@ void Thing::internalDraw(int x, int y, int blendframes, int xdiv, int ydiv, int if(!spriteId) continue; - TexturePtr spriteTex = g_sprites.getSpriteTexture(spriteId); + TexturePtr spriteTex; + if(mask == SpriteMaskNone) { + spriteTex = g_sprites.getSpriteTexture(spriteId); + g_graphics.bindColor(Color::white); + } else + spriteTex = g_sprites.getSpriteMask(spriteId, mask); + Rect drawRect((x - xi*32) - attributes.xOffset, (y - yi*32) - attributes.xOffset, 32, 32); - g_graphics.drawTexturedRect(drawRect, spriteTex); } } diff --git a/src/otclient/core/thing.h b/src/otclient/core/thing.h index b629c929..17335912 100644 --- a/src/otclient/core/thing.h +++ b/src/otclient/core/thing.h @@ -35,7 +35,7 @@ public: virtual LocalPlayerPtr asLocalPlayer() { return nullptr; } protected: - void internalDraw(int x, int y, int blendframes, int xdiv, int ydiv, int zdiv, int anim); + void internalDraw(int x, int y, int blendframes, int xdiv, int ydiv, int zdiv, int anim, SpriteMask mask = SpriteMaskNone); uint32 m_id; ThingType m_type; diff --git a/src/otclient/core/thingattributes.h b/src/otclient/core/thingattributes.h index 4ffe7fd7..1968f385 100644 --- a/src/otclient/core/thingattributes.h +++ b/src/otclient/core/thingattributes.h @@ -45,6 +45,7 @@ struct ThingAttributes isHangable, isHorizontal, isVertical, rotable, hasHeight, lookThrough, hasMiniMapColor; uint8 alwaysOnTopOrder, width, height, blendframes, xdiv, ydiv, zdiv, animcount, xOffset, yOffset; uint16 speed, subParam07, subParam08, lightLevel, lightColor, miniMapColor; + std::vector sprites; ThingAttributesGroup group; };