diff --git a/src/esp/assets/ResourceManager.cpp b/src/esp/assets/ResourceManager.cpp index d68e2e011b..2ad28f047f 100644 --- a/src/esp/assets/ResourceManager.cpp +++ b/src/esp/assets/ResourceManager.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -18,7 +19,8 @@ #include "esp/geo/geo.h" #include "esp/gfx/GenericDrawable.h" -#include "esp/gfx/GenericShader.h" +#include "esp/gfx/PrimitiveIDTexturedDrawable.h" +#include "esp/gfx/PrimitiveIDTexturedShader.h" #include "esp/io/io.h" #include "esp/io/json.h" #include "esp/scene/SceneConfiguration.h" @@ -69,9 +71,7 @@ Magnum::GL::AbstractShaderProgram* ResourceManager::getShaderProgram( switch (type) { case INSTANCE_MESH_SHADER: { shaderPrograms_[INSTANCE_MESH_SHADER] = - std::make_shared( - gfx::GenericShader::Flag::VertexColored | - gfx::GenericShader::Flag::PrimitiveIDTextured); + std::make_shared(); } break; #ifdef ESP_BUILD_PTEX_SUPPORT @@ -83,18 +83,22 @@ Magnum::GL::AbstractShaderProgram* ResourceManager::getShaderProgram( case COLORED_SHADER: { shaderPrograms_[COLORED_SHADER] = - std::make_shared(); + std::make_shared( + Magnum::Shaders::Flat3D::Flag::ObjectId); } break; case VERTEX_COLORED_SHADER: { shaderPrograms_[VERTEX_COLORED_SHADER] = - std::make_shared( - gfx::GenericShader::Flag::VertexColored); + std::make_shared( + Magnum::Shaders::Flat3D::Flag::ObjectId | + Magnum::Shaders::Flat3D::Flag::VertexColor); } break; case TEXTURED_SHADER: { - shaderPrograms_[TEXTURED_SHADER] = std::make_shared( - gfx::GenericShader::Flag::Textured); + shaderPrograms_[TEXTURED_SHADER] = + std::make_shared( + Magnum::Shaders::Flat3D::Flag::ObjectId | + Magnum::Shaders::Flat3D::Flag::Textured); } break; default: @@ -460,9 +464,14 @@ gfx::Drawable& ResourceManager::createDrawable( ASSERT(shaderType != PTEX_MESH_SHADER); // NOTE: this is a runtime error and will never return return *drawable; + } else if (shaderType == INSTANCE_MESH_SHADER) { + auto* shader = static_cast( + getShaderProgram(shaderType)); + drawable = new gfx::PrimitiveIDTexturedDrawable{node, *shader, mesh, group, + texture}; } else { // all other shaders use GenericShader auto* shader = - static_cast(getShaderProgram(shaderType)); + static_cast(getShaderProgram(shaderType)); drawable = new gfx::GenericDrawable{node, *shader, mesh, group, texture, objectId, color}; } diff --git a/src/esp/gfx/GenericDrawable.cpp b/src/esp/gfx/GenericDrawable.cpp index bd92f66a8b..fdd1e5b6f2 100644 --- a/src/esp/gfx/GenericDrawable.cpp +++ b/src/esp/gfx/GenericDrawable.cpp @@ -3,7 +3,9 @@ // LICENSE file in the root directory of this source tree. #include "GenericDrawable.h" -#include "GenericShader.h" + +#include + #include "esp/scene/SceneNode.h" namespace esp { @@ -11,7 +13,7 @@ namespace gfx { GenericDrawable::GenericDrawable( scene::SceneNode& node, - GenericShader& shader, + Magnum::Shaders::Flat3D& shader, Magnum::GL::Mesh& mesh, Magnum::SceneGraph::DrawableGroup3D* group /* = nullptr */, Magnum::GL::Texture2D* texture /* = nullptr */, @@ -24,24 +26,20 @@ GenericDrawable::GenericDrawable( void GenericDrawable::draw(const Magnum::Matrix4& transformationMatrix, Magnum::SceneGraph::Camera3D& camera) { - GenericShader& shader = static_cast(shader_); + Magnum::Shaders::Flat3D& shader = + static_cast(shader_); shader.setTransformationProjectionMatrix(camera.projectionMatrix() * transformationMatrix); - if (((shader.flags() & GenericShader::Flag::Textured) || - (shader.flags() & GenericShader::Flag::PrimitiveIDTextured)) && - texture_) { + if ((shader.flags() & Magnum::Shaders::Flat3D::Flag::Textured) && texture_) { shader.bindTexture(*texture_); } - if (!(shader.flags() & GenericShader::Flag::VertexColored)) { + if (!(shader.flags() & Magnum::Shaders::Flat3D::Flag::VertexColor)) { shader.setColor(color_); } - if (!(shader.flags() & GenericShader::Flag::PerVertexIds) && - !(shader.flags() & GenericShader::Flag::PrimitiveIDTextured)) { - shader.setObjectId(node_.getId()); - } + shader.setObjectId(node_.getId()); mesh_.draw(shader_); } diff --git a/src/esp/gfx/GenericDrawable.h b/src/esp/gfx/GenericDrawable.h index c9d60bd144..151c9685ac 100644 --- a/src/esp/gfx/GenericDrawable.h +++ b/src/esp/gfx/GenericDrawable.h @@ -4,20 +4,20 @@ #pragma once +#include + #include "Drawable.h" namespace esp { namespace gfx { -class GenericShader; - class GenericDrawable : public Drawable { public: //! Create a GenericDrawable for the given object using shader and mesh. //! Adds drawable to given group and uses provided texture, objectId, and //! color for textured, object id buffer and color shader output respectively explicit GenericDrawable(scene::SceneNode& node, - GenericShader& shader, + Magnum::Shaders::Flat3D& shader, Magnum::GL::Mesh& mesh, Magnum::SceneGraph::DrawableGroup3D* group = nullptr, Magnum::GL::Texture2D* texture = nullptr, diff --git a/src/esp/gfx/GenericShader.h b/src/esp/gfx/GenericShader.h deleted file mode 100644 index 6deac30316..0000000000 --- a/src/esp/gfx/GenericShader.h +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright (c) Facebook, Inc. and its affiliates. -// This source code is licensed under the MIT license found in the -// LICENSE file in the root directory of this source tree. - -#pragma once - -#include -#include - -#include - -#include -#include -#include - -#include "esp/core/esp.h" - -namespace esp { -namespace gfx { - -class GenericShader : public Magnum::GL::AbstractShaderProgram { - public: - //! Configuration flag - enum class Flag : uint8_t { - //! Multiply color with a texture - Textured = 1 << 0, - //! Use per-vertex colors - VertexColored = 1 << 1, - //! Use per-vertex ids encoded in vertex position[3] - PerVertexIds = 1 << 2, - //! Indexes a texture with the primitive id - PrimitiveIDTextured = 1 << 3, - }; - - //! Set of configuration flags - typedef Corrade::Containers::EnumSet Flags; - - /** - * @brief Constructor - * @param flags Flags - */ - explicit GenericShader(Flags flags = {}); - - //! @brief vertex positions - typedef Magnum::GL::Attribute<0, Magnum::Vector4> Position; - //! @brief texture coordinates - typedef Magnum::GL::Attribute<1, Magnum::Vector2> TextureCoordinates; - //! @brief vertex normals - typedef Magnum::GL::Attribute<2, Magnum::Vector3> Normal; - //! @brief vertex colors - typedef Magnum::GL::Attribute<3, Magnum::Vector3> Color; - - //! Color attachment location per output type - enum : uint8_t { - //! color output - ColorOutput = 0, - //! object id output - ObjectIdOutput = 1 - }; - - /** - * @return Configuration flags - */ - Flags flags() const { return flags_; } - - /** - * @brief Set transformation and projection matrix - * @return Reference to self (for method chaining) - */ - GenericShader& setTransformationProjectionMatrix( - const Magnum::Matrix4& matrix) { - setUniform(uniformLocation("transformationProjectionMatrix"), matrix); - return *this; - } - - /** - * @brief Set color - * @return Reference to self (for method chaining) - * - * If @ref Flag::Textured is set, initial value is @cpp 0xffffffff_rgbaf @ce - * and the color will be multiplied with texture. - * @see @ref bindTexture() - */ - GenericShader& setColor(const Magnum::Color4& color) { - setUniform(uniformLocation("colorUniform"), color); - return *this; - } - - /** - * @brief Set object id - * @return Reference to self (for method chaining) - */ - GenericShader& setObjectId(int objectId) { - setUniform(uniformLocation("objectIdUniform"), objectId); - return *this; - } - - /** - * @brief Bind a color texture - * @return Reference to self (for method chaining) - * - * Expects that the shader was created with @ref Flag::Textured enabled. - * @see @ref setColor() - */ - GenericShader& bindTexture(Magnum::GL::Texture2D& texture); - - protected: - Flags flags_; -}; - -CORRADE_ENUMSET_OPERATORS(GenericShader::Flags) - -} // namespace gfx -} // namespace esp diff --git a/src/esp/gfx/PrimitiveIDTexturedDrawable.cpp b/src/esp/gfx/PrimitiveIDTexturedDrawable.cpp new file mode 100644 index 0000000000..8c1d14bdc6 --- /dev/null +++ b/src/esp/gfx/PrimitiveIDTexturedDrawable.cpp @@ -0,0 +1,34 @@ +// Copyright (c) Facebook, Inc. and its affiliates. +// This source code is licensed under the MIT license found in the +// LICENSE file in the root directory of this source tree. + +#include "PrimitiveIDTexturedDrawable.h" +#include "PrimitiveIDTexturedShader.h" +#include "esp/scene/SceneNode.h" + +namespace esp { +namespace gfx { + +PrimitiveIDTexturedDrawable::PrimitiveIDTexturedDrawable( + scene::SceneNode& node, + PrimitiveIDTexturedShader& shader, + Magnum::GL::Mesh& mesh, + Magnum::SceneGraph::DrawableGroup3D* group /* = nullptr */, + Magnum::GL::Texture2D* texture /* = nullptr */) + : Drawable{node, shader, mesh, group}, texture_(texture) {} + +void PrimitiveIDTexturedDrawable::draw( + const Magnum::Matrix4& transformationMatrix, + Magnum::SceneGraph::Camera3D& camera) { + PrimitiveIDTexturedShader& shader = + static_cast(shader_); + shader + .setTransformationProjectionMatrix(camera.projectionMatrix() * + transformationMatrix) + .bindTexture(*texture_); + + mesh_.draw(shader_); +} + +} // namespace gfx +} // namespace esp diff --git a/src/esp/gfx/PrimitiveIDTexturedDrawable.h b/src/esp/gfx/PrimitiveIDTexturedDrawable.h new file mode 100644 index 0000000000..228ea329a0 --- /dev/null +++ b/src/esp/gfx/PrimitiveIDTexturedDrawable.h @@ -0,0 +1,34 @@ +// Copyright (c) Facebook, Inc. and its affiliates. +// This source code is licensed under the MIT license found in the +// LICENSE file in the root directory of this source tree. + +#pragma once + +#include "Drawable.h" + +namespace esp { +namespace gfx { + +class PrimitiveIDTexturedShader; + +class PrimitiveIDTexturedDrawable : public Drawable { + public: + //! Create a GenericDrawable for the given object using shader and mesh. + //! Adds drawable to given group and uses provided texture, objectId, and + //! color for textured, object id buffer and color shader output respectively + explicit PrimitiveIDTexturedDrawable( + scene::SceneNode& node, + PrimitiveIDTexturedShader& shader, + Magnum::GL::Mesh& mesh, + Magnum::SceneGraph::DrawableGroup3D* group = nullptr, + Magnum::GL::Texture2D* texture = nullptr); + + protected: + virtual void draw(const Magnum::Matrix4& transformationMatrix, + Magnum::SceneGraph::Camera3D& camera) override; + + Magnum::GL::Texture2D* texture_; +}; + +} // namespace gfx +} // namespace esp diff --git a/src/esp/gfx/GenericShader.cpp b/src/esp/gfx/PrimitiveIDTexturedShader.cpp similarity index 56% rename from src/esp/gfx/GenericShader.cpp rename to src/esp/gfx/PrimitiveIDTexturedShader.cpp index e326daf822..e6a5e20a8c 100644 --- a/src/esp/gfx/GenericShader.cpp +++ b/src/esp/gfx/PrimitiveIDTexturedShader.cpp @@ -2,7 +2,7 @@ // This source code is licensed under the MIT license found in the // LICENSE file in the root directory of this source tree. -#include "GenericShader.h" +#include "PrimitiveIDTexturedShader.h" #include #include @@ -22,13 +22,11 @@ static void importShaderResources() { namespace esp { namespace gfx { -// TODO: Use Corrade resource file for shader code instead of hard-coding here - namespace { enum { TextureLayer = 0 }; } -GenericShader::GenericShader(const Flags flags) : flags_(flags) { +PrimitiveIDTexturedShader::PrimitiveIDTexturedShader() { #ifndef MAGNUM_TARGET_WEBGL MAGNUM_ASSERT_GL_VERSION_SUPPORTED(Magnum::GL::Version::GL410); #endif @@ -49,16 +47,8 @@ GenericShader::GenericShader(const Flags flags) : flags_(flags) { Magnum::GL::Shader vert{glVersion, Magnum::GL::Shader::Type::Vertex}; Magnum::GL::Shader frag{glVersion, Magnum::GL::Shader::Type::Fragment}; - vert.addSource(flags & Flag::Textured ? "#define TEXTURED\n" : "") - .addSource(flags & Flag::VertexColored ? "#define VERTEX_COLORED\n" : "") - .addSource(flags & Flag::PerVertexIds ? "#define PER_VERTEX_IDS\n" : "") - .addSource(rs.get("generic-default-gl410.vert")); - frag.addSource(flags & Flag::Textured ? "#define TEXTURED\n" : "") - .addSource(flags & Flag::VertexColored ? "#define VERTEX_COLORED\n" : "") - .addSource(flags & Flag::PerVertexIds ? "#define PER_VERTEX_IDS\n" : "") - .addSource(flags & Flag::PrimitiveIDTextured ? "#define ID_TEXTURED\n" - : "") - .addSource(rs.get("generic-default-gl410.frag")); + vert.addSource(rs.get("primitive-id-textured-gl410.vert")); + frag.addSource(rs.get("primitive-id-textured-gl410.frag")); CORRADE_INTERNAL_ASSERT_OUTPUT(Magnum::GL::Shader::compile({vert, frag})); @@ -66,24 +56,16 @@ GenericShader::GenericShader(const Flags flags) : flags_(flags) { CORRADE_INTERNAL_ASSERT_OUTPUT(link()); - if (flags & Flag::Textured) { - setUniform(uniformLocation("textureData"), TextureLayer); - } - - if (flags & Flag::PrimitiveIDTextured) { - setUniform(uniformLocation("primTexture"), TextureLayer); - } + setUniform(uniformLocation("primTexture"), TextureLayer); } -GenericShader& GenericShader::bindTexture(Magnum::GL::Texture2D& texture) { - ASSERT((flags_ & Flag::Textured) || (flags_ & Flag::PrimitiveIDTextured)); - +PrimitiveIDTexturedShader& PrimitiveIDTexturedShader::bindTexture( + Magnum::GL::Texture2D& texture) { texture.bind(TextureLayer); // TODO this is a hack and terrible! Properly set texSize for WebGL builds #ifndef MAGNUM_TARGET_WEBGL - if (flags_ & Flag::PrimitiveIDTextured) - setUniform(uniformLocation("texSize"), texture.imageSize(0).x()); + setUniform(uniformLocation("texSize"), texture.imageSize(0).x()); #endif return *this; diff --git a/src/esp/gfx/PrimitiveIDTexturedShader.h b/src/esp/gfx/PrimitiveIDTexturedShader.h new file mode 100644 index 0000000000..5cf1ff1c42 --- /dev/null +++ b/src/esp/gfx/PrimitiveIDTexturedShader.h @@ -0,0 +1,62 @@ +// Copyright (c) Facebook, Inc. and its affiliates. +// This source code is licensed under the MIT license found in the +// LICENSE file in the root directory of this source tree. + +#pragma once + +#include +#include + +#include + +#include +#include +#include + +#include "esp/core/esp.h" + +namespace esp { +namespace gfx { + +class PrimitiveIDTexturedShader : public Magnum::GL::AbstractShaderProgram { + public: + /** + * @brief Constructor + */ + explicit PrimitiveIDTexturedShader(); + + //! @brief vertex positions + typedef Magnum::GL::Attribute<0, Magnum::Vector4> Position; + //! @brief vertex colors + typedef Magnum::GL::Attribute<3, Magnum::Vector3> Color; + + //! Color attachment location per output type + enum : uint8_t { + //! color output + ColorOutput = 0, + //! object id output + ObjectIdOutput = 1 + }; + + /** + * @brief Set transformation and projection matrix + * @return Reference to self (for method chaining) + */ + PrimitiveIDTexturedShader& setTransformationProjectionMatrix( + const Magnum::Matrix4& matrix) { + setUniform(uniformLocation("transformationProjectionMatrix"), matrix); + return *this; + } + + /** + * @brief Bind a color texture + * @return Reference to self (for method chaining) + * + * Expects that the shader was created with @ref Flag::Textured enabled. + * @see @ref setColor() + */ + PrimitiveIDTexturedShader& bindTexture(Magnum::GL::Texture2D& texture); +}; + +} // namespace gfx +} // namespace esp diff --git a/src/esp/gfx/Renderer.cpp b/src/esp/gfx/Renderer.cpp index c90b085d14..2253b4e6f2 100644 --- a/src/esp/gfx/Renderer.cpp +++ b/src/esp/gfx/Renderer.cpp @@ -6,6 +6,7 @@ #include "magnum.h" +#include #include #include #include diff --git a/src/shaders/Shaders.conf b/src/shaders/Shaders.conf index 0db9664660..9a12c54ba5 100644 --- a/src/shaders/Shaders.conf +++ b/src/shaders/Shaders.conf @@ -1,10 +1,10 @@ group = default-shaders [file] -filename = generic-default-gl410.vert +filename = primitive-id-textured-gl410.vert [file] -filename = generic-default-gl410.frag +filename = primitive-id-textured-gl410.frag [file] filename = ptex-default-gl410.vert diff --git a/src/shaders/generic-default-gl410.frag b/src/shaders/generic-default-gl410.frag deleted file mode 100644 index acb8c65b6e..0000000000 --- a/src/shaders/generic-default-gl410.frag +++ /dev/null @@ -1,53 +0,0 @@ -in mediump vec3 v_color; - - -#ifdef PER_VERTEX_IDS -flat in uint v_objectId; -#else -uniform highp int objectIdUniform; -#endif - -#ifdef TEXTURED -uniform lowp sampler2D textureData; -in mediump vec2 interpolatedTextureCoordinates; -#endif - -#ifdef ID_TEXTURED -uniform highp sampler2D primTexture; -uniform highp int texSize; -#endif - -#ifndef VERTEX_COLORED -uniform lowp vec4 colorUniform; -#endif - -layout(location = 0) out mediump vec4 color; -layout(location = 1) out uint objectId; - -void main () { - mediump vec4 baseColor = - #ifdef VERTEX_COLORED - vec4(v_color, 1.0); - #else - colorUniform; - #endif - color = - #ifdef TEXTURED - texture(textureData, interpolatedTextureCoordinates) * - #endif - baseColor; - objectId = - #ifdef PER_VERTEX_IDS - v_objectId; - #else - uint(objectIdUniform); - #endif - - #ifdef ID_TEXTURED - objectId = uint( - texture(primTexture, - vec2((float(gl_PrimitiveID % texSize) + 0.5f) / float(texSize), - (float(gl_PrimitiveID / texSize) + 0.5f) / float(texSize))) - .r + 0.5); - #endif -} diff --git a/src/shaders/generic-default-gl410.vert b/src/shaders/generic-default-gl410.vert deleted file mode 100644 index 7b8fbcaa61..0000000000 --- a/src/shaders/generic-default-gl410.vert +++ /dev/null @@ -1,33 +0,0 @@ -uniform highp mat4 transformationProjectionMatrix; - -layout(location = 0) in highp vec4 position; - -#ifdef TEXTURED -layout(location = 1) in mediump vec2 textureCoordinates; -out mediump vec2 interpolatedTextureCoordinates; -#endif - -#ifdef VERTEX_COLORED -layout(location = 1) in mediump vec3 color; -#endif - -out mediump vec3 v_color; - -#ifdef PER_VERTEX_IDS -flat out uint v_objectId; -#endif - -void main() { - gl_Position = transformationProjectionMatrix * vec4(position.xyz, 1.0); - - #ifdef TEXTURED - interpolatedTextureCoordinates = textureCoordinates; - #endif - - #ifdef VERTEX_COLORED - v_color = color; - #endif - #ifdef PER_VERTEX_IDS - v_objectId = uint(position.w); - #endif -} diff --git a/src/shaders/primitive-id-textured-gl410.frag b/src/shaders/primitive-id-textured-gl410.frag new file mode 100644 index 0000000000..5cb685402f --- /dev/null +++ b/src/shaders/primitive-id-textured-gl410.frag @@ -0,0 +1,16 @@ +in mediump vec3 v_color; + +uniform highp sampler2D primTexture; +uniform highp int texSize; + +layout(location = 0) out mediump vec4 color; +layout(location = 1) out uint objectId; + +void main () { + color = vec4(v_color, 1.0); + objectId = uint( + texture(primTexture, + vec2((float(gl_PrimitiveID % texSize) + 0.5f) / float(texSize), + (float(gl_PrimitiveID / texSize) + 0.5f) / float(texSize))) + .r + 0.5); +} diff --git a/src/shaders/primitive-id-textured-gl410.vert b/src/shaders/primitive-id-textured-gl410.vert new file mode 100644 index 0000000000..7a6f0282df --- /dev/null +++ b/src/shaders/primitive-id-textured-gl410.vert @@ -0,0 +1,11 @@ +uniform highp mat4 transformationProjectionMatrix; + +layout(location = 0) in highp vec4 position; +layout(location = 1) in mediump vec3 color; + +out mediump vec3 v_color; + +void main() { + gl_Position = transformationProjectionMatrix * vec4(position.xyz, 1.0); + v_color = color; +}