From 46a58b926866a523a37d0e8505a7ac301baac237 Mon Sep 17 00:00:00 2001 From: Roman Sorokin Date: Mon, 25 Aug 2014 14:50:37 +0300 Subject: [PATCH] Added functions to process shaders --- drape/shader.cpp | 63 +++++++++++++++++++++++++++++++++++++++++++++--- drape/shader.hpp | 8 +++++- 2 files changed, 67 insertions(+), 4 deletions(-) diff --git a/drape/shader.cpp b/drape/shader.cpp index ed27bdbdc6..a6b64ede32 100644 --- a/drape/shader.cpp +++ b/drape/shader.cpp @@ -1,14 +1,26 @@ #include "shader.hpp" -#include "glfunctions.hpp" #include "../base/assert.hpp" +#include "../base/string_utils.hpp" + namespace dp { +#if defined(OMIM_OS_DESKTOP) && !defined(COMPILER_TESTS) + #define LOW_P string("") + #define MEDIUM_P string("") + #define HIGH_P string("") +#else + #define LOW_P string("lowp") + #define MEDIUM_P string("mediump") + #define HIGH_P string("highp") +#endif + +using strings::to_string; + namespace { - glConst convert(Shader::Type t) { if (t == Shader::VertexShader) @@ -17,7 +29,51 @@ glConst convert(Shader::Type t) return gl_const::GLFragmentShader; } -} // namespace +void ResolveGetTexel(string & result, string const & sampler, int count) +{ + string const index = "Index"; + string const answer = "answer"; + string const texindex = "texIndex"; + string const texcoord = "texCoord"; + + for (int i = 0; i < count; ++i) + { + result += "const int " + index + to_string(i) + " = " + to_string(i) + ";\n"; + } + result += "\n"; + + result += "uniform sampler2D u_textures[" + to_string(count) + "];\n"; + + //Head + result += MEDIUM_P + " vec4 getTexel(int " + texindex + ", " + LOW_P + " vec2 " + texcoord + ") \n"; + result += "{\n"; + result += " " + MEDIUM_P + " vec4 " + answer + "; \n"; + //Body + result += " if (" + texindex + " == " + index + "0) \n"; + result += " " + answer + " = texture2D(" + sampler + "[" + index + "0], " + texcoord + "); \n"; + for (int i = 1; i < count; ++i) + { + string num = to_string(i); + result += " else if (" + texindex + " == " + index + num + ") \n"; + result += " " + answer + " = texture2D(" + sampler + "[" + index + num + "], " + texcoord + "); \n"; + } + //Tail + result += " return " + answer + ";\n"; + result += "}\n"; +} +} + +void sh::Inject(string & src) +{ + string const replacement("~getTexel~"); + int const pos = src.find(replacement); + if (pos == string::npos) + return; + string injector = ""; + int const count = min(8, GLFunctions::glGetInteger(gl_const::GLMaxFragmentTextures)); + ResolveGetTexel(injector, "u_textures", count); + src.replace(pos, replacement.length(), injector); +} Shader::Shader(string const & shaderSource, Type type) : m_source(shaderSource) @@ -25,6 +81,7 @@ Shader::Shader(string const & shaderSource, Type type) , m_glID(0) { m_glID = GLFunctions::glCreateShader(convert(m_type)); + sh::Inject(m_source); GLFunctions::glShaderSource(m_glID, m_source); string errorLog; bool result = GLFunctions::glCompileShader(m_glID, errorLog); diff --git a/drape/shader.hpp b/drape/shader.hpp index 31cdf02638..157e9a0fcf 100644 --- a/drape/shader.hpp +++ b/drape/shader.hpp @@ -1,4 +1,5 @@ #pragma once +#include "glfunctions.hpp" #include "../std/string.hpp" #include "../std/stdint.hpp" @@ -21,9 +22,14 @@ public: int GetID() const; private: - string const m_source; + string m_source; Type m_type; uint32_t m_glID; }; +namespace sh +{ + void Inject(string & src); +} + } // namespace dp