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;}
}
Run Code Online (Sandbox Code Playgroud)
编辑:使用glGetTexImage(GL_TEXTURE_2D,0,GL_RGB,GL_UNSIGNED_BYTE,read);
数据仍然不同:
glGetBufferSubData (...)
用于缓冲对象.你在这里有一个纹理对象,如果你打电话glGetError (...)
检查错误状态,你实际上应该得到API错误.这是因为GL_TEXTURE_2D
它不是缓冲区目标,即一种纹理对象.
这很不幸,但你的术语令人困惑.更不幸的是,有一种字面上称为缓冲区纹理(它是一种特殊的一维纹理),它允许您将缓冲区对象视为非常有限的纹理形式.
您应该考虑"数据存储",而不是松散地使用术语"缓冲区"来考虑这些事情.这是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);
Run Code Online (Sandbox Code Playgroud)
这适用于存储像素数据的所有类型的OpenGL对象.实际上,您可以使用像素缓冲区对象将纹理对象中的像素数据传输到单独的缓冲区对象中.然后glGetBufferSubData (...)
,您可以使用该像素缓冲区对象,就像您最初尝试的那样.