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

OpenGL如何将1D缓存生成2D纹理并加载?代码渲染异常如何解决?

核心问题1:像素缓冲区索引计算错误

RGBA格式下每个像素占4字节,每行1152像素的总字节数为BUFF_WIDTH * 4,你当前的索引计算逻辑完全不符合内存布局:

  • 第一个版本中int32_t ind = y * BUFF_WIDTH + x * 4的写法,相当于每一行仅偏移了1152字节,而实际一行有1152*4=4608字节,导致大部分像素数据都写到了缓冲区前1/4的位置,后续内存都是未初始化的脏数据,自然渲染出来的有效内容尺寸极小,还会重复采样脏数据。
  • 第二个排查版本中x=x+4 + ind = y*BUFF_WIDTH +x的逻辑更是完全错误,相当于每4个像素才写1个像素的颜色,其余都是脏数据。

正确的索引计算应为:
int32_t ind = y * BUFF_WIDTH * 4 + x * 4;


核心问题2:glTexImage2D参数传参顺序错误

glTexImage2D的参数顺序是先宽后高,你当前写的:

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, BUFF_HEIGHT, BUFF_WIDTH, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);

将宽高顺序传反,虽然你当前宽高都是1152暂时没触发问题,但后续宽高不一致时会直接导致图像拉伸变形。正确写法应为:

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, BUFF_WIDTH, BUFF_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);

核心问题3:纹理过滤参数未正确配置

OpenGL默认的纹理缩小过滤参数是GL_NEAREST_MIPMAP_LINEAR,需要生成完整的mipmap链才能正常采样。如果你没有生成mipmap,需要手动将过滤参数改为非mipmap模式,否则纹理采样会失败,出现黑屏或异常渲染结果。在绑定纹理后添加以下代码即可:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

其他小问题

你用new[]分配的数组,释放时应该用delete[] buffer而非delete buffer,否则会出现内存泄漏。


修正后的最简可运行代码

void OpenGLRenderer::renderScreenAlignedQuad(const XrCompositionLayerProjectionView& view)
{
    CHECK_GL_ERROR(glBindVertexArray(m_screenAlignedQuad.vao));
    CHECK_GL_ERROR(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_screenAlignedQuad.indexBuffer));

    // Update texture
    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
    glBindTexture(GL_TEXTURE_2D, m_screenAlignedQuad.texture);
    // 配置纹理参数
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

#define BUFF_HEIGHT 1152
#define BUFF_WIDTH 1152
    unsigned char *buffer = new unsigned char[BUFF_HEIGHT * BUFF_WIDTH * 4];
    for (int32_t y = 0; y < BUFF_HEIGHT; y++) {
        for (int32_t x = 0; x < BUFF_WIDTH; x++) {
            // 修正索引计算
            int32_t ind = y * BUFF_WIDTH * 4 + x * 4;
            buffer[ind] = 255;   // R
            buffer[ind + 1] = 0; // G
            buffer[ind + 2] = 0; // B
            buffer[ind + 3] = 255; // A
        }
    }
    {// =! Critical section !=
        std::shared_lock<std::shared_mutex> sl(m_videoStreamContext.g_currentFrameDataMutex);
        // 修正宽高传参顺序
        CHECK_GL_ERROR(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, BUFF_WIDTH, BUFF_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer));
    }// =! Critical section !=
    delete[] buffer; // 修正数组释放方式

    CHECK_GL_ERROR(glDrawElements(GL_TRIANGLES, m_screenAlignedQuad.indexCount, GL_UNSIGNED_SHORT, 0));
}

内容的提问来源于stack exchange,提问作者Mateusz Sadowski

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 04:36:06