Cpp11 initializers: last src root changeset (#6022)
[oweals/minetest.git] / src / shader.h
1 /*
2 Minetest
3 Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
4 Copyright (C) 2013 Kahrl <kahrl@gmx.net>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public License along
17 with this program; if not, write to the Free Software Foundation, Inc.,
18 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21 #ifndef SHADER_HEADER
22 #define SHADER_HEADER
23
24 #include <IMaterialRendererServices.h>
25 #include "irrlichttypes_extrabloated.h"
26 #include <string>
27
28 class IGameDef;
29
30 /*
31         shader.{h,cpp}: Shader handling stuff.
32 */
33
34 /*
35         Gets the path to a shader by first checking if the file
36           name_of_shader/filename
37         exists in shader_path and if not, using the data path.
38
39         If not found, returns "".
40
41         Utilizes a thread-safe cache.
42 */
43 std::string getShaderPath(const std::string &name_of_shader,
44                 const std::string &filename);
45
46 struct ShaderInfo {
47         std::string name = "";
48         video::E_MATERIAL_TYPE base_material = video::EMT_SOLID;
49         video::E_MATERIAL_TYPE material = video::EMT_SOLID;
50         u8 drawtype = 0;
51         u8 material_type = 0;
52
53         ShaderInfo() {}
54         virtual ~ShaderInfo() {}
55 };
56
57 /*
58         Setter of constants for shaders
59 */
60
61 namespace irr { namespace video {
62         class IMaterialRendererServices;
63 } }
64
65
66 class IShaderConstantSetter {
67 public:
68         virtual ~IShaderConstantSetter(){};
69         virtual void onSetConstants(video::IMaterialRendererServices *services,
70                         bool is_highlevel) = 0;
71 };
72
73
74 class IShaderConstantSetterFactory {
75 public:
76         virtual ~IShaderConstantSetterFactory() {};
77         virtual IShaderConstantSetter* create() = 0;
78 };
79
80
81 template <typename T, std::size_t count=1>
82 class CachedShaderSetting {
83         const char *m_name;
84         T m_sent[count];
85         bool has_been_set = false;
86         bool is_pixel;
87 protected:
88         CachedShaderSetting(const char *name, bool is_pixel) :
89                 m_name(name), is_pixel(is_pixel)
90         {}
91 public:
92         void set(const T value[count], video::IMaterialRendererServices *services)
93         {
94                 if (has_been_set && std::equal(m_sent, m_sent + count, value))
95                         return;
96                 if (is_pixel)
97                         services->setPixelShaderConstant(m_name, value, count);
98                 else
99                         services->setVertexShaderConstant(m_name, value, count);
100                 std::copy(value, value + count, m_sent);
101                 has_been_set = true;
102         }
103 };
104
105 template <typename T, std::size_t count = 1>
106 class CachedPixelShaderSetting : public CachedShaderSetting<T, count> {
107 public:
108         CachedPixelShaderSetting(const char *name) :
109                 CachedShaderSetting<T, count>(name, true){}
110 };
111
112 template <typename T, std::size_t count = 1>
113 class CachedVertexShaderSetting : public CachedShaderSetting<T, count> {
114 public:
115         CachedVertexShaderSetting(const char *name) :
116                 CachedShaderSetting<T, count>(name, false){}
117 };
118
119
120 /*
121         ShaderSource creates and caches shaders.
122 */
123
124 class IShaderSource {
125 public:
126         IShaderSource(){}
127         virtual ~IShaderSource(){}
128         virtual u32 getShaderIdDirect(const std::string &name,
129                 const u8 material_type, const u8 drawtype){return 0;}
130         virtual ShaderInfo getShaderInfo(u32 id){return ShaderInfo();}
131         virtual u32 getShader(const std::string &name,
132                 const u8 material_type, const u8 drawtype){return 0;}
133 };
134
135 class IWritableShaderSource : public IShaderSource {
136 public:
137         IWritableShaderSource(){}
138         virtual ~IWritableShaderSource(){}
139         virtual u32 getShaderIdDirect(const std::string &name,
140                 const u8 material_type, const u8 drawtype){return 0;}
141         virtual ShaderInfo getShaderInfo(u32 id){return ShaderInfo();}
142         virtual u32 getShader(const std::string &name,
143                 const u8 material_type, const u8 drawtype){return 0;}
144
145         virtual void processQueue()=0;
146         virtual void insertSourceShader(const std::string &name_of_shader,
147                 const std::string &filename, const std::string &program)=0;
148         virtual void rebuildShaders()=0;
149         virtual void addShaderConstantSetterFactory(IShaderConstantSetterFactory *setter) = 0;
150 };
151
152 IWritableShaderSource* createShaderSource(IrrlichtDevice *device);
153
154 void dumpShaderProgram(std::ostream &output_stream,
155         const std::string &program_type, const std::string &program);
156
157 #endif