Search code examples
c++qtopengl-es

Is it possible to upload only parts of texture that has changed in OpenGL ES 2.0?


I display a 2D texture in OpenGL using Qt. Most of the texture is the same from frame to frame but a few horizontal lines may have changed.

My first implementation uploaded the whole texture each frame using glTexImage2D.

In my current implementation I call glTexStorage2D in the initializeGL() method. Next I upload only the horizontal lines that have changed using glTexSubImage2D. I found this to be way faster.

Unfortunately I have found out that I need to support running my application via Remote Desktop to a Windows 7 PC. In this case I need to use OpenGL ES 2.0 API (ANGLE).

Is it possible to only upload the horizontal lines that have changed in OpenGL ES 2.0? glTexSubImage2D is present in OpenGL ES 2.0 but without glTexStorage2D it does not seem to work.

EDIT: Florian Winters answer worked fine: I replaced

glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, m_textureWidth, m_textureHeight);

with

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_textureWidth, m_textureHeight, 0, 
GL_RGBA, GL_UNSIGNED_BYTE, nullptr);

in the initialization, initGL(). For each frame, paintGL(), I had to add:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, /*GL_NEAREST*/GL_LINEAR);

After glBindTexture(GL_TEXTURE_2D, m_texName); to get it working.


Solution

  • You need to initialize the texture before you can use glTexSubImage2D to update parts of it. This can be done by calling either glTexStorage2D or glTexImage2D. If glTexStorage2D is not available, use glTexImage2D, as it has been available since very early versions of OpenGL.

    As the documentation of glTexSubImage2D says,

    GL_INVALID_OPERATION is generated if the texture array has not been defined by a previous glTexImage2D operation.