Beatmup
program.h
Go to the documentation of this file.
1 /*
2  Beatmup image and signal processing library
3  Copyright (C) 2019, lnstadrum
4 
5  This program is free software: you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation, either version 3 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18 
19 #pragma once
20 #include "../bitmap/abstract_bitmap.h"
21 #include "../utils/chunkfile.h"
22 #include "../basic_types.h"
23 #include "storage_buffer.h"
24 #include <map>
25 
26 #define BEATMUP_SHADER_CODE(...) #__VA_ARGS__
27 
28 namespace Beatmup {
29  namespace GL {
30  class Program;
31 
32  /** \page BeatmupGLSLDialect %Beatmup GLSL dialect
33  * %Beatmup tries to take advantage of OpenGL acceleration on a large spectrum of hardware, from low-end inexpensive GPUs to high-end ones.
34  * "Beatmup GLSL dialect" is a GLSL preprocessing feature and a texture binding logic that can be seen as a GLSL language variant. It enables
35  * the same shader running on a ES 2.0 and 3.2-conformant hardware as well as on a GPU compliant with a modern OpenGL.
36  * - In %Beatmup GLSL dialect the version header is inferred automatically to be one of ES 2.0, ES 3.2 or GLSL 1.30.
37  * - %Beatmup allows to feed to the the same shader to standard textures as well as to EGL external images enabling direct access to camera and
38  * video frames.
39  *
40  * %Beatmup GLSL dialect is limited to relatively simple shaders. Complex shaders written in a specific version of GLSL for a specific hardware
41  * can still be run with %Beatmup.
42  *
43  * %Beatmup GLSL dialect is enabled by passing a `BEATMUP_DIALECT` extension flag (see Beatmup::GL::Extensions) when constructing a shader.
44  * Following few rules apply to get a working shader program written in %Beatmup GLSL dialect.
45  * - Do not put any specific version on top of the GLSL code.
46  * - The shader code is expected to be ES 2.0-compliant:
47  * - Use `texture2D(..)` function to sample textures.
48  * - Use `gl_FragColor` variable as the fragment shader output.
49  * - Use `attribute` and `varying` qualifiers for shaders inputs and outputs.
50  * - Use `beatmupSampler` as sampler variable type for textures that can come from camera or video decoder.
51  * - If all the textures bound to the shader program are regular ones, the shader is processed as usual.
52  * - If some of textures bound to the shader program are EGL external images, all the `beatmupSampler` variables become EGL external image
53  * samplers (`samplerExternalOES`). The necessary extension is enabled implicitly and should not be put in the shader code.
54  * - Use `beatmupTexture(..)` function to sample a `beatmupSampler`. Its signature is identical to `texture2D(..)` function signature.
55  */
56 
57 
58  /**
59  Supported OpenGL estensions.
60  Used to communicate to a shader/program specific extensions used in the GLSL code.
61  This defines %Beatmup GLSL dialect interpretation.
62  */
63  enum Extensions {
64  NONE = 0, //!< no extension
65  BEATMUP_DIALECT = 1 << 0, //!< pseudo-extension enabling Beatmup GLSL dialect
66  EXTERNAL_TEXTURE = 1 << 1 //!< GL_OES_EGL_image_external_essl3 if available or GL_OES_EGL_image_external
67  };
68 
71 
72  /**
73  GLSL shader base class
74  */
75  class Shader {
76  friend class Program;
77  Shader(const Shader&) = delete; //!< disabling copying constructor
78  private:
80  uint32_t type;
81  protected:
82  Shader(const GraphicPipeline& gpu, const uint32_t type);
83  inline handle_t getHandle() const { return handle; }
84  inline uint32_t getType() const { return type; }
85  void compile(const GraphicPipeline& gpu, const char* source);
86  public:
87  ~Shader();
88  };
89 
90  /**
91  GLSL vertex shader
92  */
93  class VertexShader : public Shader {
94  public:
95  VertexShader(const GraphicPipeline& gpu);
96  VertexShader(const GraphicPipeline& gpu, const std::string& source, Extensions extensions = Extensions::NONE) : VertexShader(gpu)
97  {
98  compile(gpu, source.c_str(), extensions);
99  }
100 
101  void compile(const GraphicPipeline& gpu, const std::string& source, Extensions extensions = Extensions::NONE);
102  };
103 
104  /**
105  GLSL fragment shader
106  */
107  class FragmentShader : public Shader {
108  public:
109  static const char* DIALECT_SAMPLER_DECL_TYPE; //!< glsl type name to declare a texture in Beatmup dialect
110  static const char* DIALECT_TEXTURE_SAMPLING_FUNC; //!< glsl function name to sample a texture in Beatmup dialect
111 
112  FragmentShader(const GraphicPipeline& gpu);
113  FragmentShader(const GraphicPipeline& gpu, const std::string& source, Extensions extensions = Extensions::NONE) : FragmentShader(gpu)
114  {
115  compile(gpu, source.c_str(), extensions);
116  }
117 
118  void compile(const GraphicPipeline& gpu, const std::string& source, Extensions extensions = Extensions::NONE);
119  };
120 
122  friend class AbstractProgram;
123  private:
125  public:
126  AtomicCounter(const GraphicPipeline& gpu);
127  ~AtomicCounter();
128  void set(unsigned int value);
129  };
130 
131  /**
132  Basic GLSL program.
133  Shaders are controlled by the user.
134  */
136  private:
137  std::map<std::string, handle_t> uniformsCache, attribsCache;
139  AbstractProgram(const AbstractProgram&) = delete; //!< disabling copying constructor
140 
141  protected:
142  inline handle_t getHandle() const { return handle; }
143  void assertLinked() const;
144  void clearCaches();
145 
146  public:
147  AbstractProgram(const GraphicPipeline& gpu);
149  void enable(const GraphicPipeline& gpu);
150 
151 #ifndef BEATMUP_OPENGLVERSION_GLES20
152  Chunk* getBinary() const;
153  void loadBinary(const Chunk& binary);
154 #endif
155 
156  /**
157  Retrieves uniform variable location by its name.
158  May be slow.
159  \param[in] name The variable name
160  */
161  handle_t findUniformLocation(const char* name);
162 
163  /**
164  Retrieves attribute location by its name.
165  May be slow.
166  \param[in] name The attribute name
167  */
168  handle_t findAttribLocation(const char* name);
169 
170  /**
171  Retrieves uniform variable location by its name.
172  Uses chache. Faster when called more than once.
173  \param[in] name The variable name
174  */
175  handle_t getUniformLocation(const std::string& name);
176 
177 
178  /**
179  Retrieves attribute location by its name.
180  Uses chache. Faster when called more than once.
181  \param[in] name The attribute name
182  */
183  handle_t getAttribLocation(const std::string& name);
184 
185  /**
186  Assigns a value to a specific integer variable in the program.
187  \param name the variable name
188  \param value the value to assign
189  \param safe if `true` check if the target variable exists before assigning
190  */
191  void setInteger(const std::string& name, const int value, bool safe = false);
192  void setUnsignedInteger(const std::string& name, const unsigned int value, bool safe = false);
193 
194  /**
195  Assigns a value to a specific floating point variable in the program.
196  \param name the variable name
197  \param value the value to assign
198  \param safe if `true` check if the target variable exists before assigning
199  */
200  void setFloat(const std::string& name, const float value, bool safe = false);
201 
202  void setVector2(const std::string& name, const float x, const float y);
203  void setVector3(const std::string& name, const float x, const float y, const float z);
204  void setVector4(const std::string& name, const float x, const float y, const float z, const float w);
205  void setVector4(const std::string& name, const color4i& color, const float outRange = 1.0f);
206 
207  void setMatrix2(const std::string& name, const Matrix2& mat);
208  void setMatrix3(const std::string& name, const Matrix2& mat, const Point& pos);
209  void setMatrix3(const std::string& name, const AffineMapping& mapping);
210 
211  void setIntegerArray(const std::string& name, const int* values, const int length);
212  void setIntegerArray(const std::string& name, const int firstValue, const int length);
213 
214  void setFloatArray(const std::string& name, const float* values, const int length);
215  void setVec2Array(const std::string& name, const float* xy, const int length);
216  void setVec4Array(const std::string& name, const float* xyzw, const int length);
217 
218  void bindSampler(GraphicPipeline& gpu, GL::TextureHandler& image, const char* uniformId, TextureParam param);
219  void bindImage(GraphicPipeline& gpu, GL::TextureHandler& image, const char* uniformId, bool read, bool write);
220 
221 #ifndef BEATMUP_OPENGLVERSION_GLES20
222  void bindAtomicCounter(GraphicPipeline& gpu, AtomicCounter& counter, int unit);
223 #endif
224  };
225 
226  /**
227  Regular OpenGL program
228  */
229  class Program : public AbstractProgram {
230  public:
231  Program(const GraphicPipeline& gpu);
232  Program(const GraphicPipeline& gpu, const VertexShader&, const FragmentShader&);
233  void link(const VertexShader&, const FragmentShader&);
234  };
235 
236  /**
237  GLSL program to render images
238  Makes use of default vertex attributes to pass the texture coordinates and the image position to the GPU
239  */
240  class RenderingProgram : public Program {
241  public:
242  RenderingProgram(const GraphicPipeline& gpu, const FragmentShader&);
243  RenderingProgram(const GraphicPipeline& gpu, const VertexShader&, const FragmentShader&);
244  void link(const GraphicPipeline& gpu, const FragmentShader&);
245  void blend(bool onScreen);
246  void blend();
247  };
248  }
249 }
2x3 affine mapping containing a 2x2 matrix and a 2D point
Definition: geometry.h:639
Simply a piece of binary data of a specific size.
Definition: chunkfile.h:210
Basic GLSL program.
Definition: program.h:135
std::map< std::string, handle_t > uniformsCache
Definition: program.h:137
void setUnsignedInteger(const std::string &name, const unsigned int value, bool safe=false)
Definition: program.cpp:323
void setMatrix2(const std::string &name, const Matrix2 &mat)
Definition: program.cpp:392
handle_t getAttribLocation(const std::string &name)
Retrieves attribute location by its name.
Definition: program.cpp:298
void setVec2Array(const std::string &name, const float *xy, const int length)
Definition: program.cpp:458
handle_t getHandle() const
Definition: program.h:142
handle_t findUniformLocation(const char *name)
Retrieves uniform variable location by its name.
Definition: program.cpp:278
void bindSampler(GraphicPipeline &gpu, GL::TextureHandler &image, const char *uniformId, TextureParam param)
Definition: program.cpp:474
void bindAtomicCounter(GraphicPipeline &gpu, AtomicCounter &counter, int unit)
Definition: program.cpp:493
void setInteger(const std::string &name, const int value, bool safe=false)
Assigns a value to a specific integer variable in the program.
Definition: program.cpp:308
Chunk * getBinary() const
Definition: program.cpp:257
void enable(const GraphicPipeline &gpu)
Definition: program.cpp:250
void loadBinary(const Chunk &binary)
Definition: program.cpp:270
void setIntegerArray(const std::string &name, const int *values, const int length)
Definition: program.cpp:417
void setFloatArray(const std::string &name, const float *values, const int length)
Definition: program.cpp:450
void setVec4Array(const std::string &name, const float *xyzw, const int length)
Definition: program.cpp:466
handle_t getUniformLocation(const std::string &name)
Retrieves uniform variable location by its name.
Definition: program.cpp:288
void setVector3(const std::string &name, const float x, const float y, const float z)
Definition: program.cpp:370
void setFloat(const std::string &name, const float value, bool safe=false)
Assigns a value to a specific floating point variable in the program.
Definition: program.cpp:347
void setVector4(const std::string &name, const float x, const float y, const float z, const float w)
Definition: program.cpp:378
std::map< std::string, handle_t > attribsCache
Definition: program.h:137
handle_t findAttribLocation(const char *name)
Retrieves attribute location by its name.
Definition: program.cpp:283
void bindImage(GraphicPipeline &gpu, GL::TextureHandler &image, const char *uniformId, bool read, bool write)
Definition: program.cpp:483
AbstractProgram(const AbstractProgram &)=delete
disabling copying constructor
void setMatrix3(const std::string &name, const Matrix2 &mat, const Point &pos)
Definition: program.cpp:402
void setVector2(const std::string &name, const float x, const float y)
Definition: program.cpp:362
void set(unsigned int value)
Definition: program.cpp:204
AtomicCounter(const GraphicPipeline &gpu)
Definition: program.cpp:191
GLSL fragment shader.
Definition: program.h:107
static const char * DIALECT_SAMPLER_DECL_TYPE
glsl type name to declare a texture in Beatmup dialect
Definition: program.h:109
FragmentShader(const GraphicPipeline &gpu)
Definition: program.cpp:118
static const char * DIALECT_TEXTURE_SAMPLING_FUNC
glsl function name to sample a texture in Beatmup dialect
Definition: program.h:110
void compile(const GraphicPipeline &gpu, const std::string &source, Extensions extensions=Extensions::NONE)
Definition: program.cpp:121
FragmentShader(const GraphicPipeline &gpu, const std::string &source, Extensions extensions=Extensions::NONE)
Definition: program.h:113
Regular OpenGL program.
Definition: program.h:229
Program(const GraphicPipeline &gpu)
Definition: program.cpp:500
void link(const VertexShader &, const FragmentShader &)
Definition: program.cpp:510
A wrapper for a GPU resource.
Definition: recycle_bin.h:39
GLSL program to render images Makes use of default vertex attributes to pass the texture coordinates ...
Definition: program.h:240
void link(const GraphicPipeline &gpu, const FragmentShader &)
Definition: program.cpp:543
RenderingProgram(const GraphicPipeline &gpu, const FragmentShader &)
Definition: program.cpp:522
GLSL shader base class.
Definition: program.h:75
uint32_t type
Definition: program.h:80
handle_t getHandle() const
Definition: program.h:83
Shader(const Shader &)=delete
disabling copying constructor
handle_t handle
Definition: program.h:79
void compile(const GraphicPipeline &gpu, const char *source)
Definition: program.cpp:50
uint32_t getType() const
Definition: program.h:84
GLSL vertex shader.
Definition: program.h:93
VertexShader(const GraphicPipeline &gpu, const std::string &source, Extensions extensions=Extensions::NONE)
Definition: program.h:96
VertexShader(const GraphicPipeline &gpu)
Definition: program.cpp:75
void compile(const GraphicPipeline &gpu, const std::string &source, Extensions extensions=Extensions::NONE)
Definition: program.cpp:78
Internal low-level GPU control API.
Definition: pipeline.h:33
void write(Bitmap &bitmap, Args &&... args)
Calls a Func< WriterClass >::process(access, params) that writes to a bitmap of any kind,...
Definition: processing.h:90
void read(Bitmap &bitmap, Args &&... args)
Calls a Func< ReaderClass >::process(access, params), where.
Definition: processing.h:49
Extensions operator-=(Extensions &set, Extensions entry)
Definition: program.cpp:30
unsigned int handle_t
A reference to a GPU resource.
Definition: basic_types.h:61
Extensions
Supported OpenGL estensions.
Definition: program.h:63
@ NONE
no extension
Definition: program.h:64
@ BEATMUP_DIALECT
pseudo-extension enabling Beatmup GLSL dialect
Definition: program.h:65
@ EXTERNAL_TEXTURE
GL_OES_EGL_image_external_essl3 if available or GL_OES_EGL_image_external.
Definition: program.h:66
Extensions operator+(Extensions lhs, Extensions rhs)
Definition: program.cpp:35
TextureParam
Parameters of binding a texture to a texture unit on GPU.
return(jlong) new Beatmup jlong jstring name
jlong jstring jint jint jint z
jobject jlong jint jint y
jlong jstring jint jint jint jint w
jobject jlong jint x
jlong jintArray xy
* mat
Beatmup::AffineMapping & mapping