Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Drawing on multiple surfaces by using only EGLSurface?

Is it possible to draw from the same application on multiple surfaces, one by one, by using only the handler returned by eglCreateWindowSurface ?

What i want to achieve is to create two or more surfaces and pass them to a client who will draw on them, and then, when done, basically, i will only need to perform swapBuffers. A simple surface handler ( EGLSurface ) will be enough for the client to draw shapes etc ?

I cannot find any examples; each examples just draws in the current context.

like image 331
Cumatru Avatar asked Aug 31 '25 00:08

Cumatru


2 Answers

I would go about this by creating an openGL framebuffer backed by a texture. I'd do my complicated drawing to that once. Then I'd draw a quad on each EGLSurface using the texture id.

something like:

eglMakeCurrent();

// generate na FB
  glGenFramebuffers(1, &fb);
  glBindFramebuffer(GL_FRAMEBUFFER, fb);

    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, mContextParams->mTexture);
    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);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA,
                 GL_UNSIGNED_BYTE, NULL);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                           GL_TEXTURE_2D, Texture, 0);

Then draw fancy stuff to framebuffer:

eglMakeCurrent();

glBindFramebuffer(GL_FRAMEBUFFER, fb);

// do draw here

// unbind
glBindFramebuffer(GL_FRAMEBUFFER, 0);

Then draw to screen:

for (everyEGLContext)
{
   eglMakeCurrent(display, surface, surface, context);
   drawQuad(texture);
   eqlSwapBuffers(display, surface);
}
like image 194
Heidi Gaertner Avatar answered Sep 02 '25 13:09

Heidi Gaertner


I have never tried this, but it should be possible. On the EGL level, the association between context and surface is established when you make a context current with the eglMakeCurrent() call:

EGLBoolean eglMakeCurrent( EGLDisplay display,
                           EGLSurface draw,
                           EGLSurface read,
                           EGLContext context);

The EGLSurface you pass to this call (typically the same for read and draw) can come from the return value of eglCreateWindowSurface().

So if you're currently drawing to surface1, and you want to start rendering to surface2, you can use:

eglMakeCurrent(eglGetCurrentDisplay(), surface2, surface2,
               eglGetCurrentContext());

Note that each surface can only be current for one context at a time. From the EGL 1.4 spec:

at most one context may be bound to a particular surface at a given time

like image 38
Reto Koradi Avatar answered Sep 02 '25 15:09

Reto Koradi