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...