2016-09-14 4 views
0

Angenommen, ich bekomme einen Strom von Pixeln Puffer und ich möchte sie mit OpelnGL anzeigen; Dafür benutze ich GLES20.glTexImage2D. Jetzt möchte ich das Bild jedes Mal aktualisieren, wenn ich einen neuen Puffer bekomme. Wie kann ich das von der MainActivity oder einer anderen Klasse machen, die den OpenGL-Thread nicht kennt?wie zwischen Threads mit Android OpenGL kommunizieren

Hier ist meine loadTexture Methode

private int loadTexture() 
    { 
     int[] textureId = new int[1]; 
     buffer.clear(); // buffer is a public static variable 
     buffer.put(data); // data has been created for the test 
     buffer.position(0); 

     GLES20.glGenTextures(1, textureId, 0); 
     GLES20.glBindTexture (GLES20.GL_TEXTURE_2D, textureId[0]); 

     GLES20.glTexImage2D (GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGB, 512, 512, 0, 
       GLES20.GL_RGB, GLES20.GL_UNSIGNED_BYTE, buffer); 

     GLES20.glTexParameteri (GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); 
     GLES20.glTexParameteri (GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); 
     GLES20.glTexParameteri (GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); 
     GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); 

     return textureId[0]; 
    } 

Auch wenn ich in dem OpenGL-Thread dies die Methode

public void onDrawFrame(GL10 glUnused) 
    { 
     GLES20.glViewport(0, 0, mWidth, mHeight); 
     GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); 
     GLES20.glUseProgram(mProgramObject); 
     ... 

     // Bind the base map 
     GLES20.glActiveTexture (GLES20.GL_TEXTURE0); 
     GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mBaseMapTexId); 

     // Set the base map sampler to texture unit to 0 
     GLES20.glUniform1i(mBaseMapLoc, 0); 

     // Bind the light map 
     GLES20.glActiveTexture (GLES20.GL_TEXTURE1); 
     GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mLightMapTexId); 

     // Set the light map sampler to texture unit 1 
     GLES20.glUniform1i(mLightMapLoc, 1); 

     GLES20.glDrawElements(GLES20.GL_TRIANGLES, 6, GLES20.GL_UNSIGNED_SHORT, mIndices); 

     // For test purpose, I try to update the data in the buffer 
     byte[] data = new byte[512*512*3]; 
     for (int y = 0; y < 512; y++) 
      for (int x = 0; x < 512; x++) 
      { 
       int pixel = 200; 
       data[(y * 512 + x) * 3 + 0] = (byte)((pixel >> 0) & 0xFF); 
       data[(y * 512 + x) * 3 + 1] = (byte)((pixel >> 0) & 0xFF); 
       data[(y * 512 + x) * 3 + 2] = (byte)((pixel >> 0) & 0xFF); 
      } 
     buffer.clear(); 
     buffer.put(data); 
     buffer.position(0);   
    } 

hinzufügen, aber das Bild wird nicht aktualisiert. Auch wenn ich versuche, diese bis zum Ende der letzteren Methode hinzufügen, das ist nicht funktionieren

GLES20.glActiveTexture(GLES20.GL_TEXTURE0); 
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mBaseMapTexId); 
GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGB, 512, 512, 0, 
        GLES20.GL_RGB, GLES20.GL_UNSIGNED_BYTE, buffer); 

Antwort

0

Wie kann ich tun, dass aus den MainActivity oder einer anderen Klasse, die nicht bewusst das Threads OpenGL ist?

Zuerst - lassen Sie uns einige Terminologie korrigieren. Es gibt keinen "OpenGL-Thread". Wenn Sie diese Terminologie verwenden, wird es sehr schnell sehr verwirrend.

Sie haben einen Renderkontext von Ihrer plattformspezifischen Renderebene (z. B. EAGL auf iOS, EGL auf Android). Jeder Rendering-Kontext kann zu jedem Zeitpunkt in genau einem Thread aktiv sein, ABER kann Threads verschieben (zB über einen Aufruf an eglMakeCurrent für die EGL-Plattform-Ebene), weshalb das Nachdenken über einen "OpenGL-Thread" konzeptionell so schlecht ist .

Durch das Binden eines Kontexts an einen Thread wird die Bindung eines vorhandenen Kontexts entfernt und der neue Kontext von anderen Threads gelöst. Zusätzlich zum Verschieben eines Threads zwischen Threads können Sie auch mehrere verschiedene Renderkontexte verwenden, die an mehrere unterschiedliche Threads gebunden sind, die parallel ausgeführt werden. Dies ist für diese Frage wichtig.

Die gemeinsame Nutzung von Daten wird erreicht, indem mehrere Renderkontexte in derselben Freigabegruppe (siehe share_context Parameter zu eglCreateContext, wenn Sie EGL verwenden) an verschiedene Threads gebunden sind. Sie können eine Textur in einem Kontext erstellen, die Daten hochladen, und dann kann der andere Kontext sie binden und verwenden. Die Synchronisierung (z. B. damit der andere Thread weiß, wann es sicher ist, diese Texturbindung zu verwenden) muss über ein Synchronisationsprotokoll auf Anwendungsebene erfolgen - es wird nicht von der API bereitgestellt.

Die Regeln zur Zustandssynchronisierung zwischen mehreren Kontexten werden etwas kompliziert (zusammenfassend ist es normalerweise faul und nur synchronisiert, wenn ein Kontext eine Ressource bindet), daher empfehle ich Anhang C der OpenGL ES 2.0 Spezifikation (oder gleichwertig in den späteren ES Versionen - es hat sich nicht geändert).

+0

danke für Ihre Antwort. In der Tat habe ich ein Problem, das sogar im richtigen Kontext ist. Im 'onDrawFrame' versuche ich die Puffervariable zu ändern, aber das aktualisiert die Textur nicht, wie kann es sein? – Newben

+0

Ihre "Puffer" -Variable ist eine lokale Variable für Ihr Programm; Es hat nichts mit den Texturdaten zu tun, die von der Rendering-API verwendet werden. Der Grafiktreiber erstellt eine Kopie, wenn Sie 'glTexImage2D' aufrufen. Wenn Sie den Inhalt der Textur ändern möchten, müssen Sie "Puffer" aktualisieren, dann rufen Sie 'glTexImage2D' erneut auf, um zu ändern, was der Grafikstapel sieht. – solidpixel

+0

danke für Ihre Antwort. Ich habe versucht, Ihrer Empfehlung zu folgen. Also fügte ich am unteren Rand des 'onDrawFrame' folgenden Code' GLES20.glActiveTexture (GLES20.GL_TEXTURE0); GLES20.glBindTexture (GLES20.GL_TEXTURE_2D, mBaseMapTexId); GLES20.glTexSubImage2D (GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGB, 512, 512, 0, GLES20.GL_RGB, GLES20.GL_UNSIGNED_BYTE, bufer); ', wobei' mBaseMapTexId' die Textur-ID ist, die in 'loadTexture() gesetzt ist 'Methode, aber es hat nicht funktioniert (Wissen, dass ich natürlich 'Puffer' in der' onDrawFrame' Methode aktualisiert). Danke für Ihre Hilfe – Newben

Verwandte Themen