Beatmup
image_shader.cpp
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 #include "image_shader.h"
20 #include "../gpu/program.h"
21 #include "../gpu/bgl.h"
22 #include "../debug.h"
23 
24 
25 using namespace Beatmup;
26 
27 
28 const std::string
32  "uniform " + INPUT_IMAGE_DECL_TYPE + " " + INPUT_IMAGE_ID +";\n" +
34 
35 
36 bool str_replace(std::string& str, const std::string& from, const std::string& to) {
37  size_t start_pos = str.find(from);
38  if (start_pos == std::string::npos)
39  return false;
40  str.replace(start_pos, from.length(), to);
41  return true;
42 }
43 
44 
45 static AffineMapping getOutputCropMapping(const ImageResolution& out, const IntRectangle& outputClipRect) {
47  (float)outputClipRect.getX1() / out.getWidth(),
48  (float)outputClipRect.getY1() / out.getHeight(),
49  (float)outputClipRect.getX2() / out.getWidth(),
50  (float)outputClipRect.getY2() / out.getHeight()
51  )).getInverse();
52 }
53 
54 
56  recycleBin(recycleBin),
57  program(nullptr),
58  upToDate(false),
59  inputFormat(GL::TextureHandler::TextureFormat::RGBx8)
60 {}
61 
62 
65 {}
66 
67 
70 }
71 
72 
73 void ImageShader::setSourceCode(const std::string& sourceCode) {
74  lock();
75  this->sourceCode = sourceCode;
76  upToDate = false;
77  unlock();
78 }
79 
80 
82  this->outputClipRect = rectangle;
83 }
84 
85 
87  LockGuard lock(this);
88  if (sourceCode.empty())
89  throw NoSource();
90 
91  // check if the input format changes
92  if (input && input->getTextureFormat() != inputFormat)
93  upToDate = false;
94 
95 
96  // make program ready if not yet or if not up to date
97  if (!program || !upToDate) {
98  inputFormat = input ? input->getTextureFormat() : GL::TextureHandler::TextureFormat::RGBx8;
99 
100  // link program
101  GL::Extensions textureExtension = inputFormat == GL::TextureHandler::TextureFormat::OES_Ext ? GL::Extensions::EXTERNAL_TEXTURE : GL::Extensions::NONE;
102  GL::FragmentShader fragmentShader(gpu, sourceCode, GL::Extensions::BEATMUP_DIALECT + textureExtension);
103  if (!program) {
104  program = new GL::RenderingProgram(gpu, fragmentShader);
105  }
106  else {
107  program->link(gpu, fragmentShader);
108  }
109 
110  upToDate = true;
111  }
112 
113  // enable program
114  program->enable(gpu);
115  if (input)
118 
119  // bind output
120  if (output) {
121  if (!outputClipRect.empty())
122  gpu.bindOutput(*output, outputClipRect);
123  else
124  gpu.bindOutput(*output);
125  }
126 
127  // bind input
128  if (input)
129  gpu.bind(*input, 0, texParam);
130  // Binding order matters: texture unit 0 is used for input now.
131 
134  !output || outputClipRect.empty() ? mapping :
136  );
137 
138  // apply bundle
139  apply(*program);
140 }
141 
142 
145 }
146 
147 
149  LockGuard lock(this);
150  if (sourceCode.empty())
151  throw NoSource();
152 
153  // link program if not yet
154  if (!program || !upToDate) {
155  // link program
157  if (!program) {
158  program = new GL::RenderingProgram(gpu, fragmentShader);
159  }
160  else {
161  program->link(gpu, fragmentShader);
162  }
163 
164  upToDate = true;
165  }
166 
167  // enable program
168  program->enable(gpu);
169 
170  // bind output
171  if (output) {
172  if (!outputClipRect.empty())
173  gpu.bindOutput(*output, outputClipRect);
174  else
175  gpu.bindOutput(*output);
176  }
177 
178  // set up mapping
183  );
184 
185  // apply bundle
186  apply(*program);
187 }
188 
189 
190 void ImageShader::bindSamplerArray(const char* uniformId, int startingUnit, int numUnits) {
191  program->setIntegerArray(uniformId, startingUnit, numUnits);
192 }
193 
194 
196  program->blend();
197 }
A very basic class for any image.
const ImageResolution getSize() const
Returns the bitmap resolution within ImageResolution object.
2x3 affine mapping containing a 2x2 matrix and a 2D point
Definition: geometry.h:639
AffineMapping getInverse() const
Returns inverse mapping.
Definition: geometry.cpp:52
static const AffineMapping IDENTITY
Definition: geometry.h:717
Basic class: task and memory management, any kind of static data.
Definition: context.h:59
bool empty() const
Definition: geometry.h:149
numeric getX2() const
Definition: geometry.h:171
numeric getY2() const
Definition: geometry.h:172
numeric getX1() const
Definition: geometry.h:169
static const CustomRectangle UNIT_SQUARE
Definition: geometry.h:322
numeric getY1() const
Definition: geometry.h:170
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
void enable(const GraphicPipeline &gpu)
Definition: program.cpp:250
void setIntegerArray(const std::string &name, const int *values, const int length)
Definition: program.cpp:417
void setMatrix3(const std::string &name, const Matrix2 &mat, const Point &pos)
Definition: program.cpp:402
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
Stores references to GPU resources that will not be used anymore and needed to be recycled in a threa...
Definition: recycle_bin.h:34
void put(Item *item)
Puts an item into the recycle bin.
Definition: recycle_bin.cpp:73
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
void blend(bool onScreen)
Definition: program.cpp:548
static const char * DECLARE_TEXTURE_COORDINATES_IN_FRAG
Declaring texture coordinates in fragment shader.
static const char * MODELVIEW_MATRIX_ID
Modelview matrix (mapping input geometry to output) shader variable name in vertex shader.
virtual const TextureFormat getTextureFormat() const =0
Returns the texture format specifying how the shader must interpret the data.
void apply(Program &program)
Internal low-level GPU control API.
Definition: pipeline.h:33
const ImageResolution & getDisplayResolution() const
Definition: pipeline.cpp:916
void bindOutput(AbstractBitmap &bitmap)
Binds a bitmap to the pipeline output.
Definition: pipeline.cpp:891
void setTextureCoordinates(const Rectangle &coords)
Specifies texture coordinates for the next rendering pass.
Definition: pipeline.cpp:966
void bind(GL::TextureHandler &texture, size_t texUnit, const TextureParam param)
Definition: pipeline.cpp:881
Represents image size in pixels.
Expection thrown if no shader source is provided.
Definition: image_shader.h:119
A GLSL program to process images.
Definition: image_shader.h:34
void process(GraphicPipeline &gpu)
Apply the shader to produce an image.
bool upToDate
if true, the program is up-to-date with respect to the source code
Definition: image_shader.h:40
void setOutputClipping(const IntRectangle &rectangle)
Sets output clipping area.
void prepare(GraphicPipeline &gpu, GL::TextureHandler *input, const TextureParam texParam, AbstractBitmap *output, const AffineMapping &mapping)
Conducts required preparations for blending.
static const std::string CODE_HEADER
Shader code header containing necessary declarations.
Definition: image_shader.h:114
GL::TextureHandler::TextureFormat inputFormat
last used input texture format; when changed, the shader is recompiled
Definition: image_shader.h:41
void setSourceCode(const std::string &sourceCode)
Passes new source code to the fragment shader.
GL::RecycleBin & recycleBin
Definition: image_shader.h:37
std::string sourceCode
last passed fragment shader source code
Definition: image_shader.h:39
IntRectangle outputClipRect
output clip rectangle: only this specified area of the output image will be changed
Definition: image_shader.h:42
GL::RenderingProgram * program
Definition: image_shader.h:38
static const std::string INPUT_IMAGE_DECL_TYPE
A virtual input image type defined at shader compile time by ordinary texture or OES texture sampler ...
Definition: image_shader.h:104
ImageShader(const ImageShader &)=delete
disabling copying constructor
void bindSamplerArray(const char *uniformId, int startingUnit, int numUnits)
Binds a bunch of texture units to a uniform sampler array variable.
static const std::string INPUT_IMAGE_ID
Shader variable name referring to the input image.
Definition: image_shader.h:109
static AffineMapping getOutputCropMapping(const ImageResolution &out, const IntRectangle &outputClipRect)
bool str_replace(std::string &str, const std::string &from, const std::string &to)
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
TextureParam
Parameters of binding a texture to a texture unit on GPU.
@ INTERP_LINEAR
bilinear pixel interpolation
ctx getGpuRecycleBin() -> emptyBin()
Beatmup::Context * ctx
JNIEnv jlong jint out
Beatmup::AffineMapping & mapping
JNIEnv jobject jstring str