Luanti 5.11.0-dev
 
Loading...
Searching...
No Matches
shader.h
Go to the documentation of this file.
1// Luanti
2// SPDX-License-Identifier: LGPL-2.1-or-later
3// Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
4// Copyright (C) 2013 Kahrl <kahrl@gmx.net>
5
6#pragma once
7
9#include <IMaterialRendererServices.h>
10#include <string>
11#include "nodedef.h"
12
13class IGameDef;
14
15/*
16 shader.{h,cpp}: Shader handling stuff.
17*/
18
19/*
20 Gets the path to a shader by first checking if the file
21 name_of_shader/filename
22 exists in shader_path and if not, using the data path.
23
24 If not found, returns "".
25
26 Utilizes a thread-safe cache.
27*/
28std::string getShaderPath(const std::string &name_of_shader,
29 const std::string &filename);
30
31struct ShaderInfo {
32 std::string name = "";
33 video::E_MATERIAL_TYPE base_material = video::EMT_SOLID;
34 video::E_MATERIAL_TYPE material = video::EMT_SOLID;
37
38 ShaderInfo() = default;
39 virtual ~ShaderInfo() = default;
40};
41
42/*
43 Setter of constants for shaders
44*/
45
46namespace irr::video {
47 class IMaterialRendererServices;
48}
49
50
52public:
53 virtual ~IShaderConstantSetter() = default;
54 virtual void onSetConstants(video::IMaterialRendererServices *services) = 0;
55 virtual void onSetMaterial(const video::SMaterial& material)
56 { }
57};
58
59
61public:
62 virtual ~IShaderConstantSetterFactory() = default;
64};
65
66
67template <typename T, std::size_t count, bool cache>
69 const char *m_name;
70 T m_sent[count];
71 bool has_been_set = false;
73protected:
74 CachedShaderSetting(const char *name, bool is_pixel) :
76 {}
77public:
78 void set(const T value[count], video::IMaterialRendererServices *services)
79 {
80 if (cache && has_been_set && std::equal(m_sent, m_sent + count, value))
81 return;
82 if (is_pixel)
83 services->setPixelShaderConstant(services->getPixelShaderConstantID(m_name), value, count);
84 else
85 services->setVertexShaderConstant(services->getVertexShaderConstantID(m_name), value, count);
86
87 if (cache) {
88 std::copy(value, value + count, m_sent);
89 has_been_set = true;
90 }
91 }
92
93 /* Type specializations */
94
95 /*
96 * T2 looks redundant here but it is necessary so the compiler won't
97 * resolve the templates at class instantiation and then fail because
98 * some of these methods don't have valid types (= are not usable).
99 * ref: <https://stackoverflow.com/a/6972771>
100 *
101 * Note: a `bool dummy` template parameter would have been easier but MSVC
102 * does not like that. Also make sure not to define different specializations
103 * with the same parameters, MSVC doesn't like that either.
104 * I extend my thanks to Microsoft®
105 */
106#define SPECIALIZE(_type, _count_expr) \
107 template<typename T2 = T> \
108 std::enable_if_t<std::is_same_v<T, T2> && std::is_same_v<T2, _type> && (_count_expr)>
109
110 SPECIALIZE(float, count == 2)
111 set(const v2f value, video::IMaterialRendererServices *services)
112 {
113 float array[2] = { value.X, value.Y };
114 set(array, services);
115 }
116
117 SPECIALIZE(float, count == 3)
118 set(const v3f value, video::IMaterialRendererServices *services)
119 {
120 float array[3] = { value.X, value.Y, value.Z };
121 set(array, services);
122 }
123
124 SPECIALIZE(float, count == 3 || count == 4)
125 set(const video::SColorf value, video::IMaterialRendererServices *services)
126 {
127 if constexpr (count == 3) {
128 float array[3] = { value.r, value.g, value.b };
129 set(array, services);
130 } else {
131 float array[4] = { value.r, value.g, value.b, value.a };
132 set(array, services);
133 }
134 }
135
136 SPECIALIZE(float, count == 16)
137 set(const core::matrix4 &value, video::IMaterialRendererServices *services)
138 {
139 set(value.pointer(), services);
140 }
141
142#undef SPECIALIZE
143};
144
145template <typename T, std::size_t count = 1, bool cache=true>
146class CachedPixelShaderSetting : public CachedShaderSetting<T, count, cache> {
147public:
148 CachedPixelShaderSetting(const char *name) :
149 CachedShaderSetting<T, count, cache>(name, true){}
150};
151
152template <typename T, std::size_t count = 1, bool cache=true>
153class CachedVertexShaderSetting : public CachedShaderSetting<T, count, cache> {
154public:
155 CachedVertexShaderSetting(const char *name) :
156 CachedShaderSetting<T, count, cache>(name, false){}
157};
158
159template <typename T, std::size_t count, bool cache, bool is_pixel>
161 const char *m_name;
162 T m_sent[count];
163 bool has_been_set = false;
164 std::array<const char*, count> m_fields;
165public:
166 CachedStructShaderSetting(const char *name, std::array<const char*, count> &&fields) :
167 m_name(name), m_fields(std::move(fields))
168 {}
169
170 void set(const T value[count], video::IMaterialRendererServices *services)
171 {
172 if (cache && has_been_set && std::equal(m_sent, m_sent + count, value))
173 return;
174
175 for (std::size_t i = 0; i < count; i++) {
176 std::string uniform_name = std::string(m_name) + "." + m_fields[i];
177
178 if (is_pixel)
179 services->setPixelShaderConstant(services->getPixelShaderConstantID(uniform_name.c_str()), value + i, 1);
180 else
181 services->setVertexShaderConstant(services->getVertexShaderConstantID(uniform_name.c_str()), value + i, 1);
182 }
183
184 if (cache) {
185 std::copy(value, value + count, m_sent);
186 has_been_set = true;
187 }
188 }
189};
190
191template<typename T, std::size_t count, bool cache = true>
193
194template<typename T, std::size_t count, bool cache = true>
196
197/*
198 ShaderSource creates and caches shaders.
199*/
200
202public:
203 IShaderSource() = default;
204 virtual ~IShaderSource() = default;
205
206 virtual u32 getShaderIdDirect(const std::string &name,
207 MaterialType material_type, NodeDrawType drawtype = NDT_NORMAL){return 0;}
208 virtual ShaderInfo getShaderInfo(u32 id){return ShaderInfo();}
209 virtual u32 getShader(const std::string &name,
210 MaterialType material_type, NodeDrawType drawtype = NDT_NORMAL){return 0;}
211};
212
214public:
216 virtual ~IWritableShaderSource() = default;
217
218 virtual void processQueue()=0;
219 virtual void insertSourceShader(const std::string &name_of_shader,
220 const std::string &filename, const std::string &program)=0;
221 virtual void rebuildShaders()=0;
222
225};
226
228
229void dumpShaderProgram(std::ostream &output_stream,
230 const std::string &program_type, std::string_view program);
Definition shader.h:146
CachedPixelShaderSetting(const char *name)
Definition shader.h:148
Definition shader.h:68
bool is_pixel
Definition shader.h:72
CachedShaderSetting(const char *name, bool is_pixel)
Definition shader.h:74
T m_sent[count]
Definition shader.h:70
bool has_been_set
Definition shader.h:71
const char * m_name
Definition shader.h:69
void set(const T value[count], video::IMaterialRendererServices *services)
Definition shader.h:78
Definition shader.h:160
void set(const T value[count], video::IMaterialRendererServices *services)
Definition shader.h:170
T m_sent[count]
Definition shader.h:162
std::array< const char *, count > m_fields
Definition shader.h:164
bool has_been_set
Definition shader.h:163
CachedStructShaderSetting(const char *name, std::array< const char *, count > &&fields)
Definition shader.h:166
const char * m_name
Definition shader.h:161
Definition shader.h:153
CachedVertexShaderSetting(const char *name)
Definition shader.h:155
Definition gamedef.h:36
Definition shader.h:60
virtual ~IShaderConstantSetterFactory()=default
virtual IShaderConstantSetter * create()=0
Definition shader.h:51
virtual void onSetConstants(video::IMaterialRendererServices *services)=0
virtual void onSetMaterial(const video::SMaterial &material)
Definition shader.h:55
virtual ~IShaderConstantSetter()=default
Definition shader.h:201
IShaderSource()=default
virtual ShaderInfo getShaderInfo(u32 id)
Definition shader.h:208
virtual ~IShaderSource()=default
virtual u32 getShader(const std::string &name, MaterialType material_type, NodeDrawType drawtype=NDT_NORMAL)
Definition shader.h:209
virtual u32 getShaderIdDirect(const std::string &name, MaterialType material_type, NodeDrawType drawtype=NDT_NORMAL)
Definition shader.h:206
Definition shader.h:213
virtual void rebuildShaders()=0
virtual ~IWritableShaderSource()=default
IWritableShaderSource()=default
virtual void insertSourceShader(const std::string &name_of_shader, const std::string &filename, const std::string &program)=0
virtual void processQueue()=0
virtual void addShaderConstantSetterFactory(IShaderConstantSetterFactory *setter)=0
core::vector2d< f32 > v2f
Definition irr_v2d.h:11
core::vector3df v3f
Definition irr_v3d.h:11
Definition clientmap.h:35
NodeDrawType
Definition nodedef.h:182
@ NDT_NORMAL
Definition nodedef.h:184
IWritableShaderSource * createShaderSource()
Definition shader.cpp:336
std::string getShaderPath(const std::string &name_of_shader, const std::string &filename)
Definition shader.cpp:45
#define SPECIALIZE(_type, _count_expr)
Definition shader.h:106
void dumpShaderProgram(std::ostream &output_stream, const std::string &program_type, std::string_view program)
Definition shader.cpp:755
Definition shader.h:31
std::string name
Definition shader.h:32
virtual ~ShaderInfo()=default
video::E_MATERIAL_TYPE base_material
Definition shader.h:33
MaterialType material_type
Definition shader.h:36
NodeDrawType drawtype
Definition shader.h:35
video::E_MATERIAL_TYPE material
Definition shader.h:34
ShaderInfo()=default
MaterialType
Definition tile.h:12
@ TILE_MATERIAL_BASIC
Definition tile.h:13