29#include <SFML/Graphics/PostFX.hpp>
30#include <SFML/Graphics/RenderWindow.hpp>
31#include <SFML/Graphics/GraphicsContext.hpp>
57myTextures (Copy.myTextures),
58myFragmentShader(Copy.myFragmentShader),
59myFrameBuffer (Copy.myFrameBuffer)
65 if (Copy.myShaderProgram)
79 priv::GraphicsContext
Ctx;
95 std::cerr <<
"Failed to open effect file \"" <<
Filename <<
"\"" << std::endl;
100 myFragmentShader = PreprocessEffect(
File);
105 return myShaderProgram != 0;
118 myFragmentShader = PreprocessEffect(
Stream);
123 return myShaderProgram != 0;
142 std::cerr <<
"Parameter \"" <<
Name <<
"\" not found in post-effect" << std::endl;
165 std::cerr <<
"Parameter \"" <<
Name <<
"\" not found in post-effect" << std::endl;
188 std::cerr <<
"Parameter \"" <<
Name <<
"\" not found in post-effect" << std::endl;
211 std::cerr <<
"Parameter \"" <<
Name <<
"\" not found in post-effect" << std::endl;
227 if (myTextures.size() >=
static_cast<std::size_t
>(
MaxUnits))
229 std::cerr <<
"Impossible to use texture \"" <<
Name <<
"\" for post-effect : all available texture units are used" << std::endl;
237 std::cerr <<
"Texture \"" <<
Name <<
"\" not found in post-effect" << std::endl;
253 std::swap(myShaderProgram,
Temp.myShaderProgram);
254 std::swap(myTextures,
Temp.myTextures);
255 std::swap(myFragmentShader,
Temp.myFragmentShader);
256 std::swap(myFrameBuffer,
Temp.myFrameBuffer);
268 priv::GraphicsContext
Ctx;
283 if (!myShaderProgram)
294 TextureTable::const_iterator
ItTex = myTextures.begin();
295 for (std::size_t
i = 0;
i < myTextures.size(); ++
i)
300 ItTex->second->Bind();
321 for (std::size_t
i = 0;
i < myTextures.size(); ++
i)
334std::string PostFX::PreprocessEffect(std::istream&
File)
337 std::set<std::string> myTextures;
338 std::string
Out =
"";
342 while (std::getline(
File, Line) && (Line.substr(0, 6) !=
"effect"))
345 if (!Line.empty() && (Line[Line.size() - 1] ==
'\r'))
346 Line.erase(Line.size() - 1);
353 std::string Type,
Name;
354 std::istringstream
iss(Line);
357 std::cerr <<
"Post-effect error : invalid declaration (should be \"[type][name]\")" << std::endl
358 <<
"> " << Line << std::endl;
362 if (Type ==
"texture")
365 if (myTextures.find(Name) != myTextures.end())
367 std::cerr <<
"Post-effect error : texture \"" << Name <<
"\" already exists" << std::endl;
371 Out +=
"uniform sampler2D " + Name +
";\n";
372 myTextures.insert(Name);
377 Out +=
"uniform " + Type +
" " + Name +
";\n";
382 Out +=
"void main()\n";
383 while (std::getline(File, Line))
386 for (std::set<std::string>::const_iterator i = myTextures.begin(); i != myTextures.end(); ++i)
388 std::string::size_type Pos = Line.find(*i);
389 if (Pos != std::string::npos)
390 Line.replace(Pos, i->size() + 1,
"texture2D(" + *i +
", ");
394 for (std::string::size_type Pos = Line.find(
"_in"); Pos != std::string::npos; Pos = Line.find(
"_in"))
395 Line.replace(Pos, 3,
"gl_TexCoord[0].xy");
398 for (std::string::size_type Pos = Line.find(
"_out"); Pos != std::string::npos; Pos = Line.find(
"_out"))
399 Line.replace(Pos, 4,
"gl_FragColor");
412void PostFX::CreateProgram()
415 priv::GraphicsContext Ctx;
420 std::cerr <<
"Failed to create a PostFX : your system doesn't support effects" << std::endl;
426 GLCheck(glDeleteObjectARB(myShaderProgram));
429 static const std::string VertexShaderSrc =
432 " gl_TexCoord[0] = gl_MultiTexCoord0;"
433 " gl_Position = ftransform();"
437 myShaderProgram = glCreateProgramObjectARB();
440 GLhandleARB VertexShader = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
441 GLhandleARB FragmentShader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
444 const char* VertexSrc = VertexShaderSrc.c_str();
445 const char* FragmentSrc = myFragmentShader.c_str();
446 GLCheck(glShaderSourceARB(VertexShader, 1, &VertexSrc, NULL));
447 GLCheck(glShaderSourceARB(FragmentShader, 1, &FragmentSrc, NULL));
448 GLCheck(glCompileShaderARB(VertexShader));
449 GLCheck(glCompileShaderARB(FragmentShader));
453 GLCheck(glGetObjectParameterivARB(VertexShader, GL_OBJECT_COMPILE_STATUS_ARB, &Success));
454 if (Success == GL_FALSE)
456 char CompileLog[1024];
457 GLCheck(glGetInfoLogARB(VertexShader,
sizeof(CompileLog), 0, CompileLog));
458 std::cerr <<
"Failed to compile post-effect :" << std::endl
459 << CompileLog << std::endl;
460 GLCheck(glDeleteObjectARB(VertexShader));
461 GLCheck(glDeleteObjectARB(FragmentShader));
462 GLCheck(glDeleteObjectARB(myShaderProgram));
466 GLCheck(glGetObjectParameterivARB(FragmentShader, GL_OBJECT_COMPILE_STATUS_ARB, &Success));
467 if (Success == GL_FALSE)
469 char CompileLog[1024];
470 GLCheck(glGetInfoLogARB(FragmentShader,
sizeof(CompileLog), 0, CompileLog));
471 std::cerr <<
"Failed to compile post-effect :" << std::endl
472 << CompileLog << std::endl;
473 GLCheck(glDeleteObjectARB(VertexShader));
474 GLCheck(glDeleteObjectARB(FragmentShader));
475 GLCheck(glDeleteObjectARB(myShaderProgram));
481 GLCheck(glAttachObjectARB(myShaderProgram, VertexShader));
482 GLCheck(glAttachObjectARB(myShaderProgram, FragmentShader));
485 GLCheck(glDeleteObjectARB(VertexShader));
486 GLCheck(glDeleteObjectARB(FragmentShader));
489 GLCheck(glLinkProgramARB(myShaderProgram));
492 GLCheck(glGetObjectParameterivARB(myShaderProgram, GL_OBJECT_LINK_STATUS_ARB, &Success));
493 if (Success == GL_FALSE)
497 GLCheck(glGetInfoLogARB(myShaderProgram,
sizeof(LinkLog), 0, LinkLog));
498 std::cerr <<
"Failed to link post-effect :" << std::endl
499 << LinkLog << std::endl;
500 GLCheck(glDeleteObjectARB(myShaderProgram));
Abstract base class for every object that can be drawn into a render window.
Image is the low-level class for loading and manipulating images.
unsigned int GetHeight() const
Return the height of the image.
unsigned int GetWidth() const
Return the width of the image.
bool CopyScreen(RenderWindow &Window, const IntRect &SourceRect=IntRect(0, 0, 0, 0))
Create the image from the current contents of the given window.
FloatRect GetTexCoords(const IntRect &Rect) const
Convert a subrect expressed in pixels, into float texture coordinates.
void SetSmooth(bool Smooth)
Enable or disable image smooth filter.
PostFX is used to apply a post effect to a window.
bool LoadFromFile(const std::string &Filename)
Load the effect from a file.
PostFX()
Default constructor.
void SetTexture(const std::string &Name, Image *Texture)
Set a texture parameter.
void SetParameter(const std::string &Name, float X)
Change a parameter of the effect (1 float)
bool LoadFromMemory(const std::string &Effect)
Load the effect from a text in memory.
static bool CanUsePostFX()
Tell whether or not the system supports post-effects.
virtual void Render(RenderTarget &Target) const
/see Drawable::Render
PostFX & operator=(const PostFX &Other)
Assignment operator.
T Top
Top coordinate of the rectangle.
T Right
Right coordinate of the rectangle.
T Left
Left coordinate of the rectangle.
T Bottom
Bottom coordinate of the rectangle.
Base class for all render targets (window, image, ...)
Simple wrapper for sf::Window that allows easy 2D rendering.
Vector2 is an utility class for manipulating 2 dimensional vectors.