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

Author Topic: Shader and render texture  (Read 6946 times)

0 Members and 1 Guest are viewing this topic.

reDo

  • Full Member
  • ***
  • Posts: 104
    • View Profile
Shader and render texture
« on: April 22, 2012, 08:42:20 pm »
Hi, I want to create something like lights with using the shaders, but I do not know how to use one shader with different properties on the same render texture. I want to use it like "cycle for". Please can you tell me how to do this or another way? And I have another problem, now when I am drawing background image to the render texture, it is flipped vertically.
My code
Code: [Select]
#include <SFML/System.hpp>
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <iostream>
#include <cstring>
#include <vector>

class CLight
{
    public:
        sf::Vector2f position;
        sf::Color color;
        float radius;

        CLight(sf::Vector2f pos, sf::Color col, float rad)
        {
            position = pos;
            color = col;
            radius = rad;
        }
};

int main()
{
    sf::RenderWindow App(sf::VideoMode(800,600,32),"SFML");
    App.setFramerateLimit(60);

    std::vector<CLight> lights;
    lights.push_back(CLight(sf::Vector2f(400,300), sf::Color(128,128,128), 200.f));

    sf::RenderTexture renderTexture;
    renderTexture.create(800,600);

    sf::Texture backTex;
    backTex.loadFromFile("image.png");
    backTex.setSmooth(false);
    sf::Sprite background(backTex);

    sf::Shader fragShader;

    if(!fragShader.loadFromFile("light.frag",sf::Shader::Fragment))
        App.close();

    fragShader.setParameter("texture", backTex);
    while(App.isOpen())
    {
        sf::Event event;
        while(App.pollEvent(event))
        {
            if((event.type == sf::Event::Closed) || (event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::Escape))
                App.close();
        }

        float mouseX = float(sf::Mouse::getPosition(App).x);
        float mouseY = float(sf::Mouse::getPosition(App).y);

        std::cout<<mouseX<<" "<<mouseY<<std::endl;

        App.clear();
        renderTexture.clear();

        fragShader.setParameter("lightRad", lights[0].radius);
        fragShader.setParameter("lightPos", lights[0].position.x, 600.f-lights[0].position.y);
        fragShader.setParameter("lightCol", lights[0].color.r/255.f, lights[0].color.g/255.f, lights[0].color.b/255.f);

        sf::RenderStates shader(&fragShader);
        renderTexture.draw(background, shader);

        sf::Sprite drawTexture(renderTexture.getTexture());
        App.draw(drawTexture);

        App.display();
    }

    return 0;
}

Shader
Code: [Select]
uniform sampler2D texture;

uniform float lightRad; //radius
uniform vec2 lightPos; //position
uniform vec3 lightCol; //color

void main(void)
{
vec4 pixel = texture2D(texture, gl_TexCoord[0].xy);
float dis = 1.0f - distance(vec2(gl_FragCoord), lightPos) / lightRad;
vec4 light = vec4(lightCol.r,lightCol.g,lightCol.b,dis);

vec4 col = pixel + light;
gl_FragColor = vec4(col.xyz, dis);
}

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Shader and render texture
« Reply #1 on: April 22, 2012, 09:37:53 pm »
I don't understand your first question.

Quote
I have another problem, now when I am drawing background image to the render texture, it is flipped vertically.
You forgot
renderTexture.display();
Laurent Gomila - SFML developer

reDo

  • Full Member
  • ***
  • Posts: 104
    • View Profile
Re: Shader and render texture
« Reply #2 on: April 23, 2012, 03:45:14 pm »
Thanks that solved this problem  :D but the main is still unsolved.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Shader and render texture
« Reply #3 on: April 23, 2012, 06:03:50 pm »
And I still don't understand it :)

Would you mind elaborating a little bit?
Laurent Gomila - SFML developer

reDo

  • Full Member
  • ***
  • Posts: 104
    • View Profile
Re: Shader and render texture
« Reply #4 on: April 23, 2012, 07:30:34 pm »
I wanna create something like lighting with multiple lights. Here is picture how it looks with one light. But I wanna use multiple lights with using shaders for it. I have std::vector of lights as you can see in my code and I wanna render all lights from vector with calling shader with different properties for each light. All rendering is done to render texture and here is the problem. I dont know how to call one shader for the render texture without passing a picture that is modified. So I wanna apply light shader with different properties on background image in render texture. Do you understand know :D?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Shader and render texture
« Reply #5 on: April 23, 2012, 08:07:50 pm »
You want to make multiple passes? To do so, you must use the result of one pass as a source texture for the next pass. So you understand that you need at least two render-textures (one source and one target, since you can't read and write to the same texture at  the same time).

Some pseudo-code:
Code: [Select]
sf::RenderTexture targets[2];
sf::RenderTexture* front = target[0];
sf::RenderTexture* back = target[1];

foreach (shader)
{
    front->setParameter("texture", back);
    ... draw ...
    swap(front, back);
}

// final result is in "back"
Laurent Gomila - SFML developer

reDo

  • Full Member
  • ***
  • Posts: 104
    • View Profile
Re: Shader and render texture
« Reply #6 on: April 24, 2012, 03:20:33 pm »
Thanks that is what I was searching for  :).
« Last Edit: April 24, 2012, 08:13:03 pm by reDo »