diff options
author | Louis-Francis Ratté-Boulianne <lfrb@collabora.com> | 2014-11-11 13:43:56 -0500 |
---|---|---|
committer | Markus Mohrhard <markus.mohrhard@collabora.co.uk> | 2014-11-12 04:07:21 +0100 |
commit | 74c3dbe87e7256f8f8b3eac3a34415780035f465 (patch) | |
tree | 1271e6355a0a47850435be794581c1bfc9a4c17f /vcl/opengl | |
parent | c7a5ce27e6d27af4d868dedcde1f650fa129e6f8 (diff) |
vcl: Read back OpenGL FBO to create offscreen X11 pixmap
Change-Id: I330e7d62bf31b4a90b5866d9531f073f7c69c92a
Diffstat (limited to 'vcl/opengl')
-rw-r--r-- | vcl/opengl/gdiimpl.cxx | 19 | ||||
-rw-r--r-- | vcl/opengl/x11/gdiimpl.cxx | 33 |
2 files changed, 45 insertions, 7 deletions
diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx index 72387e22cbc1..65c4f3089017 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -503,14 +503,23 @@ void OpenGLSalGraphicsImpl::DrawPolyPolygon( const basegfx::B2DPolyPolygon& rPol glDisableVertexAttribArray( GL_ATTRIB_POS ); } -void OpenGLSalGraphicsImpl::DrawTextureRect( const Size& rSize, const SalTwoRect& rPosAry ) +void OpenGLSalGraphicsImpl::DrawTextureRect( const Size& rSize, const SalTwoRect& rPosAry, bool bInverted ) { GLfloat aTexCoord[8]; aTexCoord[0] = aTexCoord[2] = rPosAry.mnSrcX / (double) rSize.Width(); aTexCoord[4] = aTexCoord[6] = (rPosAry.mnSrcX + rPosAry.mnSrcWidth) / (double) rSize.Width(); - aTexCoord[3] = aTexCoord[5] = (rSize.Height() - rPosAry.mnSrcY) / (double) rSize.Height(); - aTexCoord[1] = aTexCoord[7] = (rSize.Height() - rPosAry.mnSrcY - rPosAry.mnSrcHeight) / (double) rSize.Height(); + + if( !bInverted ) + { + aTexCoord[3] = aTexCoord[5] = (rSize.Height() - rPosAry.mnSrcY) / (double) rSize.Height(); + aTexCoord[1] = aTexCoord[7] = (rSize.Height() - rPosAry.mnSrcY - rPosAry.mnSrcHeight) / (double) rSize.Height(); + } + else + { + aTexCoord[1] = aTexCoord[7] = (rSize.Height() - rPosAry.mnSrcY) / (double) rSize.Height(); + aTexCoord[3] = aTexCoord[5] = (rSize.Height() - rPosAry.mnSrcY - rPosAry.mnSrcHeight) / (double) rSize.Height(); + } glEnableVertexAttribArray( GL_ATTRIB_TEX ); glVertexAttribPointer( GL_ATTRIB_TEX, 2, GL_FLOAT, GL_FALSE, 0, aTexCoord ); @@ -520,7 +529,7 @@ void OpenGLSalGraphicsImpl::DrawTextureRect( const Size& rSize, const SalTwoRect glDisableVertexAttribArray( GL_ATTRIB_TEX ); } -void OpenGLSalGraphicsImpl::DrawTexture( GLuint nTexture, const Size& rSize, const SalTwoRect& pPosAry ) +void OpenGLSalGraphicsImpl::DrawTexture( GLuint nTexture, const Size& rSize, const SalTwoRect& pPosAry, bool bInverted ) { if( mnTextureProgram == 0 ) { @@ -534,7 +543,7 @@ void OpenGLSalGraphicsImpl::DrawTexture( GLuint nTexture, const Size& rSize, con CHECK_GL_ERROR(); glBindTexture( GL_TEXTURE_2D, nTexture ); - DrawTextureRect( rSize, pPosAry ); + DrawTextureRect( rSize, pPosAry, bInverted ); CHECK_GL_ERROR(); glBindTexture( GL_TEXTURE_2D, 0 ); diff --git a/vcl/opengl/x11/gdiimpl.cxx b/vcl/opengl/x11/gdiimpl.cxx index 6e803bd21acd..13b70495341a 100644 --- a/vcl/opengl/x11/gdiimpl.cxx +++ b/vcl/opengl/x11/gdiimpl.cxx @@ -83,9 +83,38 @@ X11Pixmap* X11OpenGLSalGraphicsImpl::GetPixmapFromScreen( const Rectangle& rRect { Display* pDisplay = mrParent.GetXDisplay(); SalX11Screen nScreen = mrParent.GetScreenNumber(); + XVisualInfo aVisualInfo; + X11Pixmap* pPixmap; + XImage* pImage; + sal_uInt8* pData; SAL_INFO( "vcl.opengl", "GetPixmapFromScreen" ); - return new X11Pixmap( pDisplay, nScreen, rRect.GetWidth(), rRect.GetHeight(), 24 ); + // TODO: lfrb: Use context depth + pPixmap = new X11Pixmap( pDisplay, nScreen, rRect.GetWidth(), rRect.GetHeight(), 24 ); + + if( !OpenGLHelper::GetVisualInfo( pDisplay, nScreen.getXScreen(), aVisualInfo ) ) + return pPixmap; + + // make sure everything is synced up before reading back + maContext.makeCurrent(); + glXWaitX(); + + // TODO: lfrb: What if offscreen? + pData = new sal_uInt8[rRect.GetWidth() * rRect.GetHeight() * 4]; + glPixelStorei( GL_PACK_ALIGNMENT, 1 ); + glReadPixels( rRect.Left(), GetHeight() - rRect.Top(), rRect.GetWidth(), rRect.GetHeight(), + GL_RGBA, GL_UNSIGNED_BYTE, pData ); + + pImage = XCreateImage( pDisplay, aVisualInfo.visual, 24, ZPixmap, 0, (char*) pData, + rRect.GetWidth(), rRect.GetHeight(), 8, 0 ); + XInitImage( pImage ); + GC aGC = XCreateGC( pDisplay, pPixmap->GetPixmap(), 0, NULL ); + XPutImage( pDisplay, pPixmap->GetDrawable(), aGC, pImage, + 0, 0, 0, 0, rRect.GetWidth(), rRect.GetHeight() ); + XFreeGC( pDisplay, aGC ); + XDestroyImage( pImage ); + + return pPixmap; } bool X11OpenGLSalGraphicsImpl::RenderPixmapToScreen( X11Pixmap* pPixmap, int nX, int nY ) @@ -128,7 +157,7 @@ bool X11OpenGLSalGraphicsImpl::RenderPixmapToScreen( X11Pixmap* pPixmap, int nX, glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); - DrawTexture( nTexture, pPixmap->GetSize(), aPosAry ); + DrawTexture( nTexture, pPixmap->GetSize(), aPosAry, !bInverted ); glXReleaseTexImageEXT( pDisplay, pGlxPixmap, GLX_FRONT_LEFT_EXT ); glDeleteTextures( 1, &nTexture ); |