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

Author Topic: Alpha channel gets lost  (Read 2209 times)

0 Members and 1 Guest are viewing this topic.

wintertime

  • Sr. Member
  • ****
  • Posts: 255
    • View Profile
Alpha channel gets lost
« on: November 10, 2013, 08:27:39 pm »
I was trying to do a forum search, but it only yields a Database error, so I try asking. ;)
I wanted to use a sf::RenderTexture, bind it and draw it to a window using OpenGL calls. The problem is I noticed the transparent parts of the Texture overwrite whats on the window when they should be invisible.
In the example code I wrote (I put it together from several classes in my code, added some globals to replace member variables, fixed it up and shortened it) the whole window should stay green, but it shows a red rectangle. It seems the alpha channel gets lost when using the texture or copying it?
#include "SFML/Window.hpp"
#include "SFML/OpenGL.hpp"
#include "SFML/Graphics.hpp"
#include <stdexcept>

int32_t windowx(1024);
int32_t windowy(768);
bool fullscreen(false);
sf::IntRect screenRect(0,0,windowx,windowy);

bool ProcessEvent(sf::Event& event) {
  if(event.type==sf::Event::Resized) {
    windowx=event.size.width;
    windowy=event.size.height;
    screenRect.width=windowx;
    screenRect.height=windowy;
    glViewport(0,0,event.size.width,event.size.height);
  }
  return event.type==sf::Event::KeyReleased;
}

void Draw(sf::Window& window) {
  glClearColor(0.0f,1.0f,0.0f,1.0f); // green
  glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);

  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glOrtho(screenRect.left,screenRect.left+screenRect.width,screenRect.top+screenRect.height,screenRect.top,+1024.0,-1024.0);
  glMatrixMode(GL_MODELVIEW);

  sf::RenderTexture rtex;
  if(!rtex.create(32,32))
    throw std::runtime_error("error creating RenderTexture");
  rtex.clear(sf::Color(255,0,0,0)); // transparent red
  rtex.display();

  window.setActive();
  sf::Texture::bind(&(rtex.getTexture()));

  glEnable(GL_TEXTURE_2D);
  glColor4ub(255,255,255,255);
  const sf::IntRect& rect(screenRect);

  glBegin(GL_TRIANGLES);
  glTexCoord2f(0.f,0.f);
  glVertex2i(rect.left           ,rect.top);
  glTexCoord2f(0.f,1.f);
  glVertex2i(rect.left           ,rect.top+rect.height/2);
  glTexCoord2f(1.f,1.f);
  glVertex2i(rect.left+rect.width/2,rect.top+rect.height/2);
  glVertex2i(rect.left+rect.width/2,rect.top+rect.height/2);
  glTexCoord2f(1.f,0.f);
  glVertex2i(rect.left+rect.width/2,rect.top);
  glTexCoord2f(0.f,0.f);
  glVertex2i(rect.left           ,rect.top);
  glEnd();

  glColor4ub(0,0,0,0);
  sf::Texture::bind(nullptr);
  glDisable(GL_TEXTURE_2D);
}

int main(int argc,char* argv[]) {
  sf::Window window(sf::VideoMode(windowx,windowy),"Test",
                    fullscreen ? sf::Style::Fullscreen : sf::Style::Default,
                    sf::ContextSettings(0,0,0,2,1));
  window.setVerticalSyncEnabled(1);
  glViewport(0,0,windowx,windowy);

  sf::Event event;
  while(window.isOpen()) {
    Draw(window);
    window.display();

    while(window.pollEvent(event)) {
      if(ProcessEvent(event) || event.type==sf::Event::Closed)
        window.close();
    }
  }

  return 0;
}
 

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: Alpha channel gets lost
« Reply #1 on: November 10, 2013, 08:45:21 pm »
Enable blending and choose the correct blending function.
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

You may have to set additional states, don't assume SFML does it for you. Furthermore, keep OpenGL and SFML draw calls separate with the sf::Window functions, as shown in the OpenGL tutorial.

By the way, is there a specific reason why you use OpenGL, or is it just an experiment for learning purposes?
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

wintertime

  • Sr. Member
  • ****
  • Posts: 255
    • View Profile
Re: Alpha channel gets lost
« Reply #2 on: November 10, 2013, 09:19:54 pm »
Ahh, thank you. Weird that its just forgetting such a simple thing as enabling blending.
Its gonna be a 3D game, thats why I use OpenGL everywhere. The only exception is converting some text strings to textures for the GUI when they are first used, then these textures get reused for many frames, but I deleted that part to shorten the example.
I read that tutorial already when searching for info, but what do you mean with more separating? I only use SFML Graphics module when a RenderTexture gets written to shortly and then reactivate the Window(its no RenderWindow because I only use OpenGL on it), so appeared no and should be no problem. I would assume the RenderTexture got its own context and it needs no resetGLStates call?

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: Alpha channel gets lost
« Reply #3 on: November 10, 2013, 09:30:19 pm »
I meant the ...GLStates() functions, in case you mix OpenGL and SFML draw calls. Either you use them, or you keep track of all the OpenGL states on your own.
« Last Edit: November 10, 2013, 09:31:50 pm by Nexus »
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development: