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

Author Topic: [ANSWERED] window.clear() unbinds my only texture  (Read 1334 times)

0 Members and 1 Guest are viewing this topic.

thecheeselover

  • Newbie
  • *
  • Posts: 24
    • View Profile
[ANSWERED] window.clear() unbinds my only texture
« on: June 06, 2015, 03:36:22 pm »
The title says it all: I don't understand why the call window.clear() unbinds the only texture I had binded. What I would like to do is load once a texture atlas and not have to do any bindings after that. If I bind my texture again just before the window.clear(), the texture gets black. If I bind my texture again just after the window.clear() then my texture looks perfectly fine.

I have done some tests: if I bind a texture once just after the window.clear() it appears for one frame. It is pretty clear that window.clear() does some unintended stuff.

Init:
void Core::Init()
{
    window = new sf::RenderWindow(sf::VideoMode(800, 600), "SFML works!");
    window->setVerticalSyncEnabled(true);
    window->setMouseCursorVisible(false);
    glewInit(); // Doit être appelé quand il y a un contexte OpenGL, donc après l'instanciation de la fenêtre.

    clock = new sf::Clock();
    camera = new CameraFreeRoaming (window, glm::vec3(0.0f, 5.0f, 5.0f), VecConst::ZERO_VEC3);

    glEnable(GL_TEXTURE_2D);

    glEnable(GL_DEPTH_TEST);
    glDepthMask(GL_TRUE);
    glDepthFunc(GL_LEQUAL);
    glDepthRange(0.0f, 1.0f);
    glClearDepth(1.0f);
}
 

Load:
void Core::Load()
{
    std::vector<ShaderSource> shaderSources =
        {ShaderSource("Resources/Test/Test_Tex_Shader.frag", ShaderType::FRAGMENT),
         ShaderSource("Resources/Test/Test_Tex_Shader.vert", ShaderType::VERTEX)};
    colorShader = new Shader(shaderSources);

    sf::Image img;

    if (img.loadFromFile("Resources/Test/cage.png"))
        std::cout << "Texture loaded" << std::endl;

    glGenTextures(1, &texture);
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); // GL_LINEAR_MIPMAP_LINEAR
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, img.getSize().x, img.getSize().y, 0, GL_RGBA, GL_UNSIGNED_BYTE, img.getPixelsPtr());
    glGenerateMipmap(GL_TEXTURE_2D);

    colorShader->useProgram();

    glUniform1i(glGetUniformLocation(colorShader->program, "textureSampler"), 0); // 0 pour GL_TEXTURE0
    std::cout << gluErrorString(glGetError()) << std::endl;

    projectionMat = glm::perspective(glm::radians(60.0f), (float)window->getSize().x / (float)window->getSize().y, 0.001f, 1000.0f);

    glUniformMatrix4fv(glGetUniformLocation(colorShader->program, "ProjectionMatrix"), 1, GL_FALSE, &projectionMat[0][0]);
    glUniformMatrix4fv(glGetUniformLocation(colorShader->program, "ModelMatrix"), 1, GL_FALSE, &worldMatrix[0][0]); // Si location = -1 = aucune erreur; autre que -1, mais n'existe pas = erreur

    cube1 = new DrawBuffers(CubeDataGenerator::GenCube(DataGeneratorUsage::Position3 | DataGeneratorUsage::ColorRGBA | DataGeneratorUsage::TexCoord), BufferUsage::STATIC_DRAW, true);
    cube2 = new DrawBuffers(CubeDataGenerator::GenCube(DataGeneratorUsage::Position3 | DataGeneratorUsage::ColorRGBA | DataGeneratorUsage::TexCoord, 2.0f), BufferUsage::STATIC_DRAW, true);
    cube3 = new DrawBuffers(CubeDataGenerator::GenCube(DataGeneratorUsage::Position3 | DataGeneratorUsage::ColorRGBA | DataGeneratorUsage::TexCoord, 1.0f, 3.0f, 0.1f), BufferUsage::STATIC_DRAW, true);

    clock->restart();
}
 

Draw:
void Core::Draw()
{
    window->clear();
    glClear(GL_DEPTH_BUFFER_BIT);

    glBindTexture(GL_TEXTURE_2D, texture); // à cause de window.clear()

    colorShader->useProgram();
    glUniformMatrix4fv(glGetUniformLocation(colorShader->program, "ViewMatrix"), 1, GL_FALSE, &camera->getView()[0][0]);

    glm::vec3 v1 (0.0f, 0.0f, 0.0f);
    glm::vec3 v2 (3.0f, 0.0f, 0.0f);
    glm::vec3 v3 (6.0f, 0.0f, 0.0f);

    glUniformMatrix4fv(glGetUniformLocation(colorShader->program, "ModelMatrix"), 1, GL_FALSE, &glm::translate(worldMatrix, v1)[0][0]);
    cube1->draw();

    glUniformMatrix4fv(glGetUniformLocation(colorShader->program, "ModelMatrix"), 1, GL_FALSE, &glm::translate(worldMatrix, v2)[0][0]);
    cube2->draw();

    glUniformMatrix4fv(glGetUniformLocation(colorShader->program, "ModelMatrix"), 1, GL_FALSE, &glm::translate(worldMatrix, v3)[0][0]);
    cube3->draw();

    window->display();
}
 
« Last Edit: June 06, 2015, 04:33:24 pm by thecheeselover »

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: window.clear() unbinds my only texture
« Reply #1 on: June 06, 2015, 03:51:16 pm »
It is pretty clear that window.clear() does some unintended stuff.
I guess it's not that clear that what you think is unintentional is actually intentional. ;)

The reason why sf::RenderTarget unbinds the currently bound texture before clearing is because Intel chips don't like it if a sf::RenderTexture's texture is kept bound when glClear() is called. Don't ask me why, probably a driver bug.

That doesn't change the fact that what you are doing breaks convention anyway. If you use sf::RenderWindow, you implicitly promise to set up your GL state environment anew every frame. Expecting states to be preserved between frames (and even between draw calls) is a mistake many people make when using SFML's graphics module. Any call into sf::RenderTarget is allowed to modify GL state, and you must be prepared for that.

Since it seems from your code like you are only using raw OpenGL to render anyway, just use an sf::Window instead. It doesn't have a clear() method, but since you are clearing depth yourself already, just add the extra colour bit and it will even save you the superfluous glClear() call inside sf::RenderTarget that you are making in your current implementation.
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).