簡體   English   中英

rgba數組到OpenGL紋理

[英]rgba arrays to OpenGL texture

對於游戲的gui,我有一個自定義紋理對象,用於存儲紋理的rgba數據。 我的游戲注冊的每個GUI元素都會添加到最終的GUI紋理,然后在后期處理之后將該紋理覆蓋到幀緩沖區上。

我無法將我的Texture對象轉換為openGL紋理。

首先,我創建一個一維的int數組,該數組rgbargbargba... etc.

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

其中rgba是從0到255的鋸齒狀int數組。接下來,我創建int緩沖區和紋理。

id = glGenTextures();

glBindTexture(GL_TEXTURE_2D, id);

glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

IntBuffer iBuffer = BufferUtils.createIntBuffer(((width * height)*4));

int[] data = toIntArray();
iBuffer.put(data);
iBuffer.rewind();

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_INT, iBuffer);

glBindTexture(GL_TEXTURE_2D, 0);

之后,我在紋理的左上方添加一個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());

而且有效!

在此處輸入圖片說明

我想讓問題懸而未決,因為我想了解為什么int緩沖區不起作用:)

當您將GL_UNSIGNED_INT指定為“主機”數據的類型時,OpenGL期望為每種顏色分配32位。 由於OpenGL僅將默認幀緩沖區中的輸出顏色映射到[0.0f, 1.0f]范圍,因此它將采用您的輸入顏色值(映射在[0, 255]范圍內)並將它們全部除以最大大小。整數(約42億)以獲得最終的顏色顯示在屏幕上。 作為練習,使用您的原始代碼,將屏幕的“透明”顏色設置為白色,然后看到屏幕上繪制了黑色矩形。

您有兩個選擇。 第一種是將顏色值轉換為GL_UNSIGNED_INT指定的范圍,這意味着對於每個顏色值,將它們乘以Math.pow((long)2, 24) ,並相信乘以該值的整數溢出將表現正確(因為Java沒有無符號整數類型)。

另一方面,遠更安全的選擇,是在每個0-255值存儲在一個byte[]對象( 使用charchar是在C / C ++ / OpenGL的1個字節,但為2個字節在Java中),並指定的類型元素為GL_UNSIGNED_BYTE

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM