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

Author Topic: Shaders are not binded to my render textures!  (Read 1891 times)

0 Members and 1 Guest are viewing this topic.

Lolilolight

  • Hero Member
  • *****
  • Posts: 1232
    • View Profile
Shaders are not binded to my render textures!
« on: April 16, 2014, 06:32:21 pm »
Hi!

I would like to render things on components, the components uses a depth buffer texture, a framebuffer texture, a view and a shader for advanced alpha and depthtesting.

But, there is a problem, it seems that my shaders are not binded because it doesn't do the alpha test and the depthtest :

#include "../../../../include/odfaeg/Graphics/2D/fastRenderComponent.h"
namespace odfaeg {
namespace g2d {
FastRenderComponent::FastRenderComponent (RenderWindow& window, int layer) :
    Transformable(Vec3f(window.getView().getPosition().x, window.getView().getPosition().y, layer),
                  Vec3f(window.getView().getSize().x, window.getView().getSize().y, 0),
                  Vec3f(window.getView().getSize().x + window.getView().getSize().x * 0.5f, window.getView().getPosition().y + window.getView().getSize().y * 0.5f, layer)),
    view(window.getView()) {
    sf::Vector3i resolution ((int) window.getSize().x, (int) window.getSize().y, window.getView().getSize().z);
    depthBuffer = new RenderTexture();
    frameBuffer = new RenderTexture();
    depthBuffer->create(resolution.x, resolution.y);
    frameBuffer->create(resolution.x, resolution.y);
    frameBuffer->setView(window.getView());
    depthBuffer->setView(window.getView());

    if (Shader::isAvailable()) {
        frameBufferGenerator = new Shader();
        depthBufferGenerator = new Shader();
        const std::string vertexShader =
        "void main () {"
            "gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;"
            "gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;"
            "gl_FrontColor = gl_Color;"
        "}";
        const std::string  depthGenFragShader =
        "uniform sampler2D depthBuffer;"
        "uniform sampler2D texture;"
        "uniform vec3 resolution;"
        "void main () {"
              "vec2 position = ( gl_FragCoord.xy / resolution.xy );"
              "vec4 color = texture2D(depthBuffer, position);"
              "vec4 pixel = texture2D(texture, gl_TexCoord[0].xy);"
              "if (abs(gl_FragCoord.z) > color.z && pixel.a >= color.a) {"
                 "gl_FragColor = vec4(0, 0, abs(gl_FragCoord.z), pixel.a);"
              "} else {"
                 "gl_FragColor = color;"
              "}"
        "}";
        const std::string frameBufferGenFragShader =
        "uniform sampler2D depthBuffer;"
        "uniform sampler2D frameBuffer;"
        "uniform sampler2D texture;"
        "uniform vec3 resolution;"
        "void main () { "
            "vec2 position = ( gl_FragCoord.xy / resolution.xy );"
            "vec4 depth = texture2D(depthBuffer, position);"
            "vec4 color = texture2D(frameBuffer, position);"
            "vec4 pixel = texture2D(texture, gl_TexCoord[0].xy);"
            "if (abs(gl_FragCoord.z) >= depth.z) {"
                "gl_FragColor = pixel;"
            "} else if (color.a < pixel.a) {"
                "gl_FragColor = pixel;"
            "} else {"
                "gl_FragColor = color;"
            "}"
        "}";
        if (!depthBufferGenerator->loadFromMemory(vertexShader, depthGenFragShader))
            throw Erreur(50, "Failed to load depth buffer generator shader", 0);
        if (!frameBufferGenerator->loadFromMemory(vertexShader, frameBufferGenFragShader))
            throw Erreur(51, "Failed to load frame buffer generator shader", 0);
         depthBufferGenerator->setParameter("resolution",resolution.x, resolution.y, resolution.z);
         frameBufferGenerator->setParameter("resolution",resolution.x, resolution.y, resolution.z);
         backgroundColor = sf::Color::Transparent;
    }
}
void FastRenderComponent::setBackgroundColor(sf::Color color) {
    this->backgroundColor = color;
}
void FastRenderComponent::clearBufferBits() {
    frameBuffer->clear(backgroundColor);
}
void FastRenderComponent::clearDepthBits() {
    depthBuffer->clear(sf::Color::Transparent);
}
g2d::Tile FastRenderComponent::getFrameBufferTile () const {
    sf::IntRect subRect(0, 0, frameBuffer->getView().getSize().x, frameBuffer->getView().getSize().y);
    g2d::Tile tile (&frameBuffer->getTexture(), Vec2f(0, 0), Vec2f(frameBuffer->getView().getSize().x, frameBuffer->getView().getSize().y), subRect);
    return tile;
}
g2d::Tile FastRenderComponent::getDepthBufferTile() {
    sf::IntRect subRect(0, 0, depthBuffer->getView().getSize().x, depthBuffer->getView().getSize().y);
    g2d::Tile tile (&depthBuffer->getTexture(), Vec2f(0, 0), Vec2f(depthBuffer->getView().getSize().x, depthBuffer->getView().getSize().y), subRect);
    return tile;
}
bool FastRenderComponent::load(std::vector<Entity*> visibleEntities)
{

    if (Shader::isAvailable()) {
        fg.clear();
        for (unsigned int i = 0; i < visibleEntities.size(); i++) {

            if (visibleEntities[i]->isLeaf()) {
                for (unsigned int j = 0; j < visibleEntities[i]->getFaces().size(); j++) {

                    visibleEntities[i]->getFaces()[j]->transform(visibleEntities[i]->getTransform());

                    fg.addFace(visibleEntities[i]->getFaces()[j]);
                }
            }
        }
        m_vertices = fg.getFaces();
    }
    this->visibleEntities = visibleEntities;
}

void FastRenderComponent::draw(RenderTarget& target, RenderStates states) const {
    const Shader* devShader = states.shader;
    states.transform = getTransform();
    if (Shader::isAvailable()) {
        states.shader = frameBufferGenerator;
        frameBufferGenerator->setParameter("depthBuffer", depthBuffer->getTexture());
        frameBufferGenerator->setParameter("frameBuffer", frameBuffer->getTexture());
        frameBufferGenerator->setParameter("texture", Shader::CurrentTexture);
        frameBuffer->setView(target.getView());
        for (unsigned int i = 0; i < m_vertices.size(); i++) {
            states.texture = const_cast<FastRenderComponent*>(this)->m_vertices[i].first.getMaterial().getTexture();
            for (unsigned int j = 0; j < m_vertices[i].second.size(); j++) {
                frameBuffer->draw(*m_vertices[i].second[j], states);
            }
        }
        frameBuffer->display();
        depthBuffer->setView(target.getView());
        depthBufferGenerator->setParameter("depthBuffer", depthBuffer->getTexture());
        depthBufferGenerator->setParameter("texture", Shader::CurrentTexture);
        states.shader = depthBufferGenerator;
        for (unsigned int i = 0; i < m_vertices.size(); i++) {
            states.texture = const_cast<FastRenderComponent*>(this)->m_vertices[i].first.getMaterial().getTexture();
            for (unsigned int j = 0; j < m_vertices[i].second.size(); j++) {
                depthBuffer->draw(*m_vertices[i].second[j], states);
            }
        }
        depthBuffer->display();
        g2d::Tile tile = getFrameBufferTile();
        tile.setCenter(frameBuffer->getView().getPosition());
        states.shader = devShader;
        target.draw(tile, states);
    } else {
        for (unsigned int i = 0; i < visibleEntities.size(); i++) {
            for (unsigned int j = 0; j < visibleEntities[i]->getFaces().size(); j++) {
                states.texture = visibleEntities[i]->getFaces()[j]->getMaterial().getTexture();
                states.transform = visibleEntities[i]->getTransform();
                target.draw(visibleEntities[i]->getFaces()[j]->getVertexArray(), states);
            }
        }
    }
}
void FastRenderComponent::init() {
}
FastRenderComponent::~FastRenderComponent() {

}
View& FastRenderComponent::getView() {
    return view;
}
int FastRenderComponent::getLayer() {
    return getPosition().z;
}
}
}
 

