Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: How can I prevent a program from exiting when loading a faulty shader?  (Read 4246 times)

0 Members and 1 Guest are viewing this topic.

Strobe

  • Newbie
  • *
  • Posts: 15
    • View Profile
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

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Do the methods sf::Shader::loadFromXY() not return false in this case?
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

FRex

  • Hero Member
  • *****
  • Posts: 1845
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
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..
Back to C++ gamedev with SFML in May 2023

Strobe

  • Newbie
  • *
  • Posts: 15
    • View Profile
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.

Strobe

  • Newbie
  • *
  • Posts: 15
    • View Profile
You might want to read this. :)

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 :)

Strobe

  • Newbie
  • *
  • Posts: 15
    • View Profile
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:
  • I do not receive an error about the unused uniform sampler
  • the screen isn't going blank like it would if the shader couldn't be loaded
  • the static suddenly stands still, as if the parameter I am feeding it isn't changing
  • the program continues happily as if nothing is wrong

Was it a bad idea to make myFragmentShader public?

Strobe

  • Newbie
  • *
  • Posts: 15
    • View Profile
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

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
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.
Laurent Gomila - SFML developer

Strobe

  • Newbie
  • *
  • Posts: 15
    • View Profile
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?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Yes, it could be also a veryyyyyy old revision (like 2 years old).
Laurent Gomila - SFML developer

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10823
    • View Profile
    • development blog
    • Email
Re: How can I prevent a program from exiting when loading a faulty shader?
« Reply #10 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 ;D

The CamelCase was what got me confused as well.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Strobe

  • Newbie
  • *
  • Posts: 15
    • View Profile
Re: How can I prevent a program from exiting when loading a faulty shader?
« Reply #11 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.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: How can I prevent a program from exiting when loading a faulty shader?
« Reply #12 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 :-\
Laurent Gomila - SFML developer