diff --git a/.gitignore b/.gitignore index 0ce71e497..f69058d7a 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ *.sln.docstates .idea/ .vscode/ +.vs # Build results diff --git a/src/client/creature.cpp b/src/client/creature.cpp index 4bb814f5d..8ee27eb9e 100644 --- a/src/client/creature.cpp +++ b/src/client/creature.cpp @@ -322,6 +322,32 @@ void Creature::drawInformation(const Point& point, bool useGray, const Rect& par } } +// Get the player outfit texture +TexturePtr Creature::getOutfitTexture() +{ + int exactSize; + if (m_outfit.getCategory() == ThingCategoryCreature) + exactSize = getExactSize(); + else + exactSize = g_things.rawGetThingType(m_outfit.getAuxId(), m_outfit.getCategory())->getExactSize(); + + int frameSize; + frameSize = std::max(exactSize * 0.75f, 2 * Otc::TILE_PIXELS * 0.75f); // Define the frame size + + if (g_graphics.canUseFBO()) { + // Create a temporary frame buffer + const FrameBufferPtr& outfitBuffer = g_framebuffers.getTemporaryFrameBuffer(); + outfitBuffer->resize(Size(frameSize, frameSize)); // Set the frame buffer size to frameSize (square) + outfitBuffer->bind(); // Draw operations are binded to this framebuffer from now + g_painter->setAlphaWriting(true); + g_painter->clear(Color::alpha); + internalDrawOutfit(Point(frameSize - Otc::TILE_PIXELS, frameSize - Otc::TILE_PIXELS) + getDisplacement(), 1, false, true, getDirection()); // Call the internal outfit draw + outfitBuffer->release(); // Release the frame buffer, it's not receiving next draw calls + return outfitBuffer->getTexture(); // Return the resulting texture + } + return nullptr; +} + void Creature::turn(Otc::Direction direction) { // if is not walking change the direction right away diff --git a/src/client/creature.h b/src/client/creature.h index c2d689b42..a2bdd72b7 100644 --- a/src/client/creature.h +++ b/src/client/creature.h @@ -49,6 +49,7 @@ class Creature : public Thing void internalDrawOutfit(Point dest, float scaleFactor, bool animateWalk, bool animateIdle, Otc::Direction direction, LightView *lightView = nullptr); void drawOutfit(const Rect& destRect, bool resize); void drawInformation(const Point& point, bool useGray, const Rect& parentRect, int drawFlags); + TexturePtr getOutfitTexture(); // Method for receiving the player outfit texture void setId(uint32 id) { m_id = id; } void setName(const std::string& name); diff --git a/src/client/effect.cpp b/src/client/effect.cpp index 9f6a80380..5ae1c42f0 100644 --- a/src/client/effect.cpp +++ b/src/client/effect.cpp @@ -46,13 +46,11 @@ void Effect::drawEffect(const Point& dest, float scaleFactor, bool animate, int } } - int xPattern = offsetX % getNumPatternX(); - if(xPattern < 0) - xPattern += getNumPatternX(); + int xPattern = unsigned(offsetX) % getNumPatternX(); + xPattern = 1 - xPattern - getNumPatternX(); + if (xPattern < 0) xPattern += getNumPatternX(); - int yPattern = offsetY % getNumPatternY(); - if(yPattern < 0) - yPattern += getNumPatternY(); + int yPattern = unsigned(offsetY) % getNumPatternY(); rawGetThingType()->draw(dest, scaleFactor, 0, xPattern, yPattern, 0, animationPhase, lightView); } diff --git a/src/client/mapview.cpp b/src/client/mapview.cpp index eb12a5870..f2984180a 100644 --- a/src/client/mapview.cpp +++ b/src/client/mapview.cpp @@ -37,6 +37,7 @@ #include #include #include +#include "game.h" enum { @@ -186,6 +187,7 @@ void MapView::draw(const Rect& rect) m_shader->setUniformValue(ShaderManager::MAP_CENTER_COORD, center.x / (float)framebufferRect.width(), 1.0f - center.y / (float)framebufferRect.height()); m_shader->setUniformValue(ShaderManager::MAP_GLOBAL_COORD, globalCoord.x / (float)framebufferRect.height(), globalCoord.y / (float)framebufferRect.height()); m_shader->setUniformValue(ShaderManager::MAP_ZOOM, scaleFactor); + m_shader->setUniformValue(ShaderManager::PLAYER_DIRECTION, g_game.getLocalPlayer()->getDirection()); // Set the player direction uniform g_painter->setShaderProgram(m_shader); } diff --git a/src/client/shadermanager.cpp b/src/client/shadermanager.cpp index 33a89d414..1e3625f2d 100644 --- a/src/client/shadermanager.cpp +++ b/src/client/shadermanager.cpp @@ -134,6 +134,7 @@ void ShaderManager::setupMapShader(const PainterShaderProgramPtr& shader) shader->bindUniformLocation(MAP_CENTER_COORD, "u_MapCenterCoord"); shader->bindUniformLocation(MAP_GLOBAL_COORD, "u_MapGlobalCoord"); shader->bindUniformLocation(MAP_ZOOM, "u_MapZoom"); + shader->bindUniformLocation(PLAYER_DIRECTION, "u_PlayerLookDirection"); // Binding player look direction uniform to the shader manager } PainterShaderProgramPtr ShaderManager::getShader(const std::string& name) diff --git a/src/client/shadermanager.h b/src/client/shadermanager.h index ac7b6ea25..413bd0967 100644 --- a/src/client/shadermanager.h +++ b/src/client/shadermanager.h @@ -34,7 +34,8 @@ class ShaderManager ITEM_ID_UNIFORM = 10, MAP_CENTER_COORD = 10, MAP_GLOBAL_COORD = 11, - MAP_ZOOM = 12 + MAP_ZOOM = 12, + PLAYER_DIRECTION = 13, // Added player direction to the list of default shader uniforms }; void init(); diff --git a/src/framework/graphics/paintershaderprogram.cpp b/src/framework/graphics/paintershaderprogram.cpp index 2780deb49..c226e1a2c 100644 --- a/src/framework/graphics/paintershaderprogram.cpp +++ b/src/framework/graphics/paintershaderprogram.cpp @@ -27,6 +27,7 @@ #include "graphics.h" #include #include +#include PainterShaderProgram::PainterShaderProgram() { @@ -163,6 +164,30 @@ void PainterShaderProgram::addMultiTexture(const std::string& file) m_multiTextures.push_back(texture); } +// Add player outfit texture to the shader uniforms +void PainterShaderProgram::addPlayerOutfitMultiTexture() +{ + if (m_multiTextures.size() > 3) + g_logger.error("cannot add more multi textures to shader, the max is 3"); + + TexturePtr texture = g_game.getLocalPlayer()->getOutfitTexture(); // Get player outfit texture + if (!texture) + return; + + texture->setSmooth(false); + texture->setRepeat(false); + + if (m_playerOutfitIndex == INT_MAX) + { + m_playerOutfitIndex = m_multiTextures.size(); + m_multiTextures.push_back(texture); + return; + } + else { + m_multiTextures.at(m_playerOutfitIndex) = texture; + } +} + void PainterShaderProgram::bindMultiTextures() { if(m_multiTextures.empty()) diff --git a/src/framework/graphics/paintershaderprogram.h b/src/framework/graphics/paintershaderprogram.h index 1969c29d9..33f1fa984 100644 --- a/src/framework/graphics/paintershaderprogram.h +++ b/src/framework/graphics/paintershaderprogram.h @@ -64,6 +64,7 @@ class PainterShaderProgram : public ShaderProgram void updateTime(); void addMultiTexture(const std::string& file); + void addPlayerOutfitMultiTexture(); void bindMultiTextures(); private: @@ -76,7 +77,8 @@ class PainterShaderProgram : public ShaderProgram Matrix3 m_textureMatrix; Size m_resolution; float m_time; - std::vector m_multiTextures; + int m_playerOutfitIndex = INT_MAX; + std::vector m_multiTextures; // Control variables (a shader should have only one player outfit uniform, yet, it needs to be updated very often) }; #endif diff --git a/src/framework/luafunctions.cpp b/src/framework/luafunctions.cpp index eb4b0bd19..bccfead70 100644 --- a/src/framework/luafunctions.cpp +++ b/src/framework/luafunctions.cpp @@ -736,6 +736,7 @@ void Application::registerLuaFunctions() g_lua.registerClass(); g_lua.registerClass(); g_lua.bindClassMemberFunction("addMultiTexture", &PainterShaderProgram::addMultiTexture); + g_lua.bindClassMemberFunction("addPlayerOutfitMultiTexture", &PainterShaderProgram::addPlayerOutfitMultiTexture); // Expose addPlayerOutfitMultiTexture to lua api // ParticleEffect g_lua.registerClass(); diff --git a/vc14/otclient.sln b/vc14/otclient.sln index 90037d1d3..8e6885de5 100644 --- a/vc14/otclient.sln +++ b/vc14/otclient.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.23107.0 +# Visual Studio Version 17 +VisualStudioVersion = 17.9.34723.18 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "otclient", "otclient.vcxproj", "{17A8F78F-1FFB-4128-A3B3-59CC6C19D89A}" EndProject diff --git a/vc14/otclient.vcxproj b/vc14/otclient.vcxproj index 71b6f650b..348fba59a 100644 --- a/vc14/otclient.vcxproj +++ b/vc14/otclient.vcxproj @@ -28,22 +28,22 @@ Application true - v142 + v143 Application true - v142 + v143 Application false - v142 + v143 Application false - v142 + v143 @@ -472,4 +472,4 @@ - + \ No newline at end of file diff --git a/vc14/settings.props b/vc14/settings.props index 4c1b9fc9c..734846847 100644 --- a/vc14/settings.props +++ b/vc14/settings.props @@ -41,7 +41,7 @@ glew32d.lib; zlibd.lib; - zstdd.lib; + zstd.lib; physfs.lib; openal32.lib; lua51.lib;