1/**
2 * Copyright (c) 2006-2023 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#pragma once
22
23// LOVE
24#include "graphics/Shader.h"
25#include "graphics/Graphics.h"
26#include "graphics/Volatile.h"
27#include "OpenGL.h"
28
29// STL
30#include <string>
31#include <map>
32#include <vector>
33
34namespace love
35{
36namespace graphics
37{
38namespace opengl
39{
40
41// A GLSL shader
42class Shader final : public love::graphics::Shader, public Volatile
43{
44public:
45
46 /**
47 * Creates a new Shader using a list of source codes.
48 * Source must contain either vertex or pixel shader code, or both.
49 **/
50 Shader(love::graphics::ShaderStage *vertex, love::graphics::ShaderStage *pixel);
51 virtual ~Shader();
52
53 // Implements Volatile
54 bool loadVolatile() override;
55 void unloadVolatile() override;
56
57 // Implements Shader.
58 void attach() override;
59 std::string getWarnings() const override;
60 int getVertexAttributeIndex(const std::string &name) override;
61 const UniformInfo *getUniformInfo(const std::string &name) const override;
62 const UniformInfo *getUniformInfo(BuiltinUniform builtin) const override;
63 void updateUniform(const UniformInfo *info, int count) override;
64 void sendTextures(const UniformInfo *info, Texture **textures, int count) override;
65 bool hasUniform(const std::string &name) const override;
66 ptrdiff_t getHandle() const override;
67 void setVideoTextures(Texture *ytexture, Texture *cbtexture, Texture *crtexture) override;
68
69 void updateScreenParams();
70 void updatePointSize(float size);
71 void updateBuiltinUniforms();
72
73 static std::string getGLSLVersion();
74 static bool isSupported();
75
76private:
77
78 struct TextureUnit
79 {
80 GLuint texture = 0;
81 TextureType type = TEXTURE_2D;
82 bool active = false;
83 };
84
85 // Map active uniform names to their locations.
86 void mapActiveUniforms();
87
88 void updateUniform(const UniformInfo *info, int count, bool internalupdate);
89 void sendTextures(const UniformInfo *info, Texture **textures, int count, bool internalupdate);
90
91 int getUniformTypeComponents(GLenum type) const;
92 MatrixSize getMatrixSize(GLenum type) const;
93 UniformType getUniformBaseType(GLenum type) const;
94 TextureType getUniformTextureType(GLenum type) const;
95 bool isDepthTextureType(GLenum type) const;
96
97 void flushStreamDraws() const;
98
99 // Get any warnings or errors generated only by the shader program object.
100 std::string getProgramWarnings() const;
101
102 // volatile
103 GLuint program;
104
105 // Location values for any built-in uniform variables.
106 GLint builtinUniforms[BUILTIN_MAX_ENUM];
107 UniformInfo *builtinUniformInfo[BUILTIN_MAX_ENUM];
108
109 // Location values for any generic vertex attribute variables.
110 GLint builtinAttributes[ATTRIB_MAX_ENUM];
111
112 std::map<std::string, GLint> attributes;
113
114 // Uniform location buffer map
115 std::map<std::string, UniformInfo> uniforms;
116
117 // Texture unit pool for setting images
118 std::vector<TextureUnit> textureUnits;
119
120 std::vector<std::pair<const UniformInfo *, int>> pendingUniformUpdates;
121
122 bool canvasWasActive;
123 Rect lastViewport;
124
125 float lastPointSize;
126
127 Matrix4 lastTransformMatrix;
128 Matrix4 lastProjectionMatrix;
129
130}; // Shader
131
132} // opengl
133} // graphics
134} // love
135