ios - billboard - opengl es shadows



Rendern auf Textur auf iOS OpenGL ES-funktioniert auf Simulator, aber nicht auf dem Gerät (1)

Ich habe MSAA in meinem Projekt verwendet und festgestellt, dass das Problem verschwunden ist, als ich es deaktiviert habe. Dies hat mich dazu gebracht, diese andere Frage zu entdecken , bei der das gleiche Problem diskutiert (aber nicht gelöst) wird.

Das Problem scheint zu sein, dass, wenn Multi-Sampling für Ihren Haupt-Framebuffer aktiviert ist, alle Ihre benutzerdefinierten FBOs auch Multi-Sampling verwenden müssen. Sie können nicht zu einem normalen nicht GL_TEXTURE_2D , und ein GL_TEXTURE_2D_MULTISAMPLE ist in OpenGL ES 2 nicht verfügbar.

Um das Problem zu beheben, habe ich meinen Render-to-Texture-Code genauso geändert, wie ich meinen Hauptrendering-Code geändert habe, um Multisampling zu aktivieren. Zusätzlich zu den drei Pufferobjekten, die im Code der Frage erstellt wurden, erstelle ich drei weitere für das Multisampling-Rendering:

glGenFramebuffersOES(1, &wmBuffer);
glGenRenderbuffersOES(1, &wmColor);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, wmBuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, wmColor);
glRenderbufferStorageMultisampleAPPLE(GL_RENDERBUFFER_OES, 4, GL_RGBA8_OES, width, height);
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, wmColor);
glGenRenderbuffersOES(1, &wmDepth);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, wmDepth);
glRenderbufferStorageMultisampleAPPLE(GL_RENDERBUFFER_OES, 4, GL_DEPTH_COMPONENT16_OES, width, height);
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, wmDepth);

Vor dem Rendern an die Textur binde ich den neuen MSAA-Puffer:

glBindFramebufferOES(GL_FRAMEBUFFER_OES, wmBuffer);

Schließlich, nach dem Rendern, löse ich den MSAA FBO in die Textur FBO genauso wie ich für meinen Hauptrendering Framebuffer:

glBindFramebufferOES(GL_READ_FRAMEBUFFER_APPLE, wmBuffer);
glBindFramebufferOES(GL_DRAW_FRAMEBUFFER_APPLE, wBuffer);
glResolveMultisampleFramebufferAPPLE();
GLenum attachments[] = {GL_DEPTH_ATTACHMENT_OES, GL_COLOR_ATTACHMENT0_OES, GL_STENCIL_ATTACHMENT_OES};
glDiscardFramebufferEXT(GL_READ_FRAMEBUFFER_APPLE, 3, attachments);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);

Die Texturen werden jetzt korrekt gerendert (und die Leistung ist großartig!)

https://ffff65535.com

Um die Leistung meiner OpenGL ES-Anwendung für das iPad zu verbessern, plante ich, ein selten aktualisiertes, aber renderzeitlastiges Element zu einer Textur zu zeichnen, sodass ich die Textur einfach verwenden kann, wenn das Element nicht neu gezeichnet werden muss. Während die Textur jedoch sowohl auf dem Simulator als auch auf dem Gerät korrekt abgebildet wird, wird nur auf dem Simulator etwas in die Textur gerendert.

Der folgende Code ist der Code, den ich dem Projekt hinzugefügt habe. Beim Erstellen der Szene erstelle ich die benötigten Puffer und die benötigte Textur:

int width = 768;
int height = 270;

// Prepare texture for off-screen rendering.
glGenTextures(1, &wTexture);
glBindTexture(GL_TEXTURE_2D, wTexture);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_FALSE);
glClearColor(.9f, .3f, .6f, 1.0f); // DEBUG
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA,
  GL_UNSIGNED_BYTE, 0);
glBindTexture(GL_TEXTURE_2D, 0);

// Depth attachment buffer, always needed.
glGenRenderbuffersOES(1, &wDepth);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, wDepth);
glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES,
  width, height);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, 0);

// Create FBO for render-to-texture.
glGenFramebuffersOES(1, &wBuffer);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, wBuffer);
glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES,
  GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, wTexture, 0);
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES,
  GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, wDepth);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);

Ein glFramebufferStatusOES auf dem neuen FBO (bevor es natürlich ungebunden ist) liefert einen "Framebuffer glFramebufferStatusOES " Rückgabewert sowohl auf dem Simulator als auch auf dem Gerät. Beachten Sie, dass ich die rosa klare Farbe für die Textur einstelle, um zu bestätigen, dass die Textur tatsächlich gerendert wird, und das Problem ist einfach, dass die Textur nie hineingezogen wird.

Immer wenn die Textur neu gezeichnet werden muss, mache ich das vor dem Rendern des Elements:

glBindFramebufferOES(GL_FRAMEBUFFER_OES, wBuffer);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(0, 0, width, height);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
// ...

und folgendes nach dem eigentlichen Rendering:

// ...
glPopMatrix();
glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);

Jedes Mal, wenn der Bildschirm neu gezeichnet wird, ordne ich die Textur einem Quad an der entsprechenden Position auf dem Bildschirm zu:

float Vertices[] = {
  -65.0f, -100.0f, .0f,
  -65.0f, 100.0f, .0f,
  -10.0f, -100.0f, .0f,
  -10.0f, 100.0f, .0f};
float Texture[] = {.0f, .0f, 1.0f, .0f, .0f, 1.0f, 1.0f, 1.0f};

glEnable(GL_TEXTURE_2D);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);

glBindTexture(GL_TEXTURE_2D, wTexture);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

glVertexPointer(3, GL_FLOAT, 0, Vertices);
glTexCoordPointer(2, GL_FLOAT, 0, Texture);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisable(GL_TEXTURE_2D);

glBindTexture(GL_TEXTURE_2D, 0);

Auf den iPhone- und iPad-Simulatoren (4.2, 4.3) funktioniert der Code wie erwartet. Ich sehe die dynamisch gerenderte Textur an der jeweiligen Position, natürlich mit einem rosa statt einem transparenten Hintergrund aufgrund meiner Debugging-Anweisung. Auf meinem iPad 4.2-Gerät wird jedoch nur das pinkfarbene Rechteck gerendert, nicht das, was während des Render-to-Texture-Schritts hineingezogen werden sollte. Daher wird die Textur korrekt auf dem Bildschirm gerendert, aber aus irgendeinem Grund kann der Render-to-Texture-Code auf dem Gerät tatsächlich nichts zur Textur rendern.

Ich nehme an, dass ich einige Funktionen verwende, die auf dem Gerät nicht verfügbar sind, oder irgendwo eine falsche Annahme mache, aber ich kann nicht herausfinden, was es ist. Ich habe auch versucht, es durch den OpenGL ES Analyzer zu laufen, aber es gibt mir nichts als einige grundlegende Tipps zur Leistungsoptimierung. Wo muss ich nach dem Problem suchen?