Fajak
Fajak

Reputation: 51

OpenGL error 'invalid value' when calling glTexSubImage2D

I have a small application that I'm using for testing that is doing some post processing effects. My goal is to read the pixels using double PBO's and then render the pixels to a full screen texture quad and modify/add my effects in a fragment shader. Similar to here. The application is using OSG but I am using openGL calls to do the full screen texturing.

My problem is that when I copy the pixels to the texture each frame using glTexSubImage2D, I get an invalid value openGL error. I have verified with gDEBugger that this is the call generating the errors. The first time the error happens the pointer address is different than in all the subsequent frames. Also, by making the width and height parameters of the glTexSubImage2d 0 the error is not generated. So I'm not really sure what's going.

Here is the relevant code:

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

    }

Upvotes: 1

Views: 5776

Answers (1)

Fajak
Fajak

Reputation: 51

I looked into the state changing in the read() call, however the real problem was with my setupTexturesAndShaders() function being in a different context. I believe this resulted in the glTexSubImage2D being called without having called the glTexImage2D first in the same context which would make any size image be out of range. Thanks for getting me thinking on the right track

Upvotes: 2

Related Questions