I pass the shader to the state before drawing on the framebuffer and the depthbuffer but it doesn't seems to work. :/

But when I draw directly on the renderwindow it works...

Lolilolight

  • Hero Member
  • *****
  • Posts: 1232
    • View Profile
Re: Shaders are not binded to my render textures!
« Reply #1 on: April 16, 2014, 07:57:43 pm »
Haaa, I've found the problem sorry.

I've to update the fram and depth buffer textures each time that I draw a vertex array and not when I've drawed all the stuff.

Jesper Juhl

  • Hero Member
  • *****
  • Posts: 1405
    • View Profile
    • Email
Re: Shaders are not binded to my render textures!
« Reply #2 on: April 16, 2014, 08:05:48 pm »
lolilolight; I've been reading a lot of your previous threads and this "I have a problem <whatever>" and then a few minutes or hours later "I found the problem" is becoming a pattern (no, not really becoming; it /is/ a pattern).
Here's a suggestion for you: the next time you run into a problem - don't post. Research the problem in private and experiment for at least 48 hours - then post if you still have not figured it out.
That's what all the rest of us do - research problems on our own and only post when we are really stuck after trying for quite a while on our own.

ChronicRat

  • Sr. Member
  • ****
  • Posts: 327
  • C++ programmer
    • View Profile
    • My blog
Re: Shaders are not binded to my render textures!
« Reply #3 on: April 16, 2014, 09:12:02 pm »
lolilolight; I've been reading a lot of your previous threads and this "I have a problem <whatever>" and then a few minutes or hours later "I found the problem" is becoming a pattern (no, not really becoming; it /is/ a pattern).
Here's a suggestion for you: the next time you run into a problem - don't post. Research the problem in private and experiment for at least 48 hours - then post if you still have not figured it out.
That's what all the rest of us do - research problems on our own and only post when we are really stuck after trying for quite a while on our own.
You can spend a week searching problem, but after posting on forum... "and then a few minutes or hours later "I found the problem" is becoming a pattern (no, not really becoming; it /is/ a pattern)."

 

anything