SFML community forums

Help => Graphics => Topic started by: Strobe on March 03, 2013, 11:16:10 pm

Title: How can I prevent a program from exiting when loading a faulty shader?
Post by: Strobe on March 03, 2013, 11:16:10 pm
Hi,

I'm developing a small app for producing generative art. Since I wish to load shaders while the program is running, I'll need some way to prevent the program from crashing if/when the shaders contain any errors. Ideally, a simple default shader would be loaded and a message displayed whenever a shader program is not compiled successfully. The CompileProgram() method looks promising, but is private.

Could anyone point me in the right direction so I can get this working? Compiling SFML is no problem.

-Strobe
Title: Re: How can I prevent a program from exiting when loading a faulty shader?
Post by: Nexus on March 03, 2013, 11:18:38 pm
Do the methods sf::Shader::loadFromXY() not return false in this case?
Title: Re: How can I prevent a program from exiting when loading a faulty shader?
Post by: FRex on March 03, 2013, 11:22:17 pm
Faulty shader will just not work and display errors while assigning values to it's uniforms, it'll not crash. But yes, loads return a bool..
Title: Re: How can I prevent a program from exiting when loading a faulty shader?
Post by: Strobe on March 04, 2013, 01:39:16 am
Thanks guys. Here's what I have:

if (!ShaderMain.LoadFromFile(gfx.ShaderMainFile))
  ShaderIsValid = false;
else
  ShaderIsValid = true;
 

I don't think I need a contingency shader after all.

So now I'm experiencing another problem. When I attempt to reload the shader, SFML appears to be adding the existing shader code to what was loaded before. For instance, the first error message I get is this: "'Buf1' conflicts with previous declaration at 0(1)." The other errors mention other variables, eventually arriving at main().

I need to be able to clear ShaderMain's contents in order to reload it from a file.
Title: Re: How can I prevent a program from exiting when loading a faulty shader?
Post by: Strobe on March 04, 2013, 02:08:38 am
You might want to read this (https://github.com/SFML/SFML/wiki/FAQ#wiki-grl-version). :)

I'm already using SFML 2.0. Or are you suggesting that I downgrade to 1.6?

I see a private method, "std::string  myFragmentShader," in which I'm tempted to make public just so I can clear its contents at will :)
Title: Re: How can I prevent a program from exiting when loading a faulty shader?
Post by: Strobe on March 04, 2013, 04:15:57 am
OK, so I made "std::string  myFragmentShader" in "SFML/Graphics/Shader.hpp" public, and it is working, but not correctly.

Here's what I'm doing in my main file:

case sf::Keyboard::L:

  // clearing the shader string
  ShaderMain.myFragmentShader.clear();

  // loading
  if (ShaderMain.LoadFromFile(gfx.ShaderMainFile))
    ShaderIsValid = true;
  else
    ShaderIsValid = false;

  // this checks out
  cout << ShaderMain.myFragmentShader;

break;
 

For testing purposes I am using a noise shader that just fills the screen with random values. I'm feeding it a random number to offset the noise to behave like TV static. There is a uniform sampler declared in the shader that isn't being used in the C++ program, so I know that the shader was loaded successfully when I see an error pertaining to said unused uniform sampler. If an attempt to load the shader fails, the screen will go blank.

When reloading the shader, strange things are occurring:

Was it a bad idea to make myFragmentShader public?
Title: Re: How can I prevent a program from exiting when loading a faulty shader?
Post by: Strobe on March 04, 2013, 06:26:18 am
I may have found a solution:

case sf::Keyboard::L:

  ShaderMain.myFragmentShader.clear();

  if (ShaderMain.LoadFromFile(gfx.ShaderMainFile))
  {
    ShaderIsValid = true;
    cout << "shader loaded.\n";
  }
  else
    ShaderIsValid = false;

  Buf1.Clear();
  Buf2.Clear();

  ShaderMain.SetParameter("offset", 1.f/(float)gfx.w, 1.f/(float)gfx.h);
  ShaderMain.Bind();

break;
 

As it turns out the render textures must be cleared, one-time parameters must be reset, and the shader bound. I'm sure something else will crop up, but I think I have it covered now ;) Speak up if I'm doing something horribly wrong   ;D
Title: Re: How can I prevent a program from exiting when loading a faulty shader?
Post by: Laurent on March 04, 2013, 08:59:01 am
This is definitely not SFML 2. In SFML 2, functions use camelCase naming, members have the "m_" prefix, sf::Shader handles vertex and fragment shaders, and the "myFragmentShader" member doesn't exist anymore.
Title: Re: How can I prevent a program from exiting when loading a faulty shader?
Post by: Strobe on March 04, 2013, 08:39:34 pm
This is definitely not SFML 2. In SFML 2, functions use camelCase naming, members have the "m_" prefix, sf::Shader handles vertex and fragment shaders, and the "myFragmentShader" member doesn't exist anymore.

Hmm, something's not adding up. A while back I downloaded the source for version 2, I can't remember when. Anyway, inside that .zip is a directory named "LaurentGomila-SFML-e5d6353." This is what I've been building the libraries from.

The list of modifications from 1.6 to 2.0 seem to indicate that I am indeed using the latter version. For instance, I use "EnableVerticalSync,"  and "sf::Shader" in my programs. I can also build static libraries instead dynamically linked ones.

Maybe I am not using the latest version of SFML 2.0, but some earlier draft?
Title: Re: How can I prevent a program from exiting when loading a faulty shader?
Post by: Laurent on March 04, 2013, 08:48:05 pm
Yes, it could be also a veryyyyyy old revision (like 2 years old).
Title: Re: How can I prevent a program from exiting when loading a faulty shader?
Post by: eXpl0it3r on March 04, 2013, 09:37:06 pm
Yes, it could be also a veryyyyyy old revision (like 2 years old).
Yep: 2011-08-19 (https://github.com/SFML/SFML/commit/e5d6353) ;D

The CamelCase was what got me confused as well.
Title: Re: How can I prevent a program from exiting when loading a faulty shader?
Post by: Strobe on March 05, 2013, 10:55:16 pm
Ha! Behind the times I am. I may have to download the latest version.

I see texture wrapping can now be enabled with setRepeated(), but render textures have no such support. I thought I could do something like in this post: http://en.sfml-dev.org/forums/index.php?topic=5016.0 , but the RenderTexture class has no Bind() function.

I'd also like to enable float render textures, but it's the same problem again.
Title: Re: How can I prevent a program from exiting when loading a faulty shader?
Post by: Laurent on March 06, 2013, 10:20:24 am
Quote
I see texture wrapping can now be enabled with setRepeated(), but render textures have no such support. I thought I could do something like in this post: http://en.sfml-dev.org/forums/index.php?topic=5016.0 , but the RenderTexture class has no Bind() function.
You must bind the render-texture's texture, not the render-texture itself. And remember the new syntax for binding: sf::Texture::bind(&texture).

Quote
I'd also like to enable float render textures, but it's the same problem again.
This one is much more complicated without direct support from SFML, yes :-\