Reusing FBO causes screen to invert

Started by
-1 comments, last by dfwopengl 10 years, 6 months ago

Hope this will not be too obvious (or worse unsolvable based on info I've provided),

but am struggling to understand what is going on...

I am working on a DVD player that must support BD-J. The problem is that

the bd-j xlet programs run almost on an on-demand approach. The result is that I have

a Draw function that will draw a Pixmap or Rectangle onto an offscreen buffer
whenever the bd-j xlet wants.

Below is the code that is the essence of this xlet driven Draw approach. If we do not
do a glGenFramebuffers each time, but just do it once in an initialisation routine, yet
do a glBindFramebuffer for each Draw invocation then we get an inverted screen. We have to use
"opposite" coordinates as they are documented. The RectToScreen should be, in our parlance, a
call to RectToScreenInv, but that inverts the screen.

What I've found to work, but is way too slow to be useable, is the following approach, until I
try to reuse the offscreen fbo (comment out glGenFramebuffers), then end up with inverted display:

I ask the experts here what I'm missing?? I've burned wayyy too much time to improve performance

and can't understand what is wrong!

Thanks so much for your time! smile.png

-------------------------------------------------

*** glGenFramebuffers(1, &m_offscreen_fbo);
glBindFramebuffer(GL_FRAMEBUFFER, m_offscreen_fbo);

glViewport(0, 0, dest_width, dest_height);
glActiveTexture(GL_TEXTURE0);
glUseProgram(m_program[SHADER_PROGRAM_PIXMAP]);

VDVDOpenGLESPixmap *pEGLPixmap = dynamic_cast(OffscreenPixmap.pDst);

glGenTextures(1, &texture);

EGLImageKHR eglImage = pEGLPixmap->GetEGLImage();
// bind the egl image if we have one, otherwise upload with glTexImage2D
glEGLImageTargetTexture2D(GL_TEXTURE_2D, eglImage);

glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

if ( (flags & VDVD_PIXMAP_BLEND_SRC_COLOR) && !(flags & VDVD_PIXMAP_BLEND_SRC_ALPHA))
glEnable(GL_BLEND);

// use source alpha channel and color alpha as global alpha
if ((flags & VDVD_PIXMAP_BLEND_SRC_COLOR) || (flags & VDVD_PIXMAP_BLEND_SRC_ALPHA))
glEnable(GL_BLEND);
else
glDisable(GL_BLEND);

// global color must be this when no blit flags are set
VDVDColorARGB32 global_color = {0xff, 0xff, 0xff, 0xff};

// coloralpha: blend the alpha component from the draw color into the bitmap on the draw
if (flags & VDVD_PIXMAP_BLEND_SRC_COLOR)
global_color.a = color.a;

// colorize: multiply the current draw color into the colors in the bitmap on the draw (colorize)
if (flags & VDVD_PIXMAP_BLEND_MOD_SRC_COLOR)
{
global_color.r = (color.r * global_color.a) / 255;
global_color.g = (color.g * global_color.a) / 255;
global_color.b = (color.b * global_color.a) / 255;
}

// premultiply the draw color alpha into the color being blended into the bitmap on the draw
if (flags & VDVD_PIXMAP_BLEND_COLOR_ALPHA_PREMULT)
{
// extra alpha case. multiply the draw color alpha into the image on the draw.
global_color.r = (uint8_t)(((unsigned int)global_color.r * (unsigned int)color.a) / 255);
global_color.g = (uint8_t)(((unsigned int)global_color.g * (unsigned int)color.a) / 255);
global_color.b = (uint8_t)(((unsigned int)global_color.b * (unsigned int)color.a) / 255);
}

// translate to directfb porterduff
glBlendFunc(blendToSourceFactor(model), blendToDestFactor(model));

GLfloat shader_color[4];
color_premult(shader_color, global_color);

glVertexAttrib4fv(m_color_attr_pos, shader_color);

// texture coordinates
GLfloat const tx_min = (GLfloat)event.OffscreenPixmap.SrcRect.x / (GLfloat)event.OffscreenPixmap.pSrc->Width();
GLfloat const ty_min = (GLfloat)event.OffscreenPixmap.SrcRect.y / (GLfloat)event.OffscreenPixmap.pSrc->Height();
GLfloat const tx_max = ((GLfloat)event.OffscreenPixmap.SrcRect.x + (GLfloat)event.OffscreenPixmap.SrcRect.w)
/ (GLfloat)event.OffscreenPixmap.pSrc->Width();
GLfloat const ty_max = ((GLfloat)event.OffscreenPixmap.SrcRect.y + (GLfloat)event.OffscreenPixmap.SrcRect.h)

float x1, y1, x2, y2;
RectToScreen(event.OffscreenPixmap.DestRect, x1, y1, x2, y2, dest_width, dest_height);

GLfloat attribs[] = {x1, y2, tx_min, ty_max, /* bottom left */
x2, y2, tx_max, ty_max, /* bottom right */
x1, y1, tx_min, ty_min, /* top left */
x2, y1, tx_max, ty_min}; /* top right */

// load vertex attribs and enable their positions
glVertexAttribPointer(m_vertex_attr_pos, 2, GL_FLOAT, GL_FALSE, 4*sizeof(GLfloat), &attribs[0]);
glVertexAttribPointer(m_texture_attr_pos, 2, GL_FLOAT, GL_FALSE, 4*sizeof(GLfloat), &attribs[2]);
glEnableVertexAttribArray(m_vertex_attr_pos);
glEnableVertexAttribArray(m_texture_attr_pos);

// Bind the texture to texture_0 and sampler to sampler 0
glUniform1i(m_sampler_location, 0);

GLubyte indices[] = {0, 1, 2, 1, 3, 2};
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices);
glFinish();
glDeleteTextures(1, &texture);

return DRAW_SUCCESS;

This topic is closed to new replies.

Advertisement