Java opengl:glGetTexImage用于2d纹理和1d纹理数组

Java opengl:glGetTexImage用于2d纹理和1d纹理数组,java,opengl,textures,Java,Opengl,Textures,对于texture2D,我提取mipmap的纹理,如下所示 pixels=ByteBuffer.allocateDirect(4*width*height); GL11.glGetTexImage( GL11.GL_TEXTURE_2D,mipMap ,GL11.GL_RGB,GL11.GL_UNSIGNED_BYTE ,pixels

对于texture2D,我提取mipmap的纹理,如下所示

pixels=ByteBuffer.allocateDirect(4*width*height);
    
GL11.glGetTexImage(
                    GL11.GL_TEXTURE_2D,mipMap
                   ,GL11.GL_RGB,GL11.GL_UNSIGNED_BYTE
                   ,pixels
                  );
GL11.glPixelStorei(GL11.GL_UNPACK_ALIGNMENT,4); //4 bytes since RGBA bytes were read from texture

GL11.glTexImage2D(GL11.GL_TEXTURE_2D,0
                 ,GL11.GL_RGB,width,height,0
                 ,GL11.GL_RGB,GL11.GL_UNSIGNED_BYTE,pixels);
pixels=ByteBuffer.allocateDirect(4*image.width*layers); //again creating RGBA byte buffer because thats the default behaviour

GL11.glGetTexImage(                                     //this will return the texture images of all layers of mipmap level 0
                   GL30.GL_TEXTURE_1D_ARRAY,0
                  ,GL11.GL_RGB,GL11.GL_UNSIGNED_BYTE
                  ,pixels
                 );

ByteBuffer levelN=ByteBuffer.allocateDirect(4*image.width);

int offset=4*image.width*level;                         //level is layer 0,layer 1 so on this part reads only the texels of an specific layer
for(int i=offset;i<offset+(image.width*4);i++){levelN.put(pixels.get(i));}

pixels=levelN;
ByteBuffer[] layers=//read using above method

 GL11.glPixelStorei(GL11.GL_UNPACK_ALIGNMENT,4); //4 bytes since RGBA bytes were read from texture

GL11.glTexImage2D(GL30.GL_TEXTURE_1D_ARRAY,0                                //allocate enough storage for all layers
                 ,GL11.GL_RGB,width,layers.length,0
                 ,GL11.GL_RGB,GL11.GL_UNSIGNED_BYTE,(ByteBuffer)null);



for(int layer=0;i<layers.length;layer++)
{
 ByteBuffer image=layers[i];
 
 GL11.glTexSubImage2D(GL30.GL_TEXTURE_1D_ARRAY,0                              //Update individual layers using texSubImage
                      ,0,layer,width,1
                      ,GL11.GL_RGB,GL11.GL_UNSIGNED_BYTE,image);
}
根据文档,如果纹理不是4个组件,它将每像素写入4个字节,将所需组件设置为零

稍后,我可以使用如下像素创建2D纹理

pixels=ByteBuffer.allocateDirect(4*width*height);
    
GL11.glGetTexImage(
                    GL11.GL_TEXTURE_2D,mipMap
                   ,GL11.GL_RGB,GL11.GL_UNSIGNED_BYTE
                   ,pixels
                  );
GL11.glPixelStorei(GL11.GL_UNPACK_ALIGNMENT,4); //4 bytes since RGBA bytes were read from texture

GL11.glTexImage2D(GL11.GL_TEXTURE_2D,0
                 ,GL11.GL_RGB,width,height,0
                 ,GL11.GL_RGB,GL11.GL_UNSIGNED_BYTE,pixels);
pixels=ByteBuffer.allocateDirect(4*image.width*layers); //again creating RGBA byte buffer because thats the default behaviour

GL11.glGetTexImage(                                     //this will return the texture images of all layers of mipmap level 0
                   GL30.GL_TEXTURE_1D_ARRAY,0
                  ,GL11.GL_RGB,GL11.GL_UNSIGNED_BYTE
                  ,pixels
                 );

ByteBuffer levelN=ByteBuffer.allocateDirect(4*image.width);

int offset=4*image.width*level;                         //level is layer 0,layer 1 so on this part reads only the texels of an specific layer
for(int i=offset;i<offset+(image.width*4);i++){levelN.put(pixels.get(i));}

pixels=levelN;
ByteBuffer[] layers=//read using above method

 GL11.glPixelStorei(GL11.GL_UNPACK_ALIGNMENT,4); //4 bytes since RGBA bytes were read from texture

GL11.glTexImage2D(GL30.GL_TEXTURE_1D_ARRAY,0                                //allocate enough storage for all layers
                 ,GL11.GL_RGB,width,layers.length,0
                 ,GL11.GL_RGB,GL11.GL_UNSIGNED_BYTE,(ByteBuffer)null);



for(int layer=0;i<layers.length;layer++)
{
 ByteBuffer image=layers[i];
 
 GL11.glTexSubImage2D(GL30.GL_TEXTURE_1D_ARRAY,0                              //Update individual layers using texSubImage
                      ,0,layer,width,1
                      ,GL11.GL_RGB,GL11.GL_UNSIGNED_BYTE,image);
}
所以这对2D纹理非常有效

现在跳到纹理1D阵列,我读取特定mipmap所有层的图像,如下所示

pixels=ByteBuffer.allocateDirect(4*width*height);
    
GL11.glGetTexImage(
                    GL11.GL_TEXTURE_2D,mipMap
                   ,GL11.GL_RGB,GL11.GL_UNSIGNED_BYTE
                   ,pixels
                  );
GL11.glPixelStorei(GL11.GL_UNPACK_ALIGNMENT,4); //4 bytes since RGBA bytes were read from texture

GL11.glTexImage2D(GL11.GL_TEXTURE_2D,0
                 ,GL11.GL_RGB,width,height,0
                 ,GL11.GL_RGB,GL11.GL_UNSIGNED_BYTE,pixels);
pixels=ByteBuffer.allocateDirect(4*image.width*layers); //again creating RGBA byte buffer because thats the default behaviour

GL11.glGetTexImage(                                     //this will return the texture images of all layers of mipmap level 0
                   GL30.GL_TEXTURE_1D_ARRAY,0
                  ,GL11.GL_RGB,GL11.GL_UNSIGNED_BYTE
                  ,pixels
                 );

ByteBuffer levelN=ByteBuffer.allocateDirect(4*image.width);

int offset=4*image.width*level;                         //level is layer 0,layer 1 so on this part reads only the texels of an specific layer
for(int i=offset;i<offset+(image.width*4);i++){levelN.put(pixels.get(i));}

pixels=levelN;
ByteBuffer[] layers=//read using above method

 GL11.glPixelStorei(GL11.GL_UNPACK_ALIGNMENT,4); //4 bytes since RGBA bytes were read from texture

GL11.glTexImage2D(GL30.GL_TEXTURE_1D_ARRAY,0                                //allocate enough storage for all layers
                 ,GL11.GL_RGB,width,layers.length,0
                 ,GL11.GL_RGB,GL11.GL_UNSIGNED_BYTE,(ByteBuffer)null);



for(int layer=0;i<layers.length;layer++)
{
 ByteBuffer image=layers[i];
 
 GL11.glTexSubImage2D(GL30.GL_TEXTURE_1D_ARRAY,0                              //Update individual layers using texSubImage
                      ,0,layer,width,1
                      ,GL11.GL_RGB,GL11.GL_UNSIGNED_BYTE,image);
}
pixels=ByteBuffer.allocateDirect(4*image.width*layers)//再次创建RGBA字节缓冲区,因为这是默认行为
GL11.glGetTexImage(//这将返回mipmap级别0的所有层的纹理图像
GL30.GL_纹理_1D_数组,0
,GL11.GL_RGB,GL11.GL_无符号字节
,像素
);
ByteBuffer levelN=ByteBuffer.allocateDirect(4*image.width);
int offset=4*图像宽度*级别//级别是第0层,第1层,因此此部分仅读取特定层的texel
对于(int i=偏移量;i
根据文档,它每像素写入4字节[…]

不,不是。每像素读取3个字节。行的长度对齐为4个字节(如果
GL\u PACK\u ALIGNMENT
为4)。

glGetTexImage
的参数格式和_类型不指定源纹理的格式,而是指定目标缓冲区的格式。

*“根据文档,它每像素写入4个字节”-不指定。
glGetTexImage(…GL\u RGB,GL\u UNSIGNED\u BYTE…)
每像素读取3个字节。行的长度对齐为4个字节(如果
GL\u PACK\u ALIGNMENT
为4)。但是,如果纹理是RGB格式,它会将alpha填充为零。即使如此,为什么即使是RGB纹理,4个字节也适用于我的tex2D?它说:“如果选定的纹理图像不包含四个组件[…]“。这意味着,如果尝试将RGB纹理读取到RGBA目标缓冲区,则alpha通道将设置为255。
glGetTexImage
的参数不指定源纹理的格式,但指定目标缓冲区的格式。我看到了,但我为我的1D纹理数组指定了unpack allignment为4。”[忘了在我的问题中包括]它什么也没做。我的缓冲区是RGBA,我的allignment现在也是4,但这并没有解决任何问题。无论如何,我明天会尝试更多地使用缓冲区,并在我的问题中编辑结果。谢谢你,我会尝试一下,让你知道。我只使用了UNPACK allignment,但没有使用PACK allignment。也许这就是我要看的g代表。是的,你又对了。正如我需要为使用glTexImage2D创建纹理指定unpack allignment一样,我需要指定pack allignment从纹理中读取相同的像素,并且当我为我的texture2D和1DArray指定pack allignment为1时,我只需使用3个组件就可以正确读取这两个纹理中的像素bytebuffer。在我结束之前,有没有一种方法可以使用纹理的宽度和每像素的numOfComponents来破译纹理的对齐方式,而不是指定1,因为我听说读取以前的线程会影响性能?@Syncit您无法指定每像素的对齐方式。像素的大小仅取决于目标格式和类型。我明白,不管怎样,我为RGB指定对齐1,为RGBA纹理指定对齐4,这似乎适用于大多数一般情况。这就是我要问的所有问题,再次感谢