1 /*
2  * Copyright (C) 2006-2019 Christopho, Solarus - http://www.solarus-games.org
3  *
4  * Solarus is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * Solarus is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program. If not, see <http://www.gnu.org/licenses/>.
16  */
17 #ifndef SOLARUS_SHADER_H
18 #define SOLARUS_SHADER_H
19 
20 #include "solarus/core/Common.h"
21 #include "solarus/core/Debug.h"
22 #include "solarus/graphics/BlendMode.h"
23 #include "solarus/graphics/Drawable.h"
24 #include "solarus/graphics/ShaderData.h"
25 #include "solarus/graphics/SurfacePtr.h"
26 #include "solarus/graphics/VertexArrayPtr.h"
27 #include "solarus/lua/ExportableToLua.h"
28 #include <glm/mat3x3.hpp>
29 #include <glm/mat4x4.hpp>
30 #include <map>
31 #include <string>
32 #include <unordered_map>
33 
34 namespace Solarus {
35 
36 /**
37  * \brief Represents a shader for a driver and sampler-independant uses.
38  */
39 class SOLARUS_API Shader : public DrawProxy, public ExportableToLua {
40   public:
41     constexpr static const char* POSITION_NAME = "sol_vertex";
42     constexpr static const char* TEXCOORD_NAME = "sol_tex_coord";
43     constexpr static const char* COLOR_NAME = "sol_color";
44     constexpr static const char* MVP_MATRIX_NAME = "sol_mvp_matrix";
45     constexpr static const char* UV_MATRIX_NAME = "sol_uv_matrix";
46     constexpr static const char* TEXTURE_NAME = "sol_texture";
47     constexpr static const char* INPUT_SIZE_NAME = "sol_input_size";
48     constexpr static const char* OUTPUT_SIZE_NAME = "sol_output_size";
49     constexpr static const char* TIME_NAME = "sol_time";
50     constexpr static const char* OPACITY_NAME = "sol_opacity";
51 
52     explicit Shader(const std::string& shader_id);
53     Shader(const std::string& vertex_source,
54            const std::string& fragment_source,
55            double scaling_factor);
56 
57     bool is_valid() const;
58     std::string get_error() const;
59 
60     const std::string& get_id() const;
61     const ShaderData& get_data() const;
62 
63     std::string get_vertex_source() const;
64     std::string get_fragment_source() const;
65 
66     double get_scaling_factor() const;
67     void set_scaling_factor(double scaling_factor);
68 
69     virtual void set_uniform_1b(
70         const std::string& uniform_name, bool value) = 0;
71     virtual void set_uniform_1i(
72         const std::string& uniform_name, int value) = 0;
73     virtual void set_uniform_1f(
74         const std::string& uniform_name, float value) = 0;
75     virtual void set_uniform_2f(
76         const std::string& uniform_name, float value_1, float value_2) = 0;
77     virtual void set_uniform_3f(
78         const std::string& uniform_name, float value_1, float value_2, float value_3) = 0;
79     virtual void set_uniform_4f(
80         const std::string& uniform_name, float value_1, float value_2, float value_3, float value_4) = 0;
81     virtual bool set_uniform_texture(const std::string& uniform_name, const SurfacePtr& value) = 0;
82 
as()83     template<class T> const T& as() const {
84       return *reinterpret_cast<const T*>(this);
85     }
86 
as()87     template<class T> T& as() {
88       return *reinterpret_cast<T*>(this); //TODO check if reinterpret is safe => it should
89     }
90 
91     const std::string& get_lua_type_name() const override;
92 
93   protected:
94     void set_valid(bool valid);
95     void set_error(const std::string& error);
96     void set_data(const ShaderData& data);
97     static void setup_version_string();
98     std::string get_sanitized_vertex_source() const;
99     std::string get_sanitized_fragment_source() const;
100   private:
101     static std::string sanitize_shader_source(const std::string& source);
102     static std::string version_string;
103 
104     const std::string shader_id;  /**< The id of the shader (filename without extension). */
105     ShaderData data;              /**< The loaded shader data file. */
106     std::string vertex_source;    /**< Vertex shader code. */
107     std::string fragment_source;  /**< Fragment shader code. */
108     bool valid;                   /**< \c true if the compilation succedeed. */
109     std::string error;            /**< Error message of the last operation if any. */
110 };
111 
112 }
113 
114 #endif
115