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

OpenGL 1.1纹理透显窗口背景问题的解决求助

解决OpenGL 1.1中纹理透显窗口背景的方法

我在使用OpenGL 1.1(用到glEnableClientState、glMatrixMode、glTexCoordPointer等废弃函数)时遇到问题:纹理会透显窗口背景。以下是相关验证信息与代码,给出可行的解决方法:

问题验证

通过修改glClearColor的颜色值,确认纹理存在alpha通道导致透显:

  • 设置glClearColor(1.f, 0.f, 0.f, 1.f);时的效果:
    红色背景下的纹理透显
  • 设置glClearColor(0.2f, 0.5f, 0.3f, 1.f);时的效果:
    绿色背景下的纹理透显

使用的纹理:
角色纹理
背景纹理

当前代码实现

绘制逻辑(启用深度测试)

glEnable(GL_DEPTH_TEST);

/* ... */

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// 绘制玩家
glBindTexture(GL_TEXTURE_2D, spriteTexture);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(playerBody->GetPosition().x * WORLD_SCALE,
                playerBody->GetPosition().y * WORLD_SCALE, 10.f);
glScalef(16.f, 16.f, 1.f);
glDrawArrays(GL_TRIANGLE_STRIP, drawingIndex, 4);

// 绘制金币
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(178.f, 120.f, 10.f);
glScalef(16.f, 16.f, 1.f);
glDrawArrays(GL_TRIANGLE_STRIP, 24, 4);

// 绘制敌人
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(194.f, 184.f, 10.f);
glScalef(16.f, 16.f, 1.f);
glDrawArrays(GL_TRIANGLE_STRIP, 20, 4);

// 绘制背景
glBindTexture(GL_TEXTURE_2D, backgroundTexture);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.f, 0.f, 0.f);
glScalef(256.f, 216.f, 1.f);
glDrawArrays(GL_TRIANGLE_STRIP, 16, 4);

glfwSwapBuffers(window);

初始化设置

glEnable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_TEXTURE_2D);

纹理创建函数

GLuint createTexture(char *path)
{
    int h_image, w_image, cnt;

    unsigned char *data = stbi_load(path, &w_image, &h_image, &cnt, 0);

    if (data == NULL)
    {
        cout << "Failed to load an image" << endl;
        glfwTerminate();
        exit(-1);
    }

    GLuint texture;
    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);
    {
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w_image, h_image, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
    }
    glBindTexture(GL_TEXTURE_2D, 0);

    stbi_image_free(data);

    return texture;
}

可行解决方法

  • 调整绘制顺序:将背景绘制放在最开始(先绘制背景,再绘制玩家、金币、敌人)。背景的z值设为0,其他物体z值大于0,这样背景会先填充整个屏幕,后续物体绘制在背景之上,不会透出窗口背景。
  • 绘制背景时关闭深度测试:绘制背景前调用glDisable(GL_DEPTH_TEST);,绘制完成后再调用glEnable(GL_DEPTH_TEST);。这样背景会强制覆盖整个屏幕,不受之前深度缓冲数据的影响。
  • 移除不必要的alpha通道:如果不需要纹理透明,修改纹理创建逻辑:加载图片时指定cnt=3强制获取RGB格式,同时将glTexImage2D的内部格式和格式改为GL_RGB,忽略alpha通道。
  • 按需启用混合模式:仅在绘制需要透明的物体(玩家、金币、敌人)时启用GL_BLEND,绘制背景时调用glDisable(GL_BLEND);,避免背景被混合处理。
  • 确认深度缓冲存在:检查GLFW窗口创建时是否请求了深度缓冲,添加glfwWindowHint(GLFW_DEPTH_BITS, 24);确保深度缓冲正常工作,否则GL_DEPTH_TEST会失效。

内容的提问来源于stack exchange,提问作者8Observer8

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 15:40:23