Megatron300 Megatron300 - 4 months ago 40
C++ Question

I'm trying to update a texture with glTexSubImage2D

I started learning OpenGL recently and I've been messing with texture. I updated my texture using

glTexImage2D
but I've learned that it's better to use
glTexSubImage2D
, so I tried to change my code but i doesn't work.

Working code

void GLWidget::updateTextures(){

QImage t = img.mirrored();

glBindTexture(GL_TEXTURE_2D, tex);

glTexImage2D(GL_TEXTURE_2D, 0, 3, t.width(), t.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, t.bits());

glBindTexture( GL_TEXTURE_2D, 0);
}


Not working code

void GLWidget::updateTextures(){

QImage t = img.mirrored();

glBindTexture(GL_TEXTURE_2D, tex);

glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, t.width(), t.height(), GL_RGBA, GL_UNSIGNED_BYTE, t.bits());

glBindTexture( GL_TEXTURE_2D, 0);
}


All I have is a black screen.

Thanks.

EDIT :

Here is the initialization of my texture :

void GLWidget::initializeGL(){

...

LoadGLTextures();

...

}

void GLWidget::LoadGLTextures(){


QImage t = img.mirrored();

glGenTextures(1, &tex);

glBindTexture(GL_TEXTURE_2D, tex);

glTexImage2D(GL_TEXTURE_2D, 0, 3, t.width(), t.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, t.bits());
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

glBindTexture( GL_TEXTURE_2D, 0);

}


img
is a
QImage
variable containing the pixel data.

glGetError()
Returns code 1281.

Answer

glTexSubImage2D updates the content of a previously allocated texture. glTexImage2D has to be called at least once to trigger the allocation:

void GLWidget::initializeGL(){

    //...

    QImage t = img.mirrored();

    glBindTexture(GL_TEXTURE_2D, tex);

    glTexImage2D(
        GL_TEXTURE_2D,
        0,
        3,
        t.width(),
        t.height(),
        0,
        GL_RGBA,
        GL_UNSIGNED_BYTE,
        t.bits()
    );

    glBindTexture( GL_TEXTURE_2D, 0);

    // ...
}

Update with glTexSubImage2D:

void GLWidget::updateTextures(){

    QImage t = img.mirrored();

    glBindTexture(GL_TEXTURE_2D, tex);

    glTexSubImage2D(
        GL_TEXTURE_2D,
        0,
        0,
        0,
        t.width(),
        t.height(),
        GL_RGBA,
        GL_UNSIGNED_BYTE,
        t.bits()
    );

    glBindTexture( GL_TEXTURE_2D, 0);
}

EDIT: the problem was glTexImage2D and glTexSubImage2D were called with different image sizes, generating the error GL_INVALID_VALUE (1281, 0x501) on glTexSubImage2D call.