Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

(OpenGL) How to read back texture buffer?

Is glGetBufferSubData used both for regular and texture buffers ? I am trying to troubleshoot why my texture is not showing up and when I use glGetBufferSubData to read the buffer I get some garbage

struct TypeGLtexture //Associate texture data with a GL buffer
{
    TypeGLbufferID GLbuffer;
    TypeImageFile  ImageFile;

    void GenerateGLbuffer   ()
    {
        if (GLbuffer.isActive==true || ImageFile.GetPixelArray().size()==0) return;
        GLbuffer.isActive=true;
        GLbuffer.isTexture=true;
        GLbuffer.Name="Texture Buffer";
        GLbuffer.ElementCount=ImageFile.GetPixelArray().size();

        glEnable(GL_TEXTURE_2D);
        glGenTextures (1,&GLbuffer.ID);              //instantiate ONE buffer object and return its handle/ID
        glBindTexture (GL_TEXTURE_2D,GLbuffer.ID);   //connect the object to the GL_TEXTURE_2D docking point
        glTexImage2D (GL_TEXTURE_2D,0,GL_RGB,ImageFile.GetProperties().width, ImageFile.GetProperties().height,0,GL_RGB,GL_UNSIGNED_BYTE,&(ImageFile.GetPixelArray()[0]));

if(ImageFile.GetProperties().width==6){
    cout<<"Actual Data"<<endl;
    for (unsigned i=0;i<GLbuffer.ElementCount;i++) cout<<(int)ImageFile.GetPixelArray()[i]<<" ";
    cout<<endl<<endl;

    cout<<"Buffer data"<<endl;
    GLubyte read[GLbuffer.ElementCount]; //Read back from the buffer (to make sure)
    glGetBufferSubData(GL_TEXTURE_2D,0,GLbuffer.ElementCount,read);
    for (unsigned i=0;i<GLbuffer.ElementCount;i++) cout<<(int)read[i]<<" ";
    cout<<endl<<endl;} 
}

enter image description here



EDIT: Using glGetTexImage(GL_TEXTURE_2D,0,GL_RGB,GL_UNSIGNED_BYTE,read);
the data still differs: enter image description here

like image 246
Thomas An Avatar asked Aug 21 '15 21:08

Thomas An


1 Answers

Yes, this would work for texture buffers, if this were in fact one of those.

glGetBufferSubData (...) is for Buffer Objects. What you have here is a Texture Object, and you should actually be getting API errors if you call glGetError (...) to check the error state. This is because GL_TEXTURE_2D is not a buffer target, that is a type of texture object.

It is unfortunate, but you are confusing terminology. Even more unfortunate, there is something literally called a buffer texture (it is a special 1D texture) that allows you to treat a buffer object as a very limited form of texture.

Rather than loosely using the term 'buffer' to think about these things, you should consider "data store." That is the terminology that OpenGL uses to avoid any ambiguity; texture objects have a data store and buffer objects do as well. Unless you create a texture buffer object to link these two things they are separate concepts.

Reading back data from a texture object is much more complicated than this.

Before you can read pixel data from anything in OpenGL, you have to define a pixel format and data type. OpenGL is designed to convert data from a texture's internal format to whatever (compatible) format you request. This is why the function you are actually looking for has the following signature:

void glGetTexImage (GLenum      target,
                    GLint       level,
                    GLenum      format, // GL will convert to this format
                    GLenum      type,   // Using this data type per-pixel
                    GLvoid *    img);

This applies to all types of OpenGL objects that store pixel data. You can, in fact, use a Pixel Buffer Object to transfer pixel data from your texture object into a separate buffer object. You may then use glGetBufferSubData (...) on that Pixel Buffer Object like you were attempting to do originally.

like image 97
Andon M. Coleman Avatar answered Oct 21 '22 23:10

Andon M. Coleman