5 votes

Rendu d'une image OpenGL ES 2.0

J'essaie d'effectuer un rendu OpenGL ES 2.0 sur un fichier image, indépendamment du fait que le rendu soit affiché à l'écran pour l'utilisateur. L'image vers laquelle j'effectue le rendu est d'une taille différente de celle de l'écran de l'utilisateur. J'ai juste besoin d'un tableau d'octets de données GL_RGB. Je connais bien glReadPixels, mais je ne pense pas qu'il puisse faire l'affaire dans ce cas puisque je n'utilise pas l'écran de l'utilisateur déjà rendu.

Pseudocode :

// Switch rendering to another buffer (framebuffer? renderbuffer?)

// Draw code here

// Save byte array of rendered data GL_RGB to file

// Switch rendering back to user's screen.

Comment puis-je faire cela sans interrompre l'affichage de l'utilisateur ? Je préférerais ne pas avoir à faire scintiller l'écran de l'utilisateur, en dessinant l'information désirée pour une seule image, en glReadPixel-ing et en la faisant disparaître ensuite.

Encore une fois, je ne veux pas qu'il montre quoi que ce soit à l'utilisateur. Voici mon code. Cela ne fonctionne pas est-ce que j'ai raté quelque chose ?

unsigned int canvasFrameBuffer;
bglGenFramebuffers(1, &canvasFrameBuffer);
bglBindFramebuffer(BGL_RENDERBUFFER, canvasFrameBuffer);
unsigned int canvasRenderBuffer;
bglGenRenderbuffers(1, &canvasRenderBuffer);
bglBindRenderbuffer(BGL_RENDERBUFFER, canvasRenderBuffer);
bglRenderbufferStorage(BGL_RENDERBUFFER, BGL_RGBA4, width, height);
bglFramebufferRenderbuffer(BGL_FRAMEBUFFER, BGL_COLOR_ATTACHMENT0, BGL_RENDERBUFFER, canvasRenderBuffer);

unsigned int canvasTexture;
bglGenTextures(1, &canvasTexture);
bglBindTexture(BGL_TEXTURE_2D, canvasTexture);
bglTexImage2D(BGL_TEXTURE_2D, 0, BGL_RGB, width, height, 0, BGL_RGB, BGL_UNSIGNED_BYTE, 0);
bglFramebufferTexture2D(BGL_FRAMEBUFFER, BGL_COLOR_ATTACHMENT0, BGL_TEXTURE_2D, canvasTexture, 0);

Matrix::matrix_t identity;
Matrix::LoadIdentity(&identity);
bglClearColor(1.0f, 1.0f, 1.0f, 1.0f);
bglClear(BGL_COLOR_BUFFER_BIT);
Draw(&identity, &identity, this);
bglFlush();
bglFinish();

byte *buffer = (byte*)Z_Malloc(width * height * 4, ZT_STATIC);
bglReadPixels(0, 0, width, height, BGL_RGB, BGL_UNSIGNED_BYTE, buffer);
SaveTGA("canvas.tga", buffer, width, height);
Z_Free(buffer);

// unbind frame buffer
bglBindRenderbuffer(BGL_RENDERBUFFER, 0);
bglBindFramebuffer(BGL_FRAMEBUFFER, 0);
bglDeleteTextures(1, &canvasTexture);
bglDeleteRenderbuffers(1, &canvasRenderBuffer);
bglDeleteFramebuffers(1, &canvasFrameBuffer);

5voto

user1054922 Points 188

Voici la solution, pour tous ceux qui en ont besoin :

    // Create framebuffer
unsigned int canvasFrameBuffer;
glGenFramebuffers(1, &canvasFrameBuffer);
glBindFramebuffer(GL_RENDERBUFFER, canvasFrameBuffer);

// Attach renderbuffer
unsigned int canvasRenderBuffer;
glGenRenderbuffers(1, &canvasRenderBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, canvasRenderBuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, width, height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, canvasRenderBuffer);

    // Clear the target (optional)
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);

    // Draw whatever you want here

char *buffer = (char*)malloc(width * height * 3);
glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, buffer);
SaveTGA("canvas.tga", buffer, width, height); // Your own function to save the image data to a file (in this case, a TGA)
free(buffer);

// unbind frame buffer
glBindRenderbuffer(GL_RENDERBUFFER, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDeleteRenderbuffers(1, &canvasRenderBuffer);
glDeleteFramebuffers(1, &canvasFrameBuffer);

1voto

Trax Points 1860

Vous pouvez effectuer un rendu sur une texture, lire les pixels et dessiner un carré avec cette texture (si vous voulez le montrer à l'utilisateur). Il ne devrait pas y avoir de scintillement, mais les performances s'en trouveront évidemment dégradées.

Sur iOS par exemple :

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X