Salut, j'ai fais un code minimal pour reproduire le bug, j'essaie d'afficher un rectangle rouge sur la texture d'un FBO et un rectangle vert et un rectangle bleu sur une autre texture de FBO, mais, le blending alpha ne e faire pas et le rectangle rouge n'est pas affiché et pas de blending non plus à l'intersection du rectangle vert et bleu.
Voici le code :
int main(int argc, char* argv[])
{
sf::RenderWindow window(sf::VideoMode(800, 600), "test blending", sf::Style::Default,
sf::ContextSettings(0, 0, 0, 3, 0));
sf::RenderTexture rt1, rt2;
rt1.create(800, 600, sf::ContextSettings(0, 0, 0, 3, 0));
rt2.create(800, 600, sf::ContextSettings(0, 0, 0, 3, 0));
sf::RectangleShape tile1 (sf::Vector2f(100, 50));
tile1.setFillColor(sf::Color(255, 0, 0, 50));
sf::RectangleShape tile2 (sf::Vector2f(100, 50));
tile2.setPosition(50, 25);
tile2.setFillColor(sf::Color(0, 255, 0, 50));
sf::RectangleShape tile3 (sf::Vector2f(100, 50));
tile3.setPosition(-50, 25);
tile3.setFillColor(sf::Color(0, 0, 255, 50));
sf::Sprite trt1(rt1.getTexture());
sf::Sprite trt2(rt2.getTexture());
while (window.isOpen()) {
sf::Event event;
while (window.pollEvent(event)) {
if (event.type == sf::Event::Closed) {
window.close();
}
}
window.clear();
rt1.clear();
rt2.clear();
rt1.draw(tile1);
rt1.display();
rt2.draw(tile2);
rt2.draw(tile3);
rt2.display();
window.draw(trt1);
window.draw(trt2);
window.display();
}
return 0;
}
Je suis sur windows 10 et ma carte graphique c'est une nvidia.
Lorsque j'essaie sur mon portable avec linux et une carte graphique amd ça marche.
Quelqu'un m'a dit qu'il fallait utiliser des autres paramètres pour le blending avec des FBO mais je ne sais pas lesquels.
Bon il semblerait que le problème vienne de la SFML, j'ai essayé d'utiliser opengl en dehors de la SFML pour dessiner presque la même chose avec deux FBO et là le blending alpha se fait bien.
int main(int argc, char* argv[])
{
sf::Window window(sf::VideoMode(800, 600), "test", sf::Style::Default, sf::ContextSettings(0, 0, 4, 3, 0));
GLenum err = glewInit();
if (GLEW_OK != err)
{
/* Problem: glewInit failed, something is seriously wrong. */
fprintf(stderr, "Error: %s\n", glewGetErrorString(err));
}
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
float verticesFBO1[] = {-1.f, -1.f,
1.f, 0, 0, 0.5f,
-0.90f, -1.f,
1.f, 0, 0, 0.5f,
-0.90f, -0.90f,
1.f, 0, 0, 0.5f,
-1.f, -0.90f,
1.f, 0, 0, 0.5f};
float verticesFBO2[] = {-0.95f, -0.95f,
0, 1.f, 0, 0.5f,
-0.85f, -0.95f,
0, 1.f, 0, 0.5f,
-0.85f, -0.85f,
0, 1.f, 0, 0.5f,
-0.95f, -0.85f,
0, 1.f, 0, 0.5f};
float fullScreenQuad[] = {-1.f, -1.f,
1.f, 1.f, 1.f, 1.f,
0.f, 0.f,
-1.f, 1.f,
1.f, 1.f, 1.f, 1.f,
1.f, 0.f,
1.f, 1.f,
1.f, 1.f, 1.f, 1.f,
1.f, 1.f,
1.f, -1.f,
1.f, 1.f, 1.f, 1.f,
0.f, 1.f};
GLuint textureFBO1;
glGenTextures(1, &textureFBO1);
glBindTexture(GL_TEXTURE_2D, textureFBO1);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 800, 600, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
GLuint textureFBO2;
glCheck(glGenTextures(1, &textureFBO2));
glBindTexture(GL_TEXTURE_2D, textureFBO2);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 800, 600, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
const char* data = reinterpret_cast<const char*>(fullScreenQuad);
glVertexPointer(2, GL_FLOAT, 32, data + 0 );
glColorPointer(4, GL_FLOAT, 32, data + 8);
glTexCoordPointer(2, GL_FLOAT, 32, data + 24);
sf::Context contextFBO1(sf::ContextSettings(0, 0, 4, 3, 0),800, 600);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
const char* data2 = reinterpret_cast<const char*>(verticesFBO1);
glVertexPointer(2, GL_FLOAT, 24, data2 + 0 );
glColorPointer(4, GL_FLOAT, 24, data2 + 8);
GLuint framebuffer1;
glGenFramebuffers(1, &framebuffer1);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer1);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureFBO1, 0);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
std::cerr<<"failed to create frame buffer 1";
}
sf::Context contextFBO2(sf::ContextSettings(0, 0, 4, 3, 0),800, 600);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
const char* data3 = reinterpret_cast<const char*>(verticesFBO2);
glVertexPointer(2, GL_FLOAT, 24, data3 + 0 );
glColorPointer(4, GL_FLOAT, 24, data3 + 8);
GLuint framebuffer2;
glGenFramebuffers(1, &framebuffer2);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer2);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureFBO2, 0);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
std::cerr<<"failed to create frame buffer 2";
}
fprintf(stdout, "Status: Using GLEW %s\n", glewGetString(GLEW_VERSION));
while (window.isOpen()) {
sf::Event event;
while (window.pollEvent(event)) {
if (event.type == sf::Event::Closed) {
window.close();
}
}
contextFBO1.setActive(true);
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_QUADS, 0, 4);
glFlush();
contextFBO2.setActive(true);
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_QUADS, 0, 4);
glFlush();
window.setActive(true);
glClear(GL_COLOR_BUFFER_BIT);
glBindTexture(GL_TEXTURE_2D, textureFBO1);
glDrawArrays(GL_QUADS, 0, 4);
glBindTexture(GL_TEXTURE_2D, textureFBO2);
glDrawArrays(GL_QUADS, 0, 4);
window.display();
}
return 0;
}