1 /**
2  * Copyright (c) 2006-2016 LOVE Development Team
3  *
4  * This software is provided 'as-is', without any express or implied
5  * warranty.  In no event will the authors be held liable for any damages
6  * arising from the use of this software.
7  *
8  * Permission is granted to anyone to use this software for any purpose,
9  * including commercial applications, and to alter it and redistribute it
10  * freely, subject to the following restrictions:
11  *
12  * 1. The origin of this software must not be misrepresented; you must not
13  *    claim that you wrote the original software. If you use this software
14  *    in a product, an acknowledgment in the product documentation would be
15  *    appreciated but is not required.
16  * 2. Altered source versions must be plainly marked as such, and must not be
17  *    misrepresented as being the original software.
18  * 3. This notice may not be removed or altered from any source distribution.
19  **/
20 
21 #ifndef LOVE_GRAPHICS_SHADER_H
22 #define LOVE_GRAPHICS_SHADER_H
23 
24 // LOVE
25 #include "common/Object.h"
26 #include "common/StringMap.h"
27 #include "graphics/Graphics.h"
28 #include "graphics/Texture.h"
29 #include "graphics/Volatile.h"
30 #include "OpenGL.h"
31 
32 // STL
33 #include <string>
34 #include <map>
35 #include <vector>
36 
37 namespace love
38 {
39 namespace graphics
40 {
41 namespace opengl
42 {
43 
44 class Canvas;
45 
46 // A GLSL shader
47 class Shader : public Object, public Volatile
48 {
49 public:
50 
51 	enum ShaderStage
52 	{
53 		STAGE_VERTEX,
54 		STAGE_PIXEL,
55 		STAGE_MAX_ENUM
56 	};
57 
58 	// Built-in uniform (extern) variables.
59 	enum BuiltinUniform
60 	{
61 		BUILTIN_TRANSFORM_MATRIX = 0,
62 		BUILTIN_PROJECTION_MATRIX,
63 		BUILTIN_TRANSFORM_PROJECTION_MATRIX,
64 		BUILTIN_NORMAL_MATRIX,
65 		BUILTIN_POINT_SIZE,
66 		BUILTIN_SCREEN_SIZE,
67 		BUILTIN_VIDEO_Y_CHANNEL,
68 		BUILTIN_VIDEO_CB_CHANNEL,
69 		BUILTIN_VIDEO_CR_CHANNEL,
70 		BUILTIN_MAX_ENUM
71 	};
72 
73 	// Types of potential uniform (extern) variables used in love's shaders.
74 	enum UniformType
75 	{
76 		UNIFORM_FLOAT,
77 		UNIFORM_MATRIX,
78 		UNIFORM_INT,
79 		UNIFORM_BOOL,
80 		UNIFORM_SAMPLER,
81 		UNIFORM_UNKNOWN,
82 		UNIFORM_MAX_ENUM
83 	};
84 
85 	struct ShaderSource
86 	{
87 		std::string vertex;
88 		std::string pixel;
89 	};
90 
91 	struct UniformInfo
92 	{
93 		int location;
94 		int count;
95 		int components;
96 		UniformType baseType;
97 		std::string name;
98 	};
99 
100 	// Pointer to currently active Shader.
101 	static Shader *current;
102 
103 	// Pointer to the default Shader.
104 	static Shader *defaultShader;
105 	static Shader *defaultVideoShader;
106 
107 	// Default shader code (a shader is always required internally.)
108 	static ShaderSource defaultCode[Graphics::RENDERER_MAX_ENUM][2];
109 	static ShaderSource defaultVideoCode[Graphics::RENDERER_MAX_ENUM][2];
110 
111 	/**
112 	 * Creates a new Shader using a list of source codes.
113 	 * Source must contain either vertex or pixel shader code, or both.
114 	 **/
115 	Shader(const ShaderSource &source);
116 
117 	virtual ~Shader();
118 
119 	// Implements Volatile
120 	virtual bool loadVolatile();
121 	virtual void unloadVolatile();
122 
123 	/**
124 	 * Binds this Shader's program to be used when rendering.
125 	 *
126 	 * @param temporary True if we just want to send values to the shader with no intention of rendering.
127 	 **/
128 	void attach(bool temporary = false);
129 
130 	/**
131 	 * Detach the currently bound Shader.
132 	 * Causes the GPU rendering pipeline to use fixed functionality in place of shader programs.
133 	 **/
134 	static void detach();
135 
136 	/**
137 	 * Returns any warnings this Shader may have generated.
138 	 **/
139 	std::string getWarnings() const;
140 
141 	const UniformInfo *getUniformInfo(const std::string &name) const;
142 
143 	void sendInts(const UniformInfo *info, const int *vec, int count);
144 	void sendFloats(const UniformInfo *info, const float *vec, int count);
145 	void sendMatrices(const UniformInfo *info, const float *m, int count);
146 	void sendTexture(const UniformInfo *info, Texture *texture);
147 
148 	/**
149 	 * Gets the type, number of components, and number of array elements of
150 	 * an active 'extern' (uniform) variable in the shader. If a uniform
151 	 * variable with the specified name doesn't exist, returns UNIFORM_UNKNOWN
152 	 * and sets the 'components' and 'count' values to 0.
153 	 *
154 	 * @param name The name of the uniform variable in the source code.
155 	 * @param[out] components Number of components of the variable (2 for vec2.)
156 	 * @param[out] count Number of array elements, if the variable is an array.
157 	 * @return The base type of the uniform variable.
158 	 **/
159 	UniformType getExternVariable(const std::string &name, int &components, int &count);
160 
161 	GLint getAttribLocation(const std::string &name);
162 
163 	/**
164 	 * Internal use only.
165 	 **/
166 	bool hasVertexAttrib(VertexAttribID attrib) const;
167 
168 	void setVideoTextures(GLuint ytexture, GLuint cbtexture, GLuint crtexture);
169 	void checkSetScreenParams();
170 	void checkSetPointSize(float size);
171 	void checkSetBuiltinUniforms();
172 
173 	const std::map<std::string, Object *> &getBoundRetainables() const;
174 
getProgram()175 	GLuint getProgram() const
176 	{
177 		return program;
178 	}
179 
180 	template <typename T>
getScratchBuffer(size_t count)181 	T *getScratchBuffer(size_t count)
182 	{
183 		size_t bytes = sizeof(T) * count;
184 
185 		if (scratchBuffer.size() < bytes)
186 			scratchBuffer.resize(bytes);
187 
188 		return (T *) scratchBuffer.data();
189 	}
190 
191 	static std::string getGLSLVersion();
192 	static bool isSupported();
193 
194 	static bool getConstant(const char *in, UniformType &out);
195 	static bool getConstant(UniformType in, const char *&out);
196 
197 	static bool getConstant(const char *in, VertexAttribID &out);
198 	static bool getConstant(VertexAttribID in, const char *&out);
199 
200 private:
201 
202 	// Map active uniform names to their locations.
203 	void mapActiveUniforms();
204 
205 	int getUniformTypeSize(GLenum type) const;
206 	UniformType getUniformBaseType(GLenum type) const;
207 
208 	GLuint compileCode(ShaderStage stage, const std::string &code);
209 
210 	int getTextureUnit(const std::string &name);
211 
212 	void retainObject(const std::string &name, Object *object);
213 
214 	// Get any warnings or errors generated only by the shader program object.
215 	std::string getProgramWarnings() const;
216 
217 	// Source code used for this Shader.
218 	ShaderSource shaderSource;
219 
220 	// Shader compiler warning strings for individual shader stages.
221 	std::map<ShaderStage, std::string> shaderWarnings;
222 
223 	// volatile
224 	GLuint program;
225 
226 	// Location values for any built-in uniform variables.
227 	GLint builtinUniforms[BUILTIN_MAX_ENUM];
228 
229 	// Location values for any generic vertex attribute variables.
230 	GLint builtinAttributes[ATTRIB_MAX_ENUM];
231 
232 	std::map<std::string, GLint> attributes;
233 
234 	// Uniform location buffer map
235 	std::map<std::string, UniformInfo> uniforms;
236 
237 	// Texture unit pool for setting images
238 	std::map<std::string, GLint> texUnitPool; // texUnitPool[name] = textureunit
239 	std::vector<GLuint> activeTexUnits; // activeTexUnits[textureunit-1] = textureid
240 
241 	// Uniform name to retainable objects
242 	std::map<std::string, Object*> boundRetainables;
243 
244 	// Pointer to the active Canvas when the screen params were last checked.
245 	Canvas *lastCanvas;
246 	OpenGL::Viewport lastViewport;
247 
248 	float lastPointSize;
249 
250 	Matrix4 lastTransformMatrix;
251 	Matrix4 lastProjectionMatrix;
252 
253 	GLuint videoTextureUnits[3];
254 
255 	std::vector<char> scratchBuffer;
256 
257 	// Counts total number of textures bound to each texture unit in all shaders
258 	static std::vector<int> textureCounters;
259 
260 	static StringMap<ShaderStage, STAGE_MAX_ENUM>::Entry stageNameEntries[];
261 	static StringMap<ShaderStage, STAGE_MAX_ENUM> stageNames;
262 
263 	static StringMap<UniformType, UNIFORM_MAX_ENUM>::Entry uniformTypeEntries[];
264 	static StringMap<UniformType, UNIFORM_MAX_ENUM> uniformTypes;
265 
266 	// Names for the generic vertex attributes used by love.
267 	static StringMap<VertexAttribID, ATTRIB_MAX_ENUM>::Entry attribNameEntries[];
268 	static StringMap<VertexAttribID, ATTRIB_MAX_ENUM> attribNames;
269 
270 	// Names for the built-in uniform variables.
271 	static StringMap<BuiltinUniform, BUILTIN_MAX_ENUM>::Entry builtinNameEntries[];
272 	static StringMap<BuiltinUniform, BUILTIN_MAX_ENUM> builtinNames;
273 };
274 
275 } // opengl
276 } // graphics
277 } // love
278 
279 #endif // LOVE_GRAPHICS_SHADER_H
280