使用glTexStorage2D()

时间:2018-03-03 11:55:38

标签: android opengl-es

我目前在Android上使用OpenGL ES 3.1使用这样的Java绑定分配了一个不可变纹理:

GLES32.glGenTextures(1, velocityMap, 0);
GLES32.glBindTexture(GLES32.GL_TEXTURE_2D, velocityMap[0]); // Bind our texture to target
GLES32.glActiveTexture(GLES32.GL_TEXTURE0); // Use texture unit 0
GLES32.glTexStorage2D(GLES32.GL_TEXTURE_2D, 1, GLES32.GL_RGBA32F, texWidth, texHeight); // Allocate immutable storage

// Set interpolation to nearest
GLES32.glTexParameteri(GLES32.GL_TEXTURE_2D, GLES32.GL_TEXTURE_MAG_FILTER, GLES32.GL_LINEAR);
GLES32.glTexParameteri(GLES32.GL_TEXTURE_2D, GLES32.GL_TEXTURE_MIN_FILTER, GLES32.GL_LINEAR);

///////////////////////////// ADDED THANKS TO SOLIDPIXEL -->
GLES32.glGenFramebuffers(1, fbo, 0);     // Generate an FBO
GLES32.glBindFramebuffer(GLES32.GL_DRAW_FRAMEBUFFER, fbo[0]);   // Bind it to frame buffer target
GLES32.glFramebufferTexture2D(
        GLES32.GL_DRAW_FRAMEBUFFER,
        GLES32.GL_COLOR_ATTACHMENT0,
        GLES32.GL_TEXTURE_2D,
        velocityMap[0], 0);     // Attach texture
int colourBufs[] = {GLES32.GL_COLOR_ATTACHMENT0};
GLES32.glDrawBuffers(1, colourBufs, 0);        // Specify list of colour buffers to draw to
float[] clearColor = {0.0f, 0.0f, 1.0f, 1.0f};      // Set to blue
GLES32.glClearBufferfv(GLES32.GL_COLOR, 0, clearColor, 0);  // Clear buffer

<-- ///////////////////////////// END EDIT

// Get the unit number of image2d variable in shader and bind the immutable texture
texLoc = GLES32.glGetUniformLocation(idComputeShaderProgram, "colourMap");
GLES32.glGetUniformiv(idComputeShaderProgram, texLoc, unit, 0);
GLES32.glBindImageTexture(unit[0], velocityMap[0], 0, false, 0, GLES32.GL_WRITE_ONLY, GLES32.GL_RGBA32F);

在计算着色器中,我使用imageStore()来写入数据:

#version 320 es
#define S_WORKGROUP_SIZE_X      128
#define S_WORKGROUP_SIZE_Y      1
#define S_WORKGROUP_SIZE_Z      1
layout(binding = 0, rgba32f) writeonly uniform lowp image2D colourMap;
layout(local_size_x = S_WORKGROUP_SIZE_X, local_size_y = S_WORKGROUP_SIZE_Y, local_size_z = S_WORKGROUP_SIZE_Z) in;

void main()
{
    imageStore(colourMap, ivec2(gl_GlobalInvocationID.xy), vec4(1.0f, 0.0f, 0.0f, 1.0f));
}

然后一旦完成,我使用一个单独的图形着色器程序,其中uniform 2Dsampler被称为image,以在三角形条上绘制修改后的纹理。初始化为:

GLES32.glUseProgram(idGraphicsShaderProgram);
GLES32.glBindTexture(GLES31.GL_TEXTURE_2D, velocityMap[0]);
GLES32.glUniform1i(GLES31.glGetUniformLocation(idGraphicsShaderProgram, "image"), 0); // Use texture unit 0

这在render方法中执行:

GLES32.glUseProgram(idGraphicsShaderProgram);
GLES32.glBindTexture(GLES31.GL_TEXTURE_2D, velocityMap[0]);
GLES32.glClear(GLES31.GL_COLOR_BUFFER_BIT);
GLES32.glBindVertexArray(vao[0]);
GLES32.glDrawArrays(GLES31.GL_TRIANGLE_STRIP, 0, 4);

我目前看到黑色纹理,这表明没有数据显示。如果我修改片段着色器以输出平面颜色,那么工作正常,所以我相信图形着色器工作正常。

为了帮助调试,我想初始化我分配为填充蓝色纹理的纹理,以隔离问题是图形着色器读取纹理还是计算着色器修改纹理,但我不知道如何一旦我用glTexStorage2D()分配数据,我就可以将数据缓冲到纹理 - 我在桌面上使用glTexImage2D(),因为没有像GLES中那样的不可变存储限制,我可以直接缓冲数据。如何用来自客户端的数据填充不可变纹理?

更新
实施solidpixel的原始建议后,我仍然看不到任何纹理。这个最小代码中还有其他什么东西显然不正确吗?

1 个答案:

答案 0 :(得分:0)

创建一个framebuffer对象,将纹理作为附件附加,并使用“glClear”将其设置为常量颜色。