You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

开启MSI Afterburner overlay时OpenGL纹理错位问题求助

开启MSI Afterburner overlay时OpenGL纹理错位问题

开启MSI Afterburner overlay启动游戏后,出现纹理错位:第一个纹理被第二个替代,第二个被第三个替代,以此类推;关闭overlay启动则一切正常。怀疑和OpenGL纹理ID有关,但排查项目后没找到问题。昨天还正常,只做了少量修改就出问题,最近的备份在实现纹理之前,处境棘手。


主渲染类代码

#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;
};

片段着色器代码

#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;
}

问题根源与修复方案

核心问题

update()方法中绑定纹理时硬编码了固定ID1、2、3:

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, 1); // 错误:直接使用固定ID,而非实际加载的纹理ID
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, 2);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, 3);

正常情况下OpenGL生成的纹理ID可能刚好是1、2、3,但MSI Afterburner的overlay会提前创建OpenGL资源,抢占了这些ID,导致你加载的纹理ID变为其他值(比如4、5、6),此时绑定1、2、3会指向overlay的纹理,最终出现错位。

修复步骤

  1. 在Renderer类中添加成员变量保存纹理ID:
private:
    unsigned int id_texture1, id_texture2, id_texture3;
  1. 构造函数中赋值(替换原局部变量):
id_texture1 = loadTexture( "../textures/grass.png", false);
id_texture2 = loadTexture( "../textures/awesomeface.png", true);
id_texture3 = loadTexture( "../textures/container2.png", true);
  1. update()方法中使用实际纹理ID绑定:
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, id_texture1);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, id_texture2);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, id_texture3);

额外优化

  • 移除loadTexture()中未初始化的std::cout<<textureID;,该行会输出垃圾值,无实际意义。
  • 确保每次渲染前都执行完整的纹理绑定逻辑,避免外部工具修改OpenGL状态后导致绑定失效。

内容的提问来源于stack exchange,提问作者I desperatly need help

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 16:55:30