2016-12-12 3 views
1

Ich versuche, einige GPGPU-Programmierung auf iOS-Geräten zu tun, aber ich kann keine Ressourcen zum Einrichten der OpenGL ES 3.0-Umgebung finden. Ich verstehe, wie Berechnungen im Fragment-Shader durchgeführt werden, aber ich kann mein Float-Array nicht an eine einheitliche Sampler-Variable an den Fragment-Shader übergeben.Wie Übergeben Float-Array zu Textur in OpenGL ES?

Dies ist, wie ich das FBO einrichten und CPU-Speicher zuteilen:

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

Hier ist mein Code für load_texture ist:

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

und meine 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); 
} 

Es gibt keinen Fehlercode, aber ich sehe nur einen schwarzen Bildschirm und wir erwarten einen weißen Bildschirm, weil ich den Wert auf 1 gesetzt habe im CPU-Speicher. Was habe ich falsch gemacht?

+0

Was versuchen Sie zu tun? Sie zeigen den Setup-Code für einen Framebuffer, aber die Frage scheint zu sein, wie man eine Textur zum Laufen bringt. Diese beiden Dinge haben nichts miteinander zu tun. – BDL

+0

@BDL Ich versuche, die CPU-Float-Array-Daten in meinen Fragment-Shader einzugeben, aber mein Setup funktioniert nicht. Ich habe meinen FBO-Code angezeigt, weil er GL_INCOMPLETE_ATTACHMENT enthält, als ich versuchte, das interne Format in GL_R32F zu ändern, nach GL_RED zu formatieren und nach GL_FLOAT zu schreiben. Die obigen Codes funktionieren ohne Fehler, aber trotzdem bekomme ich einen schwarzen Bildschirm auf meinem iOS-Gerät. –

Antwort

1

Eine Textur ist ein 2D-Array (d. H. Ein einzelner zusammenhängender Speicherblock für Spalten und Zeilen). Sie laden eine Liste von 1D-Arrays hoch, die verstreut im Arbeitsspeicher gespeichert sind, da sie jeweils einzeln dynamisch zugewiesen werden. Keine Ahnung, was du hier eigentlich hochladen kannst, aber du hast Glück, dass es nicht einfach abstürzt.

Die RGBA8-Texturen, die Sie hochladen möchten, speichern 4 separate Bytewerte zwischen 0 und 255 pro Texel (eins für Rot, eins für Blau usw.). Sie versuchen, einen Gleitkommawert pro Pixel hochzuladen, der daher in einem völlig falschen Datenformat vorliegt.

Ihre Uniform für "Position" wird für jedes Pixel konstant sein, also wird jedes Pixel von der gleichen Texturkoordinate nachsehen, was wahrscheinlich nicht das ist, was Sie wollten. Sie müssen Ihre Texturkoordinaten als per-vertex variierende Werte hochladen.

Ehrlich gesagt gibt es hier viele grundlegende Fehler - ich würde vorschlagen, mit einem grundlegenden Tutorial "Textur ein Dreieck" für iOS zu beginnen, gibt es viele im Web.

+0

Sorry für meinen Mangel an Erklärungen, aber ich habe Position als Attributvariable gesetzt, aber ich habe vergessen, es zu zeigen. Dies ist in meiner c-Datei: _aPosition = glGetAttribLocation (_program, "aPosition"); und in meinem vsh. : Attribut vec2 aPosition; void main (void) { gl_Position = vec4 (aPosition, 0., 1.); } Ich habe auch die CPU-Eingangsdaten zu malloc (W * H * sizeof (float)) und internes Format zu GL_R32F, Format zu GL_RED und Typ GL_FLOAT geändert. Allerdings bekomme ich immer noch einen GL_INCOMPLETE_ATTACHMENT Fehler. Haben Sie Vorschläge, wie Sie das Problem beheben können? Vielen Dank für die Antwort! –

+0

Gleitkomma-Renderziele sind nicht Teil der ES3-Kernspezifikation. Daher kann es sein, dass die von Ihnen verwendete GPU dies nicht unterstützt. – solidpixel

+0

Beachten Sie, dass Ihre Frage nur Texturen betrifft, aber es ist auch eine Menge Aufwand, ein Renderziel zu erstellen - die beiden sind nicht dasselbe. Sie können eine Fließkomma-Textur lesen (dies ist der Kern in ES3.0), ohne dass sie Teil eines FBO ist. Du kannst einfach nicht in einen rendern. – solidpixel