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

时间:2015-08-21 21:29:16

标签: opengl textures

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

documentation



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

1 个答案:

答案 0 :(得分:5)

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

glGetBufferSubData (...)适用于Buffer Objects。你在这里有一个Texture Object,如果你调用glGetError (...)来检查错误状态,你实际上应该会遇到API错误。这是因为GL_TEXTURE_2D不是缓冲区目标,这是一种纹理对象。

很遗憾,但你的术语令人困惑。更不幸的是,有一些字面上称为buffer texture(它是一种特殊的一维纹理),允许您将缓冲对象视为非常有限的纹理形式。

您应该考虑“数据存储”,而不是松散地使用术语“缓冲区”来考虑这些事情。这是OpenGL用来避免任何歧义的术语;纹理对象也有数据存储和缓冲对象。除非你创建一个纹理缓冲区对象来链接这两个东西,否则它们就是不同的概念。

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

在从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 (...)