Search code examples
c++openglglsltexturesstb-image

Why is it when I open my game with MSI afterburner overlay toggled on none of my textures work how they are supposed to


Whenever I open my game with the MSI afterburner overlay toggled on the textures seem to be shifted by one so the first one gets set to the second one, the second to the third and so on. But if I don`t use the overlay while loading everything is fine. I have a feeling this is to do with texture ids in openGL but I really don't know. I have literally gone through my entire project and found nothing.

Here is the code I think is relevant because my project is quite big:

Main render class:

#include "main_renderer.h"

Renderer::Renderer(Shader *shader, Player *player, World *world): shader(shader), player(player), world(world){
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);
    glEnable(GL_STENCIL);

    float vertices[] = {
       // vertices I really don`t think these are the problem so im not going to add them all    
    }; 

    unsigned int count = 0;
    for (unsigned int z = 0; z < 1; z++){
    for (unsigned int x = 0; x < 16; x++){
        for (unsigned int y = 0; y < 16; y++){
            cubePositions[count] = glm::vec3( 0.0f + x,  0.0f + z,  0.0f + y);
            count += 1;
        };
    };
    };//generates a 16 by 16 grid of cubes

    glGenVertexArrays(1, &cubeVAO);
    glGenBuffers(1, &VBO);

    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    glBindVertexArray(cubeVAO);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
    glEnableVertexAttribArray(2);

    unsigned int id_texture1 = loadTexture( "../textures/grass.png", false);
    unsigned int id_texture2 = loadTexture( "../textures/awesomeface.png", true);
    unsigned int id_texture3 = loadTexture( "../textures/container2.png", true);
        
    shader->use();  
    shader->setInt("grass", 0);
    shader->setInt("face", 1);
    shader->setInt("container", 2);
};

void Renderer::update(){
    extern float width, height;
    extern double currentFrame;

    shader->use();
    
    glm::mat4 projection = glm::perspective(glm::radians(player -> Zoom), (float) width /  (float) height, 0.05f, 500.0f);
    glm::mat4 view = player -> GetViewMatrix();
    shader->setMat4("projection", projection);
    shader->setMat4("view", view); 

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, 1);
    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, 2);
    glActiveTexture(GL_TEXTURE2);
    glBindTexture(GL_TEXTURE_2D, 3);  


    glBindVertexArray(cubeVAO);
        for (unsigned int i = 0; i < sizeof(cubePositions) / sizeof(cubePositions[0]); i++){
            glm::mat4 model = glm::mat4(1.0f);
            model = glm::translate(model, cubePositions[i]);
            shader->setMat4("model", model);

            glDrawArrays(GL_TRIANGLES, 0, 36);
        }
};

void Renderer::exit(){
    glDeleteVertexArrays(1, &cubeVAO);
    glDeleteBuffers(1, &VBO);
    glfwTerminate();
};

unsigned int Renderer::loadTexture(char const * path, bool linear){
    unsigned int textureID;
    std::cout<<textureID;
    glGenTextures(1, &textureID);
    
    int width, height, nrComponents;
    unsigned char *data = stbi_load(path, &width, &height, &nrComponents, 0);
    if (data){
        GLenum format;
        if (nrComponents == 1)
            format = GL_RED;
        else if (nrComponents == 3)
            format = GL_RGB;
        else if (nrComponents == 4)
            format = GL_RGBA;

        glBindTexture(GL_TEXTURE_2D, textureID);
        glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, data);
        glGenerateMipmap(GL_TEXTURE_2D);

        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
        if (linear){
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        }else{
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        };

        stbi_image_free(data);
    }
    else{
        std::cout << "Texture failed to load at path: " << path << std::endl;
        stbi_image_free(data);
    };

    return textureID;
};

Fragment shader:

#version 330 core
out vec4 FragColor;

uniform sampler2D grass;
uniform sampler2D face;
uniform sampler2D container;

in vec2 TexCoords;
 
void main(){
    vec4 color = texture(face, TexCoords);
    if (color.a < 0.5) {
        color = texture(grass, TexCoords); 
    }
    FragColor = color;
}

I think the problem lies somewhere in there seeing as everything was working fine yesterday and I added a couple of small changes and everything seemed to break and sadly my last backup is right before I implemented the textures which is really annoying.


Solution

  • I have resolved the problem! After looking at it for longer than I care to admit it turns out I was extremely incompetent and when binding the textures every frame I was just binding to the textures in the 1st, 2nd and 3rd slots but if another program was using one of those slots like the MSI afterburner overlay then when creating the textures it would add them to the 2nd, 3rd and so on slots consequently whenever the textures when bound it would check the 1st slot and use that texture. Basically having the effect of shifting the textures over one with a new first texture. To fix this I simply declared unsigned int id_texture1, id_texture2, id_texture3; in the main header file and just used their texture ids when binding like this:

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, id_texture1); etc...