0
\$\begingroup\$

I've written a very simple OpenGL application. Its goal is to load a texture and draw it on a plane using a PBO. If I use the function 'glTexSubImage2D' the plane is not textured and the function 'glGetError' returns the error '1281' (invalid value). However if I use the function 'glTexImage2D' my plane plane is textured correctly (and I have no error).

Here's the code for the texture loading :

#define OFFSET_BUFFER(offset) ((char*)NULL + offset)

void core::RootDevice::LoadTexture(char const *pFileName)
{
    SDL_Surface *pSurface = IMG_Load(pFileName);
    char *pPixels = reinterpret_cast<char*>(pSurface->pixels);
    uint32_t bytePerPixel = pSurface->format->BitsPerPixel;

    glGenTextures(1, &textureId);
    glBindTexture(GL_TEXTURE_2D, textureId);
    {
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

        glGenBuffers(1, &pboID);
        glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pboID);
        {
            unsigned int bufferSize = pSurface->w * pSurface->h * 3 * sizeof(unsigned char);

            glBufferData(GL_PIXEL_UNPACK_BUFFER, bufferSize, 0, GL_STATIC_DRAW);
            glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, bufferSize, pPixels);

            glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, pSurface->w,                //NOT OK : ERROR 1281
                pSurface->h, GL_RGB, GL_UNSIGNED_BYTE, OFFSET_BUFFER(0));

            /*glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, pSurface->w,               //OK : NO ERROR
                pSurface->h, 0, GL_RGB, GL_UNSIGNED_BYTE, OFFSET_BUFFER(0));*/
        }
        glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
    }
    glBindTexture(GL_TEXTURE_2D, 0);
}

And the rendering code :

void core::RootDevice::Render(void)
{
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, textureId);
    {
        glBegin(GL_QUADS);
            glTexCoord2f(0.0f, 0.0f);
            glVertex3f(-1.0f, -1.0f, 0.0f);
            glTexCoord2f(1.0f, 0.0f);
            glVertex3f(1.0f, -1.0f, 0.0f);
            glTexCoord2f(1.0f, 1.0f);
            glVertex3f(1.0f, 1.0f, 0.0f);
            glTexCoord2f(0.0f, 1.0f);
            glVertex3f(-1.0f, 1.0f, 0.0f);
        glEnd();
    }
    glBindTexture(GL_TEXTURE_2D, 0);
}

And the result is the followings:

enter image description here

I'm really lost. Does anyone can help me, please ?

Thanks a lot in advance for your help.

\$\endgroup\$
7
  • \$\begingroup\$ Your buffer, and the amount of chars you copy is too few. You are missing the fact there are 3 components, each 1 char in size, so you need a '* 3' in there. \$\endgroup\$
    – elFarto
    May 13, 2014 at 11:54
  • \$\begingroup\$ Thank you for this remark. I fixed it. But I still have no texture mapped on my plane. I edited my post. \$\endgroup\$ May 13, 2014 at 12:15
  • \$\begingroup\$ A little detail, not related to your problem: you are using a static_cast to convert the void pointer from SDL to a char pointer, i.e.: char *pPixels = static_cast<char*>(pSurface->pixels); whereas the correct would be a reinterpret_cast. Most compilers wouldn't even let you use a static cast in this case. \$\endgroup\$
    – glampert
    May 13, 2014 at 12:44
  • \$\begingroup\$ I think it might be a memory alignment issue. Please try adding glPixelStorei(GL_UNPACK_ALIGNMENT, 1); to the top of your function, before creating the PBO. Also, take a look at the documentation of glMapBuffer and GL_MIN_MAP_BUFFER_ALIGNMENT to know more about the alignment requirements. opengl.org/sdk/docs/man/docbook4/xhtml/glMapBuffer.xml \$\endgroup\$
    – glampert
    May 13, 2014 at 12:52
  • \$\begingroup\$ Thanks again for your advices :). I fixed the problem (without the glPixelSorei call -> I tried without success) by doing a 'glTexImage2D' call. I have no error with this function. But if I use 'glTexSubImage2D' I have the error '1281'. I know that it corresponds to an invalid value but I don't understand why because the other function works! \$\endgroup\$ May 13, 2014 at 13:37

1 Answer 1

3
\$\begingroup\$

This is expected behaviour.

If you look over your code, you'll see that you're getting a new texture name, binding it, then calling glTexSubImage.

The problem here is that when you call glTexSubImage the texture does not actually exist yet.

Textures are not created by glGenTextures; all that glGenTextures does is give you a free texture object name for use in subsequent calls. The texture doesn't get created ("specified" in OpenGL terminology) until you make the first glTexImage call.

So hence the fact that glTexImage works but glTexSubImage doesn't:

  • glTexImage is actually creating the texture successfully for the first time.
  • glTexSubImage is trying to update a texture that does not exist yet.

Some general comments.

You don't actually need a PBO for this; you'll get the same result by just calling glTexImage directly (it may even be a little faster as you're not going through an intermediate object). PBOs as a rule aren't useful if your usage pattern is to immediately update the texture after updating the PBO.

If all you want to do is create a new texture but not initialize it with any data you can call:

glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB, pSurface->w, pSurface->h, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);

Consider using format GL_BGRA and type GL_UNSIGNED_INT_8_8_8_8_REV for a faster transfer; yes, it's more data but it will more closely match the driver's internal representation and the driver will be more likely to do a direct transfer to the GPU rather than having to do any internal format conversions of it's own. This is, of course, irrelevant if you're just initializing a texture with NULL data.

\$\endgroup\$
1
  • \$\begingroup\$ Ok it's logical :). Thank you very much for all your explanations ! Bye. \$\endgroup\$ May 13, 2014 at 14:54

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .