2016-12-12 5 views
1

Я пытаюсь сделать некоторые программы GPGPU на устройствах iOS, но я не могу найти какие-либо ресурсы о том, как настроить среду OpenGL ES 3.0. Я понимаю, как делать вычисления в шейдере фрагмента, но я не могу передать свой массив float в единую переменную семплера в шейдер фрагмента.Как передать массив float текстуре в openGL ES?

Это, как я создал 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; 
} 

и мой fragmentshader.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); 
} 

Нет кода ошибки, но я могу видеть только черный экран, и мы ожидаем белый экран из-за того, что я установил значение 1 в памяти процессора. Где я неправ?

+0

Что вы пытаетесь сделать? Вы показываете код настройки для фреймбуфера, но, похоже, вопрос о том, как заставить текстуру работать. Эти две вещи не имеют ничего общего друг с другом. – BDL

+0

@BDL Я пытаюсь ввести данные массива float процессора в свой шейдер фрагмента, но моя настройка не работает. Я показал свой код FBO, потому что он дает мне GL_INCOMPLETE_ATTACHMENT, когда я попытался изменить внутренний формат на GL_R32F, формат на GL_RED и набрать GL_FLOAT. Вышеупомянутые коды работают без каких-либо ошибок, но все же я получаю черный экран на моем устройстве iOS. –

ответ

1

Текстура представляет собой 2D-массив (т. Е. Единый непрерывный блок памяти столбцов и строк). Вы загружаете список 1D массивов, которые хранятся разбросанными по памяти, поскольку каждый из них динамически выделяется отдельно. Не знаю, что вы фактически загружаете здесь, но вам повезло, что это не просто сбой.

Текстуры RGBA8, которые вы пытаетесь загрузить в хранилище 4 отдельных байтовых значения от 0 до 255 на тексель (один для красного, один для синего и т. Д.). Вы пытаетесь загрузить поплавок на пиксель, который, следовательно, полностью неправильный формат данных.

Ваш мундир для «положения» будет постоянным для каждого пикселя, поэтому каждый пиксель будет искать из той же текстурной координаты, что, вероятно, не так, как вы хотели. Вам нужно загрузить свои координаты текстуры как переменное значение для каждого вершины.

Честно говоря, здесь много основополагающих ошибок - я бы посоветовал начать с базового учебника «текстура треугольника» для iOS, в Интернете есть много.

+0

Извините за отсутствие объяснений, но я установил позицию как переменную атрибута, но я забыл ее показать. Это в моем файле c: _aPosition = glGetAttribLocation (_program, "aPosition"); и в моем vsh. : атрибут vec2 aPosition; void main (void) { gl_Position = vec4 (aPosition, 0., 1.); } Я также изменил входные данные CPU в malloc (W * H * sizeof (float)) и внутренний формат для GL_R32F, формат GL_RED и тип GL_FLOAT. Однако я все еще получаю ошибку GL_INCOMPLETE_ATTACHMENT. У вас есть предложения по устранению проблемы? Большое спасибо за ответ! –

+0

Цели рендеринга плавающей точки не являются частью основной спецификации ES 3.0, поэтому может оказаться, что используемый вами графический процессор не поддерживает это. – solidpixel

+0

Обратите внимание, что ваш вопрос говорит только о текстурах, но прикладывает много усилий, чтобы настроить цель рендеринга - они не то же самое. Вы можете прочитать текстуру с плавающей точкой (это ядро ​​в ES3.0), не будучи частью FBO; вы просто не можете сделать в одном. – solidpixel