Kaydet (Commit) 80533fb4 authored tarafından Louis-Francis Ratté-Boulianne's avatar Louis-Francis Ratté-Boulianne Kaydeden (comit) Markus Mohrhard

vcl: Implement basic SalGraphics methods for OpenGL backend

Change-Id: Iade3960c38f0de5594bc98e535450abcf88e9a6d
üst 18e1d133
...@@ -31,6 +31,51 @@ private: ...@@ -31,6 +31,51 @@ private:
OpenGLContext maContext; OpenGLContext maContext;
SalColor mnLineColor;
SalColor mnFillColor;
std::vector< GLuint > maShaders;
GLuint mnSolidProgram;
GLuint mnColorUniform;
GLuint mnTextureProgram;
GLuint mnSamplerUniform;
GLuint mnMaskedTextureProgram;
GLuint mnMaskedSamplerUniform;
GLuint mnMaskSamplerUniform;
GLuint mnMaskProgram;
GLuint mnMaskUniform;
GLuint mnMaskColorUniform;
GLuint CompileShader( GLenum nType, const char *aSrc );
GLuint CreateProgram( const char *aVertShaderSrc, const char *aFragShaderSrc );
bool CreateSolidProgram( void );
bool CreateTextureProgram( void );
bool CreateMaskedTextureProgram( void );
bool CreateMaskProgram( void );
void BeginSolid( SalColor nColor, sal_uInt8 nTransparency );
void BeginSolid( SalColor nColor );
void EndSolid( void );
void BeginInvert( void );
void EndInvert( void );
void DrawPoint( long nX, long nY );
void DrawLine( long nX1, long nY1, long nX2, long nY2 );
void DrawLines( sal_uInt32 nPoints, const SalPoint* pPtAry, bool bClose );
void DrawConvexPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry );
void DrawRect( long nX, long nY, long nWidth, nHeight );
void DrawPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry );
void DrawPolyPolygon( const basegfx::B2DPolyPolygon& pPolyPolygon );
void DrawTextureRect( const SalTwoRect& pPosAry );
void DrawTexture( GLuint nTexture, const SalTwoRect& pPosAry );
void DrawTextureWithMask( GLuint nTexture, GLuint nMask, const SalTwoRect& pPosAry );
void DrawMask( GLuint nMask, SalColor nMaskColor, const SalTwoRect& pPosAry );
public: public:
virtual ~OpenGLSalGraphicsImpl (); virtual ~OpenGLSalGraphicsImpl ();
......
...@@ -20,6 +20,18 @@ ...@@ -20,6 +20,18 @@
#include "openglgdiimpl.hxx" #include "openglgdiimpl.hxx"
#include <vcl/gradient.hxx> #include <vcl/gradient.hxx>
#include <basegfx/polygon/b2dpolygontools.hxx>
#include <basegfx/polygon/b2dpolygontriangulator.hxx>
#define GL_ATTRIB_POS 0
#define GL_ATTRIB_TEX 1
#define glUniformColor(nUniform, nColor, nTransparency) \
glUniform4f( nUniform, \
((float) SALCOLOR_RED( nColor )) / 255, \
((float) SALCOLOR_GREEN( nColor )) / 255, \
((float) SALCOLOR_BLUE( nColor )) / 255, \
(100 - nTransparency) * (1.0 / 100) )
OpenGLSalGraphicsImpl::~OpenGLSalGraphicsImpl() OpenGLSalGraphicsImpl::~OpenGLSalGraphicsImpl()
{ {
...@@ -27,11 +39,30 @@ OpenGLSalGraphicsImpl::~OpenGLSalGraphicsImpl() ...@@ -27,11 +39,30 @@ OpenGLSalGraphicsImpl::~OpenGLSalGraphicsImpl()
void OpenGLSalGraphicsImpl::freeResources() void OpenGLSalGraphicsImpl::freeResources()
{ {
// Delete shaders, programs and textures if not shared
} }
bool OpenGLSalGraphicsImpl::setClipRegion( const vcl::Region& ) bool OpenGLSalGraphicsImpl::setClipRegion( const vcl::Region& rClip )
{ {
return false; const basegfx::B2DPolyPolygon aClip( rClip.GetAsB2DPolyPolygon() );
glEnable(GL_STENCIL_TEST);
glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );
glDepthMask( GL_FALSE );
glStencilMask( 0xFF );
glStencilFunc( GL_NEVER, 1, 0xFF );
glStencilOp( GL_REPLACE, GL_KEEP, GL_KEEP );
glClear( GL_STENCIL_BUFFER_BIT );
DrawPolyPolygon( aClip );
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glDepthMask( GL_TRUE );
glStencilMask( 0x00 );
glStencilFunc(GL_EQUAL, 1, 0xFF);
return true;
} }
// get the depth of the device // get the depth of the device
...@@ -49,28 +80,45 @@ long OpenGLSalGraphicsImpl::GetGraphicsWidth() const ...@@ -49,28 +80,45 @@ long OpenGLSalGraphicsImpl::GetGraphicsWidth() const
// set the clip region to empty // set the clip region to empty
void OpenGLSalGraphicsImpl::ResetClipRegion() void OpenGLSalGraphicsImpl::ResetClipRegion()
{ {
glDisable(GL_STENCIL_TEST);
} }
// set the line color to transparent (= don't draw lines) // set the line color to transparent (= don't draw lines)
void OpenGLSalGraphicsImpl::SetLineColor() void OpenGLSalGraphicsImpl::SetLineColor()
{ {
if( mnLineColor != SALCOLOR_NONE )
{
mnLineColor = SALCOLOR_NONE;
}
} }
// set the line color to a specific color // set the line color to a specific color
void OpenGLSalGraphicsImpl::SetLineColor( SalColor /*nSalColor*/ ) void OpenGLSalGraphicsImpl::SetLineColor( SalColor nSalColor )
{ {
if( mnLineColor != nSalColor )
{
mnLineColor = nSalColor;
}
} }
// set the fill color to transparent (= don't fill) // set the fill color to transparent (= don't fill)
void OpenGLSalGraphicsImpl::SetFillColor() void OpenGLSalGraphicsImpl::SetFillColor()
{ {
if( mnFillColor != SALCOLOR_NONE )
{
mnFillColor = SALCOLOR_NONE;
}
} }
// set the fill color to a specific color, shapes will be // set the fill color to a specific color, shapes will be
// filled accordingly // filled accordingly
void OpenGLSalGraphicsImpl::SetFillColor( SalColor /*nSalColor*/ ) void OpenGLSalGraphicsImpl::SetFillColor( SalColor nSalColor )
{ {
if( mnFillColor != nSalColor )
{
mnFillColor = nSalColor;
}
} }
// enable/disable XOR drawing // enable/disable XOR drawing
...@@ -88,34 +136,571 @@ void OpenGLSalGraphicsImpl::SetROPFillColor( SalROPColor /*nROPColor*/ ) ...@@ -88,34 +136,571 @@ void OpenGLSalGraphicsImpl::SetROPFillColor( SalROPColor /*nROPColor*/ )
{ {
} }
// draw --> LineColor and FillColor and RasterOp and ClipRegion GLuint OpenGLSalGraphicsImpl::CompileShader( GLenum nType, const char *aSrc )
void OpenGLSalGraphicsImpl::drawPixel( long /*nX*/, long /*nY*/ ) {
GLint nStatus;
GLuint nShader;
GLint nLogLen( 0 );
char *aLog( NULL );
nShader = glCreateShader( nType );
glShaderSource( nShader, 1, (const GLchar **) &aSrc, NULL );
glCompileShader( nShader );
glGetShaderiv( nShader, GL_COMPILE_STATUS, &nStatus );
if( nStatus )
return nShader;
glGetShaderiv( nShader, GL_INFO_LOG_LENGTH, &nLogLen );
if( nLogLen > 1 )
aLog = new char[nLogLen];
if( aLog )
glGetShaderInfoLog( nShader, nLogLen, NULL, aLog );
SAL_WARN( "vcl.opengl", "::CompileShader failed: " << aLog );
delete aLog;
glDeleteShader( nShader );
return 0;
}
GLuint OpenGLSalGraphicsImpl::CreateProgram( const char *aVertShaderSrc, const char *aFragShaderSrc )
{
GLuint nProgram;
GLuint nVertShader, nFragShader;
GLint nStatus;
nVertShader = CompileShader( GL_VERTEX_SHADER, aVertShaderSrc );
nFragShader = CompileShader( GL_FRAGMENT_SHADER, aFragShaderSrc );
if( !nVertShader || !nFragShader )
{
SAL_WARN( "vcl.opengl", "::CreateProgram couldn't compile the shaders" );
return 0;
}
nProgram = glCreateProgram();
if( nProgram == 0 )
{
SAL_WARN( "vcl.opengl", "::CreateProgram couldn't create GL program" );
return 0;
}
glAttachShader( nProgram, nVertShader );
glAttachShader( nProgram, nFragShader );
glLinkProgram( nProgram );
glGetProgramiv( nProgram, GL_LINK_STATUS, &nStatus );
if( !nStatus )
{
GLint nLogLen( 0 );
char *aLog( NULL );
glDeleteShader( nVertShader );
glDeleteShader( nFragShader );
glGetProgramiv( nProgram, GL_INFO_LOG_LENGTH, &nLogLen );
if( nLogLen > 0 )
aLog = new char[nLogLen];
if( aLog )
glGetProgramInfoLog( nProgram, nLogLen, NULL, aLog );
SAL_WARN( "vcl.opengl", "::CreateSolidShader couldn't link program: " << aLog );
delete aLog;
return 0;
}
maShaders.push_back( nVertShader );
maShaders.push_back( nFragShader );
return nProgram;
}
bool OpenGLSalGraphicsImpl::CreateSolidProgram( void )
{
static const char aVertShaderSrc[] =
"attribute vec4 position;\n"
"void main() {\n"
" gl_Position = position;\n"
"}\n";
static const char aFragShaderSrc[] =
"precision mediump float;\n"
"uniform vec4 color;\n"
"void main() {\n"
" gl_FragColor = color;\n"
"}\n";
mnSolidProgram = CreateProgram( aVertShaderSrc, aFragShaderSrc );
if( mnSolidProgram == 0 )
return false;
glBindAttribLocation( mnSolidProgram, GL_ATTRIB_POS, "position" );
mnColorUniform = glGetUniformLocation( mnSolidProgram, "color" );
return true;
}
bool OpenGLSalGraphicsImpl::CreateTextureProgram( void )
{
static const char aVertShaderSrc[] =
"attribute vec4 position;\n"
"attribute vec2 tex_coord_in;\n"
"varying vec2 tex_coord;\n"
"void main() {\n"
" gl_Position = position;\n"
" tex_coord = tex_coord_in;\n"
"}\n";
static const char aFragShaderSrc[] =
"precision mediump float;\n"
"varying vec2 tex_coord;\n"
"uniform sampler2D sampler;\n"
"void main() {\n"
" gl_FragColor = texture2D(sampler, tex_coord);\n"
"}\n";
mnTextureProgram = CreateProgram( aVertShaderSrc, aFragShaderSrc );
if( mnTextureProgram == 0 )
return false;
glBindAttribLocation( mnTextureProgram, GL_ATTRIB_POS, "position" );
glBindAttribLocation( mnTextureProgram, GL_ATTRIB_TEX, "tex_coord_in" );
mnSamplerUniform = glGetUniformLocation( mnTextureProgram, "sampler" );
return true;
}
bool OpenGLSalGraphicsImpl::CreateMaskedTextureProgram( void )
{
static const char aVertShaderSrc[] =
"attribute vec4 position;\n"
"attribute vec2 tex_coord_in;\n"
"varying vec2 tex_coord;\n"
"void main() {\n"
" gl_Position = position;\n"
" tex_coord = tex_coord_in;\n"
"}\n";
static const char aFragShaderSrc[] =
"precision mediump float;\n"
"varying vec2 tex_coord;\n"
"uniform sampler2D sampler;\n"
"uniform sampler2D mask;\n"
"void main() {\n"
" vec4 texel0, texel1;\n"
" texel0 = texture2D(sampler, tex_coord);\n"
" texel1 = texture2D(mask, tex_coord);\n"
" gl_FragColor = texel0 * texel1.a;\n"
"}\n";
mnMaskedTextureProgram = CreateProgram( aVertShaderSrc, aFragShaderSrc );
if( mnMaskedTextureProgram == 0 )
return false;
glBindAttribLocation( mnTextureProgram, GL_ATTRIB_POS, "position" );
glBindAttribLocation( mnTextureProgram, GL_ATTRIB_TEX, "tex_coord_in" );
mnMaskedSamplerUniform = glGetUniformLocation( mnMaskedTextureProgram, "sampler" );
mnMaskSamplerUniform = glGetUniformLocation( mnMaskedTextureProgram, "mask" );
return true;
}
bool OpenGLSalGraphicsImpl::CreateMaskProgram( void )
{
static const char aVertShaderSrc[] =
"attribute vec4 position;\n"
"attribute vec2 tex_coord_in;\n"
"varying vec2 tex_coord;\n"
"void main() {\n"
" gl_Position = position;\n"
" tex_coord = tex_coord_in;\n"
"}\n";
static const char aFragShaderSrc[] =
"precision mediump float;\n"
"varying vec2 tex_coord;\n"
"uniform sampler2D sampler;\n"
"uniform vec4 color;\n"
"void main() {\n"
" vec4 texel0;\n"
" texel0 = texture2D(sampler, tex_coord);\n"
" gl_FragColor = color * texel0.a;\n"
"}\n";
mnMaskedTextureProgram = CreateProgram( aVertShaderSrc, aFragShaderSrc );
if( mnMaskedTextureProgram == 0 )
return false;
glBindAttribLocation( mnTextureProgram, GL_ATTRIB_POS, "position" );
glBindAttribLocation( mnTextureProgram, GL_ATTRIB_TEX, "tex_coord_in" );
mnMaskUniform = glGetUniformLocation( mnMaskProgram, "sampler" );
mnMaskColorUniform = glGetUniformLocation( mnMaskProgram, "mask" );
return true;
}
void OpenGLSalGraphicsImpl::BeginSolid( SalColor nColor, sal_uInt8 nTransparency )
{
if( mnSolidProgram == 0 )
{
if( !CreateSolidProgram() )
return;
}
glUseProgram( mnSolidProgram );
glUniformColor( mnColorUniform, nColor, nTransparency );
}
void OpenGLSalGraphicsImpl::BeginSolid( SalColor nColor )
{
BeginSolid( nColor, 0 );
}
void OpenGLSalGraphicsImpl::EndSolid( void )
{
glUseProgram( 0 );
}
void OpenGLSalGraphicsImpl::BeginInvert( void )
{
glEnable( GL_BLEND );
glBlendFunc( GL_ONE_MINUS_DST_COLOR, GL_ZERO );
BeginSolid( MAKE_SALCOLOR( 255, 255, 255 ) );
}
void OpenGLSalGraphicsImpl::EndInvert( void )
{
EndSolid();
glDisable( GL_BLEND );
}
void OpenGLSalGraphicsImpl::DrawPoint( long nX, long nY )
{
GLushort pPoint[2];
pPoint[0] = nX;
pPoint[1] = nY;
glEnableVertexAttribArray( GL_ATTRIB_POS );
glVertexAttribPointer( GL_ATTRIB_POS, 2, GL_UNSIGNED_SHORT, GL_FALSE, 0, pPoint );
glDrawArrays( GL_POINTS, 0, 1 );
glDisableVertexAttribArray( GL_ATTRIB_POS );
}
void OpenGLSalGraphicsImpl::DrawLine( long nX1, long nY1, long nX2, long nY2 )
{
GLushort pPoints[4];
pPoints[0] = nX1;
pPoints[1] = nY1;
pPoints[2] = nX2;
pPoints[3] = nY2;
glEnableVertexAttribArray( GL_ATTRIB_POS );
glVertexAttribPointer( GL_ATTRIB_POS, 4, GL_UNSIGNED_SHORT, GL_FALSE, 0, pPoints );
glDrawArrays( GL_LINES, 0, 2 );
glDisableVertexAttribArray( GL_ATTRIB_POS );
}
void OpenGLSalGraphicsImpl::DrawLines( sal_uInt32 nPoints, const SalPoint* pPtAry, bool bClose )
{
GLushort *pPoints;
sal_uInt32 i, j;
pPoints = new GLushort[nPoints * 2];
for( i = 0, j = 0; i < nPoints; i++, j += 2 )
{
pPoints[j] = pPtAry[i].mnX;
pPoints[j+1] = pPtAry[i].mnY;
}
glEnableVertexAttribArray( GL_ATTRIB_POS );
glVertexAttribPointer( GL_ATTRIB_POS, nPoints * 2, GL_UNSIGNED_SHORT, GL_FALSE, 0, pPoints );
if( bClose )
glDrawArrays( GL_LINE_LOOP, 0, nPoints );
else
glDrawArrays( GL_LINE_STRIP, 0, nPoints );
glDisableVertexAttribArray( GL_ATTRIB_POS );
}
void OpenGLSalGraphicsImpl::DrawConvexPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry )
{ {
GLushort pVertices[nPoints * 2];
sal_uInt32 i, j;
for( i = 0, j = 0; i < nPoints; i++, j += 2 )
{
pVertices[j] = pPtAry[i].mnX;
pVertices[j+1] = pPtAry[i].mnY;
}
glEnableVertexAttribArray( GL_ATTRIB_POS );
glVertexAttribPointer( GL_ATTRIB_POS, nPoints * 2, GL_UNSIGNED_SHORT, GL_FALSE, 0, pVertices );
glDrawArrays( GL_TRIANGLE_FAN, 0, nPoints );
glDisableVertexAttribArray( GL_ATTRIB_POS );
} }
void OpenGLSalGraphicsImpl::drawPixel( long /*nX*/, long /*nY*/, SalColor /*nSalColor*/ ) void OpenGLSalGraphicsImpl::DrawRect( long nX, long nY, long nWidth, long nHeight )
{ {
long nX1( nX );
long nY1( nY );
long nX2( nX + nWidth - 1 );
long nY2( nY + nHeight - 1 );
const SalPoint aPoints[] = { { nX1, nY2 }, { nX1, nY1 },
{ nX2, nY1 }, { nX2, nY2 }};
DrawConvexPolygon( 4, aPoints );
} }
void OpenGLSalGraphicsImpl::drawLine( long /*nX1*/, long /*nY1*/, long /*nX2*/, long /*nY2*/ ) void OpenGLSalGraphicsImpl::DrawPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry )
{ {
::basegfx::B2DPolygon aPolygon;
for( sal_uInt32 i = 0; i < nPoints; i++ )
aPolygon.append( ::basegfx::B2DPoint( pPtAry[i].mnX, pPtAry[i].mnY ) );
aPolygon.setClosed( true );
if( ::basegfx::tools::isConvex( aPolygon ) )
{
if( nPoints > 2L )
{
DrawConvexPolygon( nPoints, pPtAry );
}
}
else
{
const ::basegfx::B2DPolygon& aResult(
::basegfx::triangulator::triangulate( aPolygon ) );
GLushort pVertices[aResult.count() * 2];
sal_uInt32 j( 0 );
for( sal_uInt32 i = 0; i < aResult.count(); i++ )
{
const ::basegfx::B2DPoint& rPt( aResult.getB2DPoint(i) );
pVertices[j++] = rPt.getX();
pVertices[j++] = rPt.getY();
}
glEnableVertexAttribArray( GL_ATTRIB_POS );
glVertexAttribPointer( GL_ATTRIB_POS, aResult.count() * 2, GL_UNSIGNED_SHORT, GL_FALSE, 0, pVertices );
glDrawArrays( GL_TRIANGLES, 0, aResult.count() );
glDisableVertexAttribArray( GL_ATTRIB_POS );
}
} }
void OpenGLSalGraphicsImpl::drawRect( long /*nX*/, long /*nY*/, long /*nWidth*/, long /*nHeight*/ ) void OpenGLSalGraphicsImpl::DrawPolyPolygon( const basegfx::B2DPolyPolygon& pPolyPolygon )
{ {
sal_uInt32 i, j;
::std::vector< GLushort > pVertices;
for( i = 0; i < pPolyPolygon.count(); i++ )
{
const basegfx::B2DPolygon& pPolygon( pPolyPolygon.getB2DPolygon( i ) );
const ::basegfx::B2DPolygon& aResult(
::basegfx::triangulator::triangulate( pPolygon ) );
for( j = 0; i < aResult.count(); j++ )
{
const ::basegfx::B2DPoint& rPt( aResult.getB2DPoint(i) );
pVertices.push_back( rPt.getX() );
pVertices.push_back( rPt.getY() );
}
}
glEnableVertexAttribArray( GL_ATTRIB_POS );
glVertexAttribPointer( GL_ATTRIB_POS, pVertices.size(), GL_UNSIGNED_SHORT, GL_FALSE, 0, pVertices.size() );
glDrawArrays( GL_TRIANGLES, 0, pVertices.size() / 2 );
glDisableVertexAttribArray( GL_ATTRIB_POS );
} }
void OpenGLSalGraphicsImpl::drawPolyLine( sal_uInt32 /*nPoints*/, const SalPoint* /*pPtAry*/ ) void OpenGLSalGraphicsImpl::DrawTextureRect( const SalTwoRect& pPosAry )
{ {
GLushort aTexCoord[8];
glEnableVertexAttribArray( GL_ATTRIB_TEX );
glVertexAttribPointer( GL_ATTRIB_TEX, 8, GL_UNSIGNED_SHORT, GL_FALSE, 0, aTexCoord );
DrawRect( pPosAry.mnDestX, pPosAry.mnDestY, pPosAry.mnDestWidth, pPosAry.mnDestHeight );
glDisableVertexAttribArray( GL_ATTRIB_TEX );
} }
void OpenGLSalGraphicsImpl::drawPolygon( sal_uInt32 /*nPoints*/, const SalPoint* /*pPtAry*/ ) void OpenGLSalGraphicsImpl::DrawTexture( GLuint nTexture, const SalTwoRect& pPosAry )
{ {
if( mnTextureProgram == 0 )
{
if( !CreateTextureProgram() )
return;
}
glUseProgram( mnTextureProgram );
glUniform1i( mnSamplerUniform, 0 );
glActiveTexture( GL_TEXTURE0 );
glBindTexture( GL_TEXTURE_2D, nTexture );
DrawTextureRect( pPosAry );
glBindTexture( GL_TEXTURE_2D, 0 );
glUseProgram( 0 );
}
void OpenGLSalGraphicsImpl::DrawTextureWithMask( GLuint nTexture, GLuint nMask, const SalTwoRect& pPosAry )
{
if( mnMaskedTextureProgram == 0 )
{
if( !CreateMaskedTextureProgram() )
return;
}
glUseProgram( mnMaskedTextureProgram );
glUniform1i( mnMaskedSamplerUniform, 0 );
glUniform1i( mnMaskSamplerUniform, 1 );
glActiveTexture( GL_TEXTURE0 );
glBindTexture( GL_TEXTURE_2D, nTexture );
glActiveTexture( GL_TEXTURE1 );
glBindTexture( GL_TEXTURE_2D, nMask );
DrawTextureRect( pPosAry );
glActiveTexture( GL_TEXTURE1 );
glBindTexture( GL_TEXTURE_2D, 0 );
glActiveTexture( GL_TEXTURE0 );
glBindTexture( GL_TEXTURE_2D, 0 );
glUseProgram( 0 );
} }
void OpenGLSalGraphicsImpl::drawPolyPolygon( sal_uInt32 /*nPoly*/, const sal_uInt32* /*pPoints*/, PCONSTSALPOINT* /*pPtAry*/ ) void OpenGLSalGraphicsImpl::DrawMask( GLuint nMask, SalColor nMaskColor, const SalTwoRect& pPosAry )
{ {
if( mnMaskProgram == 0 )
{
if( !CreateMaskProgram() )
return;
}
glUseProgram( mnMaskProgram );
glUniformColor( mnMaskColorUniform, nMaskColor, 0 );
glUniform1i( mnMaskUniform, 0 );
glActiveTexture( GL_TEXTURE0 );
glBindTexture( GL_TEXTURE_2D, nMask );
DrawTextureRect( pPosAry );
glActiveTexture( GL_TEXTURE0 );
glBindTexture( GL_TEXTURE_2D, 0 );
glUseProgram( 0 );
} }
// draw --> LineColor and FillColor and RasterOp and ClipRegion
void OpenGLSalGraphicsImpl::drawPixel( long nX, long nY )
{
if( mnLineColor != SALCOLOR_NONE )
{
BeginSolid( mnLineColor );
DrawPoint( nX, nY );
EndSolid();
}
}
void OpenGLSalGraphicsImpl::drawPixel( long nX, long nY, SalColor nSalColor )
{
if( nSalColor != SALCOLOR_NONE )
{
BeginSolid( nSalColor );
DrawPoint( nX, nY );
EndSolid();
}
}
void OpenGLSalGraphicsImpl::drawLine( long nX1, long nY1, long nX2, long nY2 )
{
if( mnLineColor != SALCOLOR_NONE )
{
BeginSolid( mnLineColor );
DrawLine( nX1, nY1, nX2, nY2 );
EndSolid();
}
}
void OpenGLSalGraphicsImpl::drawRect( long nX, long nY, long nWidth, long nHeight )
{
if( mnFillColor != SALCOLOR_NONE )
{
BeginSolid( mnFillColor );
DrawRect( nX, nY, nWidth, nHeight );
EndSolid();
}
if( mnLineColor != SALCOLOR_NONE )
{
const long nX1( nX );
const long nY1( nY );
const long nX2( nX + nWidth - 1 );
const long nY2( nY + nHeight - 1 );
const SalPoint aPoints[] = { { nX1, nY1 }, { nX2, nY1 },
{ nX2, nY2 }, { nX1, nY2 } };
BeginSolid( mnLineColor );
DrawLines( 4, aPoints, true );
EndSolid();
}
}
void OpenGLSalGraphicsImpl::drawPolyLine( sal_uInt32 nPoints, const SalPoint* pPtAry )
{
if( mnLineColor != SALCOLOR_NONE && nPoints > 1 )
{
BeginSolid( mnLineColor );
DrawLines( nPoints, pPtAry, false );
EndSolid();
}
}
void OpenGLSalGraphicsImpl::drawPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry )
{
if( nPoints == 0 )
return;
if( nPoints == 1 )
{
drawPixel( pPtAry[0].mnX, pPtAry[0].mnY );
return;
}
if( nPoints == 2 )
{
drawLine( pPtAry[0].mnX, pPtAry[0].mnY,
pPtAry[1].mnX, pPtAry[1].mnY );
return;
}
if( mnFillColor != SALCOLOR_NONE )
{
BeginSolid( mnFillColor );
DrawPolygon( nPoints, pPtAry );
EndSolid();
}
if( mnLineColor != SALCOLOR_NONE )
{
BeginSolid( mnLineColor );
DrawLines( nPoints, pPtAry, true );
EndSolid();
}
}
void OpenGLSalGraphicsImpl::drawPolyPolygon( sal_uInt32 nPoly, const sal_uInt32* pPoints, PCONSTSALPOINT* pPtAry )
{
if( nPoly <= 0 )
return;
if( mnFillColor != SALCOLOR_NONE )
{
BeginSolid( mnFillColor );
for( sal_uInt32 i = 0; i < nPoly; i++ )
DrawPolygon( pPoints[i], pPtAry[i] );
EndSolid();
}
if( mnLineColor != SALCOLOR_NONE )
{
// TODO Use glMultiDrawElements or primitive restart
BeginSolid( mnLineColor );
for( sal_uInt32 i = 0; i < nPoly; i++ )
DrawLines( pPoints[i], pPtAry[i], true );
EndSolid();
}
}
bool OpenGLSalGraphicsImpl::drawPolyPolygon( const ::basegfx::B2DPolyPolygon&, double /*fTransparency*/ ) bool OpenGLSalGraphicsImpl::drawPolyPolygon( const ::basegfx::B2DPolyPolygon&, double /*fTransparency*/ )
{ {
return false; return false;
...@@ -167,12 +752,34 @@ void OpenGLSalGraphicsImpl::copyArea( ...@@ -167,12 +752,34 @@ void OpenGLSalGraphicsImpl::copyArea(
// CopyBits and DrawBitmap --> RasterOp and ClipRegion // CopyBits and DrawBitmap --> RasterOp and ClipRegion
// CopyBits() --> pSrcGraphics == NULL, then CopyBits on same Graphics // CopyBits() --> pSrcGraphics == NULL, then CopyBits on same Graphics
void OpenGLSalGraphicsImpl::copyBits( const SalTwoRect& /*rPosAry*/, SalGraphics* /*pSrcGraphics*/ ) void OpenGLSalGraphicsImpl::copyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics )
{ {
// TODO Check if SalGraphicsImpl is the same
const bool bSameGraphics( false );
if( bSameGraphics &&
(rPosAry.mnSrcWidth == rPosAry.mnDestWidth) &&
(rPosAry.mnSrcHeight == rPosAry.mnDestHeight))
{
// short circuit if there is nothing to do
if( (rPosAry.mnSrcX == rPosAry.mnDestX) &&
(rPosAry.mnSrcY == rPosAry.mnDestY))
return;
// use copyArea() if source and destination context are identical
copyArea( rPosAry.mnDestX, rPosAry.mnDestY, rPosAry.mnSrcX, rPosAry.mnSrcY,
rPosAry.mnSrcWidth, rPosAry.mnSrcHeight, 0 );
return;
}
// TODO Copy from one FBO to the other (glBlitFramebuffer)
} }
void OpenGLSalGraphicsImpl::drawBitmap( const SalTwoRect& /*rPosAry*/, const SalBitmap& /*rSalBitmap*/ ) void OpenGLSalGraphicsImpl::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap )
{ {
const OpenGLSalBitmap& rBitmap = static_cast<const OpenGLSalBitmap&>(rSalBitmap);
GLuint nTexture = rBitmap.GetTexture();
DrawTexture( nTexture, rPosAry );
} }
void OpenGLSalGraphicsImpl::drawBitmap( void OpenGLSalGraphicsImpl::drawBitmap(
...@@ -180,42 +787,101 @@ void OpenGLSalGraphicsImpl::drawBitmap( ...@@ -180,42 +787,101 @@ void OpenGLSalGraphicsImpl::drawBitmap(
const SalBitmap& /*rSalBitmap*/, const SalBitmap& /*rSalBitmap*/,
SalColor /*nTransparentColor*/ ) SalColor /*nTransparentColor*/ )
{ {
OSL_FAIL( "::DrawBitmap with transparent color not supported" );
} }
void OpenGLSalGraphicsImpl::drawBitmap( void OpenGLSalGraphicsImpl::drawBitmap(
const SalTwoRect& /*rPosAry*/, const SalTwoRect& rPosAry,
const SalBitmap& /*rSalBitmap*/, const SalBitmap& rSalBitmap,
const SalBitmap& /*rMaskBitmap*/ ) const SalBitmap& rMaskBitmap )
{ {
const OpenGLSalBitmap& rBitmap = static_cast<const OpenGLSalBitmap&>(rSalBitmap);
const OpenGLSalBitmap& rMask = static_cast<const OpenGLSalBitmap&>(rMaskBitmap);
const GLuint nTexture( rBitmap.GetTexture() );
const GLuint nMask( rMask.GetTexture() );
DrawTextureWithMask( nTexture, nMask, rPosAry );
} }
void OpenGLSalGraphicsImpl::drawMask( void OpenGLSalGraphicsImpl::drawMask(
const SalTwoRect& /*rPosAry*/, const SalTwoRect& rPosAry,
const SalBitmap& /*rSalBitmap*/, const SalBitmap& rSalBitmap,
SalColor /*nMaskColor*/ ) SalColor nMaskColor )
{ {
const OpenGLSalBitmap& rBitmap = static_cast<const OpenGLSalBitmap&>(rSalBitmap);
const GLuint nTexture( rBitmap.GetTexture() );
DrawMask( nTexture, nMaskColor, rPosAry );
} }
SalBitmap* OpenGLSalGraphicsImpl::getBitmap( long /*nX*/, long /*nY*/, long /*nWidth*/, long /*nHeight*/ ) SalBitmap* OpenGLSalGraphicsImpl::getBitmap( long nX, long nY, long nWidth, long nHeight )
{ {
return NULL; GLuint nTexture;
/*glGenTexture( 1, &nTexture );
glBindTexture( GL_TEXTURE_2D, nTexture );
glCopyTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, nX, nY, nWidth, nHeight, 0 );
glBindTexture( GL_TEXTURE_2D, 0 );*/
OpenGLSalBitmap* pBitmap = new OpenGLSalBitmap;
if( !pBitmap->Create( nX, nY, nWidth, nHeight ) )
{
delete pBitmap;
pBitmap = NULL;
}
return pBitmap;
} }
SalColor OpenGLSalGraphicsImpl::getPixel( long /*nX*/, long /*nY*/ ) SalColor OpenGLSalGraphicsImpl::getPixel( long nX, long nY )
{ {
return 0; char pixel[3];
glReadPixels( nX, nY, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, pixel);
return MAKE_SALCOLOR( pixel[0], pixel[1], pixel[2] );
} }
// invert --> ClipRegion (only Windows or VirDevs) // invert --> ClipRegion (only Windows or VirDevs)
void OpenGLSalGraphicsImpl::invert( void OpenGLSalGraphicsImpl::invert(
long /*nX*/, long /*nY*/, long nX, long nY,
long /*nWidth*/, long /*nHeight*/, long nWidth, long nHeight,
SalInvert /*nFlags*/) SalInvert nFlags)
{ {
// TODO Figure out what are those:
// * SAL_INVERT_50 (50/50 pattern?)
// * SAL_INVERT_TRACKFRAME (dash-line rectangle?)
if( nFlags & SAL_INVERT_TRACKFRAME )
{
}
else if( nFlags & SAL_INVERT_50 )
{
}
else // just invert
{
BeginInvert();
DrawPolygon( 4, aPoints );
EndInvert();
}
} }
void OpenGLSalGraphicsImpl::invert( sal_uInt32 /*nPoints*/, const SalPoint* /*pPtAry*/, SalInvert /*nFlags*/ ) void OpenGLSalGraphicsImpl::invert( sal_uInt32 nPoints, const SalPoint* pPtAry, SalInvert nFlags )
{ {
if( nFlags & SAL_INVERT_TRACKFRAME )
{
}
else if( nFlags & SAL_INVERT_50 )
{
}
else // just invert
{
BeginInvert();
DrawPolygon( nPoints, pPtAry );
EndInvert();
}
} }
bool OpenGLSalGraphicsImpl::drawEPS( bool OpenGLSalGraphicsImpl::drawEPS(
...@@ -240,11 +906,17 @@ bool OpenGLSalGraphicsImpl::drawEPS( ...@@ -240,11 +906,17 @@ bool OpenGLSalGraphicsImpl::drawEPS(
compositing themselves compositing themselves
*/ */
bool OpenGLSalGraphicsImpl::drawAlphaBitmap( bool OpenGLSalGraphicsImpl::drawAlphaBitmap(
const SalTwoRect&, const SalTwoRect& rPosAry,
const SalBitmap& /*rSourceBitmap*/, const SalBitmap& rSalBitmap,
const SalBitmap& /*rAlphaBitmap*/ ) const SalBitmap& rAlphaBitmap )
{ {
return false; const OpenGLSalBitmap& rBitmap = static_cast<const OpenGLSalBitmap&>(rSalBitmap);
const OpenGLSalBitmap& rAlpha = static_cast<const OpenGLSalBitmap&>(rAlphaBitmap);
const GLuint nTexture( rBitmap.GetTexture() );
const GLuint nAlpha( rAlpha.GetTexture() );
DrawTextureWithMask( nTexture, nAlpha, rPosAry );
return true;
} }
/** draw transformed bitmap (maybe with alpha) where Null, X, Y define the coordinate system */ /** draw transformed bitmap (maybe with alpha) where Null, X, Y define the coordinate system */
...@@ -265,11 +937,18 @@ bool OpenGLSalGraphicsImpl::drawTransformedBitmap( ...@@ -265,11 +937,18 @@ bool OpenGLSalGraphicsImpl::drawTransformedBitmap(
fully transparent rectangle fully transparent rectangle
*/ */
bool OpenGLSalGraphicsImpl::drawAlphaRect( bool OpenGLSalGraphicsImpl::drawAlphaRect(
long /*nX*/, long /*nY*/, long nX, long nY,
long /*nWidth*/, long /*nHeight*/, long nWidth, long nHeight,
sal_uInt8 /*nTransparency*/ ) sal_uInt8 nTransparency )
{ {
return false; if( mnFillColor != SALCOLOR_NONE && nTransparency < 100 )
{
BeginSolid( mnFillColor, nTransparency );
DrawRect( nX, nY, nWidth, nHeight );
EndSolid();
}
return true;
} }
bool OpenGLSalGraphicsImpl::drawGradient(const tools::PolyPolygon& /*rPolygon*/, bool OpenGLSalGraphicsImpl::drawGradient(const tools::PolyPolygon& /*rPolygon*/,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment