SFML community forums

Help => Graphics => Topic started by: topfpflanze on April 04, 2018, 03:18:01 pm

Title: Texture is overwritten
Post by: topfpflanze on April 04, 2018, 03:18:01 pm
Hi,
I'm having  a small problem in an application, mixing OpenGL and normal SFML draw calls. As soon as I generate a texture (in my case a 3D texture) in OpenGL, it overrides the SFML texture I've loaded. Drawing the texture to the screen (even without any other OpenGL calls than those to generate the texture) just shows a slice of the 3D texture instead.

Minimal code to reproduce:
int main(int argc, char* argv[]) {

  sf::RenderWindow window(sf::VideoMode(1280, 720));

  GLenum glew_status = glewInit();
  if (glew_status) {
    std::cout << "GLEW could not be initialized: " << glewGetErrorString(glew_status) << std::endl;
    return -1;
  }
  glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  glPixelStorei(GL_PACK_ALIGNMENT, 1);
  glEnable(GL_FRAMEBUFFER_SRGB);
  glEnable(GL_TEXTURE_2D);
  glEnable(GL_TEXTURE_3D);

  sf::Texture material_texture;
  material_texture.loadFromFile("assets/materials/specular.png");
 
  // volume_data, volume_width, volume_height, volume_depth are read from file
  GLuint volume_texture;
  glGenTextures(1, &volume_texture);
  glBindTexture(GL_TEXTURE_3D, volume_texture);
  glTexStorage3D(GL_TEXTURE_3D, 1, GL_R16, volume_width, volume_height, volume_depth);
  glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, volume_width, volume_height, volume_depth, GL_RED, GL_UNSIGNED_SHORT, (void*)volume_data);

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

    window.clear(sf::Color::Black);

    sf::Sprite material(material_texture);
    window.draw(material);

    window.display();
  }

  return 0;
}
 
Title: Re: Texture is overwritten
Post by: Laurent on April 04, 2018, 03:27:02 pm
Have you read the documentation (https://www.sfml-dev.org/tutorials/2.4/window-opengl.php#using-opengl-together-with-the-graphics-module) first?
Title: Re: Texture is overwritten
Post by: topfpflanze on April 04, 2018, 05:47:10 pm
Yes, and I've tried multiple combinations of push, pop and reset and neither worked for me. Also, how would I even use it here, where I don't even draw anything using OpenGL?
Title: Re: Texture is overwritten
Post by: Laurent on April 04, 2018, 06:02:44 pm
The OpenGL calls that you make after creating the window are enough to mess up the internal cache of the RenderWindow. So yes, you should apply what the tutorial suggests, or manage the states yourself when you switch between OpenGL and SFML.
Title: Re: Texture is overwritten
Post by: topfpflanze on April 04, 2018, 06:12:28 pm
Well, no matter what I've tried with pushGLStates and popGLStates, I couldn't get it to work in my minimal code example. According to the tutorial, shouldn't it be enough to push the states after the creation of the texture and then create the material_texture afterwards?
Title: Re: Texture is overwritten
Post by: Laurent on April 04, 2018, 06:49:14 pm
Can you show the code that you've tried, so that we can see what's wrong and help you fix it?
Title: Re: Texture is overwritten
Post by: topfpflanze on April 04, 2018, 06:57:59 pm
It's hard to tell since I've tried various combinations. Basically pushing/poping before and after calling OpenGL code, with the recent one looking like this:
int main(int argc, char* argv[]) {

  sf::RenderWindow window(sf::VideoMode(1280, 720));

  GLenum glew_status = glewInit();
  if (glew_status) {
    std::cout << "GLEW could not be initialized: " << glewGetErrorString(glew_status) << std::endl;
    return -1;
  }
  glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  glPixelStorei(GL_PACK_ALIGNMENT, 1);
  glEnable(GL_FRAMEBUFFER_SRGB);
  glEnable(GL_TEXTURE_2D);
  glEnable(GL_TEXTURE_3D);

  // volume_data, volume_width, volume_height, volume_depth are read from file
  GLuint volume_texture;
  glGenTextures(1, &volume_texture);
  glBindTexture(GL_TEXTURE_3D, volume_texture);
  glTexStorage3D(GL_TEXTURE_3D, 1, GL_R16, volume_width, volume_height, volume_depth);
  glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, volume_width, volume_height, volume_depth, GL_RED, GL_UNSIGNED_SHORT, (void*)volume_data);
  window.pushGLStates();

  sf::Texture material_texture;
  material_texture.loadFromFile("assets/materials/specular.png");

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

    window.clear(sf::Color::Black);

    sf::Sprite material(material_texture);
    window.draw(material);

    window.display();
  }

  return 0;
}
 

I've also tried the opposite, pushing the gl state after creating the window and popping it after creating the texture but to no effect.
Title: Re: Texture is overwritten
Post by: topfpflanze on April 04, 2018, 08:05:44 pm
It seems, the culprit was
glEnable(GL_TEXTURE_3D);
for whatever reason. After removing that line, everything works as expected and a
target.resetGLStates();
after drawing with OpenGL is enough.