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

Author Topic: SFML 2.0 Using shaders together with rendering text  (Read 14492 times)

0 Members and 3 Guests are viewing this topic.

r0undh0u53

  • Newbie
  • *
  • Posts: 14
    • View Profile
Re: SFML 2.0 Using shaders together with rendering text
« Reply #15 on: June 19, 2012, 05:10:43 pm »
Yes. But specifically, what I am doing is rendering a Quad using a shader and applying a texture to it. Then after that, render the Text.

I see an almost similar code in the "Edge effect" sample but the Texture was rendered as a Sprite. What I am really aiming for is similar to what you illustrated in a previous post of yours (http://en.sfml-dev.org/forums/index.php?topic=6426.msg42450#msg42450) wherein you used a VertexArray. The difference is that instead of passing the Texture directly into the draw call (in C# that would be in the RenderStates), I would pass the texture into the shader as a parameter and then pass the shader into the draw call.

So it looks like the shader method, wherein a texture passed to a shader and then passed to the states, is broken. But I do understand that this can easily be alleviated by passing the texture directly to the draw call and not bother with shaders. And just apply shaders directly to a RenderTexture if post processing is the goal.

I guess it's a case of the API allowing such a scenario (by way of the broad nature of supporting shaders), but internally, it doesn't really support it or at least in this case, with unexpected results in the texture coordinates.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: SFML 2.0 Using shaders together with rendering text
« Reply #16 on: June 19, 2012, 06:26:27 pm »
I've found the error. The shader cannot use the texture if it is not bound, and the texture cannot be bound if it is not assigned explicitely, either in a textured drawable (sprite, shape) or in the RenderStates.

What you must do is:
shader.SetParameter("texture", Shader.CurrentTexture); // so that it uses the current texture, whatever it is

RenderStates states = new RenderStates();
states.Texture = texture;
states.Shader = shader;

...

window.Draw(vertexArray, states);
Laurent Gomila - SFML developer

r0undh0u53

  • Newbie
  • *
  • Posts: 14
    • View Profile
Re: SFML 2.0 Using shaders together with rendering text
« Reply #17 on: June 19, 2012, 07:37:00 pm »
Ahhh ok.... So assigning a texture to a shader needs to be done by passing Shader.CurrentTexture and passing the texture to RenderStates.

How about if I have a 2nd texture that I would need to send to the shader? Would that be possible? Sorry for complicating a bit, it's just a curiosity. I plan on implementing some fullscreen transitions, I was thinking of sending 2 RenderTargets to a shader and do some interesting transitions like fade in/out, screen wipes, etc. Is that possible?

r0undh0u53

  • Newbie
  • *
  • Posts: 14
    • View Profile
Re: SFML 2.0 Using shaders together with rendering text
« Reply #18 on: June 19, 2012, 08:05:24 pm »
Ok so I experimented with the idea a bit. I modified my fragment shader to accept 2 textures. The second texture has some parts that are transparent and will be applied as a decal on top of the first texture:

uniform sampler2D texture;
uniform sampler2D texture2;

void main()
{
    vec4 color1 = texture2D(texture, gl_TexCoord[0].st);
    vec4 color2 = texture2D(texture2, gl_TexCoord[0].st);

    vec3 temp = mix(color1.rgb, color2.rgb, color2.a);

    gl_FragColor = vec4(temp, 1) * gl_Color;   
}
 

And here is my updated shader initialization code:

// Load the shader
shader = new Shader("basic.vert", "basic.frag");
shader.SetParameter("texture", Shader.CurrentTexture);
shader.SetParameter("texture2", texture2);
RenderStates states = new RenderStates();
states.Texture = texture;
states.Shader = shader;
 

It works! So I guess as long as I use "Shader.CurrentTexture" for my first texture, there won't be any problems with regards to texture coordinates introduced by Text rendering (and possibly other SFML built in drawables). This means I can now go wild in the fragment shader.  ;D

Thanks Laurent for a very very fascinating library! A special thank you too for continually updating the .NET bindings! Keep up the excellent work!

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: SFML 2.0 Using shaders together with rendering text
« Reply #19 on: June 19, 2012, 08:17:54 pm »
In fact what I said is wrong ;D

Shader binds its textures. So there's still no explanation for your initial code, but at least we've found that it's most likely related to the CurrentTexture parameter.

After checking the source code, I think your texture is bound to texture unit 1, not 0. 0 is reserved for the CurrentTexture. I realize that there's no way to know which texture unit a texture is bound to, which can be blocking when indices are required, like with texture matrices. The fragment shader is ok since it refers to textures by name.
« Last Edit: June 19, 2012, 08:20:23 pm by Laurent »
Laurent Gomila - SFML developer

r0undh0u53

  • Newbie
  • *
  • Posts: 14
    • View Profile
Re: SFML 2.0 Using shaders together with rendering text
« Reply #20 on: June 19, 2012, 09:45:19 pm »
Yeah, It was partly my gut feel too that there must be some sort of conflict in the texture index seeing that there is no way to set which index you want to bind the texture to. If you run the code, you will notice that the texture shows but only for a split second. So it seems that the draw call to render the text does something to the underlying render states.

At least there is a way to work around it, but the problem is if we extend the shader code to use gl_TexCoord[1..n].

 

anything