8 #include "SimpleMultiPassFragmentShader.hh"
13 SimpleMultiPassFragmentShader::SimpleMultiPassFragmentShader()
16 createdGLContext_ =
false;
20 SimpleMultiPassFragmentShader::Init(
bool createGLContext)
40 createdGLContext_ =
true;
44 createdGLContext_ =
false;
47 framebuffer_setup_pool_.Create(texture_pool_);
51 InitVertexTransformation_();
57 SimpleMultiPassFragmentShader::Destroy()
59 shader_pool_.ClearAll();
60 framebuffer_setup_pool_.ClearAll();
61 texture_pool_.ClearAll();
62 input_textures_.clear();
64 if (createdGLContext_)
70 createdGLContext_ =
false;
81 SimpleMultiPassFragmentShader::AddFragmentShaderFromFile(
82 const string& shader_path,
const string& shader_name)
88 shader_pool_.AddShaderProgram(shader_name);
89 shader_pool_.AddFragmentShaderFromFile(shader_path, shader_name,
92 shader_pool_.LinkAll();
94 BIASERR(
"error adding shader : "<<shader_name<<
" from file : "<<shader_path<<endl);
100 GLF_THROW_EXCEPTION(
"call Init first !" << endl);
105 SimpleMultiPassFragmentShader::AddFragmentShader(
const string& shader_source,
106 const string& shader_name)
111 shader_pool_.AddShaderProgram(shader_name);
112 shader_pool_.AddFragmentShader(shader_source, shader_name, shader_name);
113 shader_pool_.LinkAll();
117 GLF_THROW_EXCEPTION(
"call Init first !" << endl);
121 template<
class StorageType>
123 SimpleMultiPassFragmentShader::SetShaderVariable(
const string& shader_name,
124 const string& var_name, StorageType value)
126 string type = shader_pool_.GetUniformType(shader_name, var_name);
127 if (type.compare(
"sampler2D") == 0)
129 GLF_THROW_EXCEPTION(
"variable with name " << var_name <<
" is a texture (sampler2D), use SetOutputTextures / SetInputTextures to set textures " << endl);
133 shader_pool_.SetUniform(shader_name, var_name, value);
138 SimpleMultiPassFragmentShader::LoadTexture(
const ImageBase& image,
139 const string& texture_name, GLenum minFilter, GLenum magFilter,
140 GLenum wrapS, GLenum wrapT, GLenum internalFormat,
int mipmap)
144 texture_pool_.UploadImage(texture_name, image, minFilter, magFilter,
145 wrapS, wrapT, internalFormat, mipmap);
149 GLF_THROW_EXCEPTION(
"call Init first !" << endl);
154 SimpleMultiPassFragmentShader::CreateTexture(
int width,
int height,
155 GLenum internalFormat,
const std::string& texture_name,
156 GLenum minFilter, GLenum magFilter,
157 GLenum wrapS, GLenum wrapT,
int mipmap)
161 texture_pool_.Create(texture_name, width, height, internalFormat,
162 minFilter, magFilter, wrapS, wrapT, mipmap);
166 GLF_THROW_EXCEPTION(
"call Init first !" << endl);
171 SimpleMultiPassFragmentShader::CreateTexture(
int width,
int height,
173 const string& texture_name, GLenum minFilter, GLenum magFilter,
174 GLenum wrapS, GLenum wrapT,
int mipmap)
178 texture_pool_.Create(texture_name, width, height, storageType,
179 colorModel, minFilter, magFilter, wrapS, wrapT, mipmap);
183 GLF_THROW_EXCEPTION(
"call Init first !" << endl);
188 SimpleMultiPassFragmentShader::SetInputTextures(
const string& shader_name,
189 const vector<string>& samplers2D,
const vector<string>& texture_names)
192 BIASASSERT(samplers2D.size() == texture_names.size());
195 shader_pool_.LinkAll();
198 if (programP == NULL)
200 GLF_THROW_EXCEPTION(
"no shader with name: " << shader_name
201 <<
" exists." << endl);
205 vector<pair<glfTexture*, pair<string, string> > > textures(
207 for (
unsigned int i = 0; i < samplers2D.size(); i++)
209 glfTexture2D* textureP = texture_pool_[texture_names[i]];
210 if (textureP == NULL)
212 GLF_THROW_EXCEPTION(
"no texture with name: " << texture_names[i]
213 <<
" exists." << endl);
217 textures[i] = make_pair(textureP, make_pair(samplers2D[i],
221 SetInputTextures_(shader_name, textures);
226 BIASERR(
"call Init first !" << endl);
232 SimpleMultiPassFragmentShader::SetInputTextures(
const std::string& shaderName,
const std::string& uniformVarName,
233 const std::string& texturePoolName)
237 shader_pool_.LinkAll();
240 if (programP == NULL)
242 GLF_THROW_EXCEPTION(
"no shader with name: " << shaderName
243 <<
" exists." << endl);
247 vector<pair<glfTexture*, pair<string, string> > > textures(1);
249 glfTexture2D* textureP = texture_pool_[texturePoolName];
250 if (textureP == NULL)
252 GLF_THROW_EXCEPTION(
"no texture with name: " << texturePoolName
253 <<
" exists." << endl);
257 textures[0] = make_pair(textureP, make_pair(uniformVarName, texturePoolName));
260 SetInputTextures_(shaderName, textures);
265 BIASERR(
"call Init first !" << endl);
270 vector<pair<glfTexture*, pair<string, string> > >*
271 SimpleMultiPassFragmentShader::GetInputTextures_(
const string& shader_name)
273 map<string, vector<pair<glfTexture*, pair<string, string> > > >::iterator
274 iter = input_textures_.find(shader_name);
275 if (iter != input_textures_.end())
277 return &(iter->second);
286 SimpleMultiPassFragmentShader::ActivateInputTextures_(
287 const string& shader_name,
288 vector<pair<
glfTexture*, pair<string, string> > >& textures)
290 for (
int i = 0; i < (int) textures.size(); i++)
292 glActiveTexture(GL_TEXTURE0+i);
293 textures[i].first->Bind();
294 shader_pool_.SetUniform(shader_name, (textures[i].second).first, i);
299 SimpleMultiPassFragmentShader::SetInputTextures_(
const string& shader_name,
300 vector<pair<
glfTexture*, pair<string, string> > >& textures)
302 map<string, vector<pair<glfTexture*, pair<string, string> > > >::iterator
303 iter = input_textures_.find(shader_name);
304 if (iter != input_textures_.end())
306 iter->second = textures;
310 input_textures_[shader_name] = textures;
315 SimpleMultiPassFragmentShader::SetOutputTexture(
const string& shader_name,
316 const string& colorTextureName,
const string& depthTextureName)
326 GLF_THROW_EXCEPTION(
"no shader with name: " << shader_name
327 <<
" exists." << endl);
334 glfTexture2D* texture = texture_pool_[colorTextureName];
336 GLF_THROW_EXCEPTION(
"cannot attach unexistant texture with name" <<colorTextureName<< endl);
340 if(depthTextureName.size()>0) {
341 texture = texture_pool_[depthTextureName];
343 GLF_THROW_EXCEPTION(
"cannot attach unexistant texture with name" <<depthTextureName<< endl);
352 BIASERR(
"call Init first !" << endl);
358 SimpleMultiPassFragmentShader::SetOutputTextures(
const string& shader_name,
359 const vector<string>& texture_names,
const string& depthTextureName)
369 GLF_THROW_EXCEPTION(
"no shader with name: " << shader_name
370 <<
" exists." << endl);
376 framebuffer_setup_pool_.SetColorAttachments(shader_name, texture_names);
377 if(depthTextureName.size()>0) {
378 glfTexture2D* texture = texture_pool_[depthTextureName];
380 GLF_THROW_EXCEPTION(
"cannot attach unexistant texture with name" <<depthTextureName<< endl);
389 BIASERR(
"call Init first !" << endl);
395 SimpleMultiPassFragmentShader::CopyToImage(
const string& texture_name,
399 if (textureP == NULL)
401 GLF_THROW_EXCEPTION(
"no texture with name: " << texture_name <<
" exists !" << endl);
410 SimpleMultiPassFragmentShader::CopyChannelsToImage(
const string& texture_name,
415 if (textureP == NULL)
417 GLF_THROW_EXCEPTION(
"no texture with name: " << texture_name <<
" exists !" << endl);
425 SimpleMultiPassFragmentShader::ActionGuard::ActionGuard() : action_(NULL)
428 SimpleMultiPassFragmentShader::ActionGuard::~ActionGuard()
436 this->operator = (action);
445 action_ = action->
Clone();
451 SimpleMultiPassFragmentShader::ActionGuard::Execute(
const unsigned int& currentIter,
const unsigned int& numIter)
454 BIASERR(
"fatal implementation error!");
457 action_->Execute(currentIter, numIter);
461 SimpleMultiPassFragmentShader::ActionGuard::Reset()
464 BIASERR(
"fatal implementation error!");
470 SimpleMultiPassFragmentShader::ActionGuard::ActionGuard(
const SimpleMultiPassFragmentShader::ActionGuard& a)
473 this->operator = (a.action_);
476 SimpleMultiPassFragmentShader::ActionGuard&
477 SimpleMultiPassFragmentShader::ActionGuard::operator=(
const SimpleMultiPassFragmentShader::ActionGuard& a)
479 this->operator = (a.action_);
486 postActions_[shaderName] = &postAction;
492 if(postActions_.find(shaderName)!=postActions_.end())
493 postActions_[shaderName].Reset();
501 map<std::string, ActionGuard>::iterator it = postActions_.find(shaderName);
502 if(it!=postActions_.end()) {
503 postActions_.erase(it);
509 unsigned int iter_number)
516 for (
unsigned int num = 0; num < iter_number; num++)
518 for (
unsigned int i = 0; i < shader_names.size(); i++)
524 if (programP == NULL)
526 GLF_THROW_EXCEPTION(
"no program"<< shader_names[i] <<
" exists !" << endl);
531 GLF_THROW_ON_OPENGL_ERROR;
532 vector<pair<glfTexture*, pair<string, string> > >* input_texturesP =
533 GetInputTextures_(shader_names[i]);
535 if (input_texturesP != NULL)
537 ActivateInputTextures_(shader_names[i], *input_texturesP);
538 for (
unsigned int j = 0; j < input_texturesP->size(); j++)
540 batch_.
SetTexture(((*input_texturesP)[j]).first, j);
549 GLF_THROW_EXCEPTION(
"no output textures for shader "<< shader_names[i] <<
" specified" << endl);
553 if (textureP == NULL)
555 GLF_THROW_EXCEPTION(
"no output textures for shader "<< shader_names[i] <<
" specified" << endl);
559 framebuffer_setup_pool_.
Activate(shader_names[i]);
565 ActivateDepthTest_(shader_names[i]);
570 map<string, ActionGuard>::iterator postAction = postActions_.find(shader_names[i]);
571 if(postAction != postActions_.end()) {
572 postAction->second.Execute(num, iter_number);
580 float red,
float green,
float blue,
float alpha)
584 if (setupP == NULL) {
585 GLF_THROW_EXCEPTION(
"no output textures for shader "<< setupP <<
" spezified" << endl);
596 if (setupP == NULL) {
597 GLF_THROW_EXCEPTION(
"no output textures for shader "<< setupP <<
" spezified" << endl);
608 if (setupP == NULL) {
609 GLF_THROW_EXCEPTION(
"no output textures for shader "<< setupP <<
" spezified" << endl);
620 if (setupP == NULL) {
621 GLF_THROW_EXCEPTION(
"no output textures for shader "<< setupP <<
" spezified" << endl);
629 depthTest_[shaderName].SetDepthTest(enabled);
630 depthTest_[shaderName].SetDepthFunc(depthFunc);
634 SimpleMultiPassFragmentShader::ActivateDepthTest_(
const std::string& shaderName)
636 map<string, glfDepthBufferMode>::const_iterator it = depthTest_.find(shaderName);
637 if(it!=depthTest_.end()) {
647 const unsigned int referenceHeight,
648 const std::vector<unsigned int>& posX,
649 const std::vector<unsigned int>& posY,
650 const unsigned int hw)
654 vertices_, elements_,
false);
659 const unsigned int referenceHeight,
660 const unsigned int posY,
661 const unsigned int hw)
665 vertices_, elements_,
false);
682 template BIASOpenGLFramework_EXPORT
void
683 SimpleMultiPassFragmentShader::SetShaderVariable<int>(
684 const string& shader_program_name,
const string& varName,
int value);
685 template BIASOpenGLFramework_EXPORT
void
686 SimpleMultiPassFragmentShader::SetShaderVariable<bool>(
687 const string& shader_program_name,
const string& varName,
bool value);
688 template BIASOpenGLFramework_EXPORT
void
689 SimpleMultiPassFragmentShader::SetShaderVariable<float>(
690 const string& shader_program_name,
const string& varName,
float value);
691 template BIASOpenGLFramework_EXPORT
void
692 SimpleMultiPassFragmentShader::SetShaderVariable<double>(
693 const string& shader_program_name,
const string& varName,
double value);
694 template BIASOpenGLFramework_EXPORT
void
695 SimpleMultiPassFragmentShader::SetShaderVariable<Vector<float> >(
696 const string& shader_program_name,
const string& varName,
EColorModel
These are the most often used color models.
void ResetPostAction(const std::string &shaderName)
void DisableDepthClearance(const std::string &shaderName)
Disables the clearence of the output when rendered into.
int GetWidth(int mipmap=0) const
Returns the width of a mipmap of the texture.
void ClearColorAttachments()
void SetDepthBufferMode(const glfDepthBufferMode *depthBufferMode)
Sets the depth buffer mode.
void Draw()
Draws the batch.
Class allows to add actions different then rendering to the multipass shader execution.
void SetDepthAttachment(BIAS::glfTexture *texture)
static void AddRelativeQuadPatchOverImageLine(const unsigned int referenceWidth, const unsigned int referenceHeight, const unsigned int linePos, const unsigned int hw, BIAS::glfVertexBuffer &vb, BIAS::glfElementBuffer &eb, const bool flip)
Adds a patch suited for rendering with identity rendering parameters that exactly fits over an image ...
void CopyToImage(ImageBase &image, int mipmap=0)
Copies the pixels of a mipmap of the texture to a BIAS::ImageBase.
Exception class used for run-time errors in the OpenGLFramework.
A shader program composed of several shaders.
void ClearPostAction(const std::string &shaderName)
static const glfDepthBufferMode DEFAULT
The default depth buffer mode.
void DisableColorClearance()
FramebufferSetup * GetSetup(const std::string &setupName)
Returns the pointer to a texture attached during a setup.
int GetHeight(int mipmap=0) const
Returns the height of a mipmap of the texture.
void Activate(const std::string &setupName)
void EnableColorClearance(float red=0.0f, float green=0.0f, float blue=0.0f, float alpha=0.0f)
void SetTexture(const glfTexture *texture, int textureUnit)
Sets the texture of a texture unit.
void DisableColorClearance(const std::string &shaderName)
Disables the clearence of the output when rendered into.
void SetRenderTarget(const glfRenderTarget *renderTarget)
Sets the render target.
void EvaluateOnlyLine(const unsigned int referenceWidth, const unsigned int referenceHeight, const unsigned int posY, const unsigned int hw)
Instead of processing a whole image, the fragment shaders are run only on a region around an image li...
void DisableDepthClearance()
void SetShaderProgram(const glfShaderProgram *shaderProgram)
Sets the shader program.
void SetColorAttachment(BIAS::glfTexture *texture, int AttachmentPoint=0)
glfFramebufferObject * GetFBO()
void SetSize(int width, int height)
Sets the size of the viewport in pixel coordinates.
void EvaluateOnlyPatches(const unsigned int referenceWidth, const unsigned int referenceHeight, const std::vector< unsigned int > &posX, const std::vector< unsigned int > &posY, const unsigned int hw)
Instead ogf processing a whole image, the fragment shaders are run only on a set of symmetric patches...
void SetPostAction(const std::string &shaderName, const SMPFSActionInterface &postAction)
Sets an action that is performed after the respective shader has run.
void EnableDepthClearance(const std::string &shaderName, float depth=1.0f)
Enables the clearence of the output, each time when rendered into.
static void AddRelativeQuadPatches(const unsigned int referenceWidth, const unsigned int referenceHeight, const std::vector< unsigned int > &posX, const std::vector< unsigned int > &posY, const unsigned int hw, BIAS::glfVertexBuffer &vb, BIAS::glfElementBuffer &eb, const bool flip)
Calculates 2D patches in the image plane suited for rendering with identity rendering parameters...
void EnableColorClearance(const std::string &shaderName, float red=0.0f, float green=0.0f, float blue=0.0f, float alpha=0.0f)
Enables the clearence of the output, each time when rendered into.
void Execute(const std::vector< std::string > &shader_names, unsigned int iter_number=1)
executes all shaders with names in shader_names vector in the given order (iter_number)-times ...
virtual SMPFSActionInterface * Clone() const =0
void SetDepthTest(const std::string &shaderName, const bool enabled, GLenum depthFunc)
Sets the depth test for the particular shader execution.
This is the base class for images in BIAS.
Configuration for a rendering context.
glfShaderProgram * GetShaderProgram(const std::string &shader_program_name)
returns the pointer to the shader program with the name shader_program_name if a program with this na...
void CopyChannelsToImage(ImageBase &image, GLenum format, int mipmap=0)
Copies the pixels of a mipmap of the texture to a BIAS::ImageBase and interprets the texture using th...
void EnableDepthClearance(float depth=1.0f)
glfTexture2D * GetColorAttachment2D(int AttachmentPoint)
Returns texture attached to AttachmentPoint if it is a glfTexture2D otherwise NULL.