(OpenGL) 如何读回纹理缓冲区?

(OpenGL) How to read back texture buffer?

glGetBufferSubData 是否同时用于常规缓冲区和纹理缓冲区? 我正在尝试解决为什么我的纹理没有显示以及当我使用 glGetBufferSubData 读取缓冲区时我得到一些垃圾

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



编辑: 使用 glGetTexImage(GL_TEXTURE_2D,0,GL_RGB,GL_UNSIGNED_BYTE,read);
数据仍然不同:

是的,这适用于纹理缓冲区,如果这实际上是其中之一的话。

glGetBufferSubData (...) 用于 Buffer Objects. What you have here is a Texture Object,如果您调用 glGetError (...) 检查错误状态,您实际上应该得到 API 错误。这是因为 GL_TEXTURE_2D 不是缓冲目标,它是一种纹理对象。

不幸的是,您混淆了术语。更不幸的是,有一种字面上称为 buffer texture 的东西(它是一种特殊的一维纹理),它允许您将缓冲区对象视为一种非常有限的纹理形式。

与其松散地使用术语 'buffer' 来考虑这些事情,您应该考虑“数据存储”。这是 OpenGL 用来避免歧义的术语;纹理对象有数据存储,缓冲区对象也有。除非你为 link 创建纹理缓冲区对象,否则这两个东西是不同的概念。

从纹理对象中读回数据比这复杂得多。

在您可以从 OpenGL 中的任何内容读取像素数据之前,您必须定义像素格式和数据类型。 OpenGL 旨在将数据从纹理的内部格式转换为您请求的任何(兼容)格式。这就是为什么您实际要查找的函数具有以下签名:

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

这适用于存储像素数据的所有类型的 OpenGL 对象。实际上,您可以使用 Pixel Buffer Object 将纹理对象中的 像素数据传输到单独的缓冲区对象中。然后,您可以像最初尝试那样在该像素缓冲区对象上使用 glGetBufferSubData (...)