如何在openGL ES中将float数组传递给纹理?

时间:2016-12-12 09:46:49

标签: ios c opengl-es shader

我正在尝试在iOS设备上进行一些GPGPU编程,但我无法找到有关如何设置openGL ES 3.0环境的任何资源。我理解如何在片段着色器中进行计算但是我无法将我的float数组传递给片段着色器的统一采样器变量。

这是我设置FBO并分配CPU内存的方法:

float** dens = (float**) malloc(W*sizeof(float*));
for (int i = 0; i < W; i++) {
    dens[i] = (float *)malloc(H*sizeof(float));
}

// input value
for (int i = 0; i < W; i++) {
    for (int j = 0; j < H; j++) {
        dens[i][j] = 1.0f;
    }
}

GLuint FBO;
glGenFramebuffers(1, &FBO);
glBindFramebuffer(GL_FRAMEBUFFER, FBO);

GLuint dens_gl = load_texture(W, H, GL_RGBA, 0, dens);

glBindFramebuffer(GL_FRAMEBUFFER, 0);

这是我的load_texture代码:

GLuint load_texture(const GLsizei width, const GLsizei height, const GLenum type, int tex_number, const float** data) {

GLuint texture_object_id;
glGenTextures(1, &texture_object_id);
assert(texture_object_id != 0);
glActiveTexture(GL_TEXTURE0 + tex_number);
glBindTexture(GL_TEXTURE_2D, texture_object_id);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

glTexImage2D(GL_TEXTURE_2D, 0, type, width, height, 0, type, GL_UNSIGNED_BYTE, data);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + tex_number, GL_TEXTURE_2D, texture_object_id, 0);

if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE){
    NSLog(@"failed to make complete framebuffer objects %x", glCheckFramebufferStatus(GL_FRAMEBUFFER));
}

glBindTexture(GL_TEXTURE_2D, 0);

return texture_object_id;
}

和我的fragmenthader.fsh:

uniform vec2 uResolution;
uniform vec2 aPosition;
uniform sampler2D dens_gl;

void main(void) {
vec2 uv = aPosition.xy / uResolution.xy;
gl_FragColor = texture2D(dens_gl, uv);
}

没有错误代码,但我只能看到黑屏,我们期待白屏,因为我在CPU内存中将值设置为1。我哪里出错了?

1 个答案:

答案 0 :(得分:1)

纹理是2D数组(即列和行的单个连续的存储器块)。您正在上传一个1D阵列的列表,这些阵列分散存储在内存中,因为它们分别是动态分配的。不知道你实际上要在这里上传什么,但是你很幸运它不会崩溃。

您尝试上传的RGBA8纹理存储4个单独的字节值,每个纹素在0到255之间(一个用于红色,一个用于蓝色等)。您正在尝试上传每个像素的浮点数,因此它的数据格式完全错误。

对于每个像素,“位置”的均匀性将保持不变,因此每个像素都将从相同的纹理坐标中查找,这可能不是您想要的。您需要将纹理坐标上传为每顶点变化值。

老实说,这里有许多根本性的错误 - 我建议从iOS的基本“纹理三角形”教程开始,网上有很多。