rgba数组到OpenGL纹理

rgba数组到OpenGL纹理,opengl,textures,lwjgl,Opengl,Textures,Lwjgl,对于游戏的gui,我有一个自定义纹理对象,用于存储纹理的rgba数据。我的游戏注册的每个GUI元素都会添加到最终的GUI纹理中,然后在后期处理后,该纹理会覆盖到帧缓冲区上 我无法将纹理对象转换为openGL纹理 首先,我创建了一个1D整数数组,该数组是rgbargba。。。等等。 public int[] toIntArray(){ int[] colors = new int[(width*height)*4]; int i = 0; for(int y = 0; y

对于游戏的gui,我有一个自定义纹理对象,用于存储纹理的rgba数据。我的游戏注册的每个GUI元素都会添加到最终的GUI纹理中,然后在后期处理后,该纹理会覆盖到帧缓冲区上

我无法将纹理对象转换为openGL纹理

首先,我创建了一个1D整数数组,该数组是
rgbargba。。。等等。

public int[] toIntArray(){
    int[] colors = new int[(width*height)*4];

    int i = 0;
    for(int y = 0; y < height; ++y){
        for(int x = 0; x < width; ++x){

            colors[i] = r[x][y];
            colors[i+1] = g[x][y];
            colors[i+2] = b[x][y];
            colors[i+3] = a[x][y];

            i += 4;
        }
    }
    return colors;
}
之后,我在纹理的左上角添加一个50x50的红方块,将纹理绑定到帧缓冲区着色器,并渲染显示帧缓冲区的全屏矩形

frameBuffer.unbind(window.getWidth(), window.getHeight());

postShaderProgram.bind();

glEnable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, guiManager.texture()); // this gets the texture id that was created

postShaderProgram.setUniform("gui_texture", 1);

mesh.render();

postShaderProgram.unbind();
然后在片段着色器中,我尝试显示GUI:

#version 330

in  vec2 Texcoord;
out vec4 outColor;

uniform sampler2D texFramebuffer;
uniform sampler2D gui_texture;

void main()
{
    outColor = texture(gui_texture, Texcoord);
}
但它输出的只是一个黑色的窗口

我在左上角添加了一个红色的50x50矩形,并验证了它是否存在,但由于某些原因,它没有显示在最终输出中

这让我有理由相信,我没有正确地使用
glTexImage2D
将纹理转换为opengl纹理

你能看出我做错了什么吗

更新1:

我看到他们使用浮点数组做了类似的事情,所以我尝试将我的0-255转换为0-1浮点数组,并将其作为图像数据传递,如下所示:

public float[] toFloatArray(){
    float[] colors = new float[(width*height)*4];

    int i = 0;
    for(int y = 0; y < height; ++y){
        for(int x = 0; x < width; ++x){

            colors[i] = (( r[x][y] * 1.0f) / 255);
            colors[i+1] = (( g[x][y] * 1.0f) / 255);
            colors[i+2] = (( b[x][y] * 1.0f) / 255);
            colors[i+3] = (( a[x][y] * 1.0f) / 255);

            i += 4;
        }
    }
    return colors;
}

...

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_FLOAT, toFloatArray());
public float[]toFloatArray(){
浮动[]颜色=新浮动[(宽度*高度)*4];
int i=0;
对于(int y=0;y
而且它有效


但是,我想知道int缓冲区不工作的原因,所以我将保留这个问题:)

当您指定
GL\u UNSIGNED\u int
作为“主机”数据的类型时,OpenGL希望为每种颜色分配32位。由于OpenGL仅将默认帧缓冲区中的输出颜色映射到范围
[0.0f,1.0f]
,因此它将获取您的输入颜色值(映射到范围
[0,255]
)并将所有颜色除以整数的最大大小(约42亿),以获得屏幕上显示的最终颜色。作为练习,使用原始代码,将屏幕的“清除”颜色设置为白色,并查看屏幕上是否绘制了黑色矩形

你有两个选择。第一种方法是将颜色值转换为
GL\u UNSIGNED\u INT
指定的范围,这意味着对于每个颜色值,将它们乘以
Math.pow((long)2,24)
,并相信乘以该值的整数溢出将正常运行(因为Java没有无符号整数类型)


另一个更安全的选择是将每个0-255值存储在
byte[]
对象中(donotuse
char
char
在C/C++/OpenGL中是1个字节,但在Java中是2个字节)并将元素的类型指定为
GL\u UNSIGNED\u BYTE

当您将
GL\u UNSIGNED\u INT
指定为“主机”数据的类型时,OpenGL希望为每种颜色分配32位。由于OpenGL仅将默认帧缓冲区中的输出颜色映射到范围
[0.0f,1.0f]
,因此它将获取您的输入颜色值(映射到范围
[0,255]
)并将所有颜色除以整数的最大大小(约42亿),以获得屏幕上显示的最终颜色。作为练习,使用原始代码,将屏幕的“清除”颜色设置为白色,并查看屏幕上是否绘制了黑色矩形

你有两个选择。第一种方法是将颜色值转换为
GL\u UNSIGNED\u INT
指定的范围,这意味着对于每个颜色值,将它们乘以
Math.pow((long)2,24)
,并相信乘以该值的整数溢出将正常运行(因为Java没有无符号整数类型)


另一个更安全的选择是将每个0-255值存储在
byte[]
对象中(donotuse
char
char
在C/C++/OpenGL中是1个字节,但在Java中是2个字节),并将元素的类型指定为
GL\u UNSIGNED\u byte

更正:OpenGL类型称为GL\u UNSIGNED\u byte,未签名_CHAR@AntonReshetnikov已编辑。更正:OpenGL类型称为GL_UNSIGNED_BYTE,而不是GL_UNSIGNED_CHAR@AntonReshetnikov编辑。
public float[] toFloatArray(){
    float[] colors = new float[(width*height)*4];

    int i = 0;
    for(int y = 0; y < height; ++y){
        for(int x = 0; x < width; ++x){

            colors[i] = (( r[x][y] * 1.0f) / 255);
            colors[i+1] = (( g[x][y] * 1.0f) / 255);
            colors[i+2] = (( b[x][y] * 1.0f) / 255);
            colors[i+3] = (( a[x][y] * 1.0f) / 255);

            i += 4;
        }
    }
    return colors;
}

...

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_FLOAT, toFloatArray());