【问题标题】:OpenGL error 'invalid value' when calling glTexSubImage2D调用 glTexSubImage2D 时 OpenGL 错误“无效值”
【发布时间】:2012-02-02 20:35:27
【问题描述】:

我有一个用于测试的小型应用程序正在执行一些后期处理效果。我的目标是使用双 PBO 读取像素,然后将像素渲染到全屏纹理四边形,并在片段着色器中修改/添加我的效果。类似于here。该应用程序正在使用 OSG,但我正在使用 openGL 调用来进行全屏纹理处理。

我的问题是,当我使用 glTexSubImage2D 将像素复制到每一帧的纹理时,我得到一个无效值 openGL 错误。我已经用 gDEBugger 验证了这是生成错误的调用。第一次发生错误时,指针地址与所有后续帧中的地址不同。此外,通过将 glTexSubImage2d 的宽度和高度参数设为 0,不会产生错误。所以我不太确定发生了什么。

以下是相关代码:

MyCallbackClass()
{
    pImgData = (unsigned char*) malloc(1024*512*3);
    setupTextureAndShaders();
}
void setupTextureAndShaders()
{
    glGenTextures(1, &screenTexture);
    glBindTexture(GL_TEXTURE_2D, screenTexture);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

    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);

    memset(pImgData, 0, 1024*512*3);

    glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB, 1024, 512, 0, GL_RGB, GL_UNSIGNED_BYTE, pImgData);
    glBindTexture(GL_TEXTURE_2D, 0);
}


//callback called every frame
virtual void operator () (osg::RenderInfo& renderInfo) const
{
    // buffer and context stuff unchanged from the sample program

    if(!shaderInit) // only executed once
    {
        GLuint vs = glCreateShader(GL_VERTEX_SHADER);
        const GLchar* vs_source = shaderLoadFile("vert.glsl");

        glShaderSource(vs, 1, &vs_source, NULL);
        glCompileShader(vs);
        checkShader(&vs);

        GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
        const GLchar* fs_source = shaderLoadFile("frag.glsl");

        glShaderSource(fs, 1, &fs_source, NULL);
        glCompileShader(fs);
        checkShader(&fs);

        prog = glCreateProgram();

        glAttachShader(prog, vs);
        glAttachShader(prog, fs);

        glLinkProgram(prog);
        texLoc = glGetUniformLocation(prog, "screenTex");

        shaderInit = true;
    }

    read();  // does the double pbo operations to read the image data into pImgData

    glUseProgram(prog);

    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity();
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    glLoadIdentity();

    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, screenTexture);
    glUniform1i(texLoc, 0);
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1024, 512, GL_RGB, GL_UNSIGNED_BYTE, pImgData);

    glBegin(GL_QUADS);
        glTexCoord2f(0, 1);
        glVertex2f(-1,-1);
        glTexCoord2f(0, 0);
        glVertex2f(-1,1);
        glTexCoord2f(1,0);
        glVertex2f(1,1);
        glTexCoord2f(1,1);
        glVertex2f(1,-1);
    glEnd();

    glDisable(GL_TEXTURE_2D);

    glMatrixMode (GL_MODELVIEW);
    glPopMatrix();
    glMatrixMode (GL_PROJECTION);
    glPopMatrix ();
    glMatrixMode (GL_MODELVIEW);


    glUseProgram(0);

    }

【问题讨论】:

  • read() 函数有什么作用?产生您列出的错误的原因是将 mip-map 级别设置为低于 0 或高于最大值,而您没有这样做,或者宽度和/或高度为负数或超出图像边界,这是不是你的情况。因此,也许您的 pbo 操作已将状态设置为与您期望的不同? (顺便说一句,你可能应该从 PBO 切换到 FBO,因为 PBO 已被弃用。)
  • PBO 未被弃用,并且仍然存在于最新的 OpenGL 4.x 规范中
  • 不推荐使用 3.3 核心中的任何内容

标签: c++ opengl texturing glteximage2d


【解决方案1】:

我查看了 read() 调用中的状态变化,但真正的问题是我的 setupTexturesAndShaders() 函数处于不同的上下文中。我相信这会导致 glTexSubImage2D 被调用,而没有在相同的上下文中首先调用 glTexImage2D,这会使任何大小的图像超出范围。感谢您让我走上正轨

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-10
    • 1970-01-01
    • 2015-09-28
    • 1970-01-01
    相关资源
    最近更新 更多