LCOV - code coverage report
Current view: top level - chart2/source/view/main - OpenGLRender.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 0 741 0.0 %
Date: 2014-04-11 Functions: 0 39 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  */
       9             : 
      10             : #include <GL/glew.h>
      11             : #include <vector>
      12             : #include "OpenGLRender.hxx"
      13             : #include <vcl/bmpacc.hxx>
      14             : #include <vcl/graph.hxx>
      15             : #include <com/sun/star/awt/XBitmap.hpp>
      16             : #include <com/sun/star/beans/XPropertySet.hpp>
      17             : #include <com/sun/star/graphic/XGraphic.hpp>
      18             : #include <comphelper/InlineContainer.hxx>
      19             : #include <com/sun/star/beans/XPropertySet.hpp>
      20             : #include <com/sun/star/drawing/CircleKind.hpp>
      21             : #include <com/sun/star/drawing/DoubleSequence.hpp>
      22             : #include <com/sun/star/drawing/FlagSequence.hpp>
      23             : #include <com/sun/star/drawing/FillStyle.hpp>
      24             : #include <com/sun/star/drawing/LineStyle.hpp>
      25             : #include <com/sun/star/drawing/NormalsKind.hpp>
      26             : #include <com/sun/star/drawing/PointSequence.hpp>
      27             : #include <com/sun/star/drawing/PolygonKind.hpp>
      28             : #include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp>
      29             : #include <com/sun/star/drawing/ProjectionMode.hpp>
      30             : #include <com/sun/star/drawing/ShadeMode.hpp>
      31             : #include <com/sun/star/drawing/TextFitToSizeType.hpp>
      32             : #include <com/sun/star/drawing/TextureProjectionMode.hpp>
      33             : #include <com/sun/star/text/XText.hpp>
      34             : #include <com/sun/star/uno/Any.hxx>
      35             : #include <vcl/virdev.hxx>
      36             : #include <vcl/dibtools.hxx>
      37             : 
      38             : #include <osl/file.hxx>
      39             : #include <rtl/bootstrap.hxx>
      40             : #include <config_folders.h>
      41             : 
      42             : #include <boost/scoped_array.hpp>
      43             : 
      44             : using namespace com::sun::star;
      45             : 
      46             : using namespace std;
      47             : 
      48             : #define DEBUG_PNG 0
      49             : #if RENDER_TO_FILE
      50             : #define BMP_HEADER_LEN 54
      51             : #endif
      52             : 
      53             : #if DEBUG_PNG
      54             : #include <vcl/pngwrite.hxx>
      55             : #endif
      56             : 
      57             : #define GL_PI 3.14159f
      58             : 
      59             : #if defined( _WIN32 )
      60             : #define WGL_SAMPLE_BUFFERS_ARB   0x2041
      61             : #define WGL_SAMPLES_ARB          0x2042
      62             : #endif
      63             : 
      64             : #define Z_STEP 0.001f
      65             : 
      66           0 : int static checkGLError(const char *file, int line)
      67             : {
      68             :     GLenum glErr;
      69           0 :     int retCode = 0;
      70           0 :     glErr = glGetError();
      71           0 :     while (glErr != GL_NO_ERROR)
      72             :     {
      73           0 :         const GLubyte* sError = gluErrorString(glErr);
      74             : 
      75           0 :         if (sError)
      76             :             SAL_WARN("chart2.opengl", "GL Error #" << glErr << "(" << gluErrorString(glErr) << ") " << " in File " << file << " at line: " << line);
      77             :         else
      78             :             SAL_WARN("chart2.opengl", "GL Error #" << glErr << " (no message available)" << " in File " << file << " at line: " << line);
      79             : 
      80           0 :         retCode = -1;
      81           0 :         return retCode;
      82             :     }
      83           0 :     return retCode;
      84             : }
      85             : 
      86             : static bool bGlewInit = false;
      87             : 
      88             : #define CHECK_GL_ERROR() checkGLError(__FILE__, __LINE__)
      89             : 
      90             : #define CHECK_GL_FRAME_BUFFER_STATUS() \
      91             :     status = glCheckFramebufferStatus(GL_FRAMEBUFFER);\
      92             :     if( status != GL_FRAMEBUFFER_COMPLETE ) {\
      93             :         SAL_WARN("chart2.opengl", "OpenGL error: " << status );\
      94             :         return -1;\
      95             :     }
      96             : 
      97             : namespace {
      98             : 
      99           0 : OUString getShaderFolder()
     100             : {
     101           0 :     OUString aUrl("$BRAND_BASE_DIR/" LIBO_ETC_FOLDER);
     102           0 :     rtl::Bootstrap::expandMacros(aUrl);
     103             : 
     104           0 :     return aUrl + "/opengl/";
     105             : }
     106             : 
     107           0 : OUString maShaderFolder = getShaderFolder();
     108             : 
     109           0 : OString loadShader(const OUString& rFilename)
     110             : {
     111           0 :     OUString aFileURL = maShaderFolder + rFilename +".glsl";
     112           0 :     osl::File aFile(aFileURL);
     113           0 :     if(aFile.open(osl_File_OpenFlag_Read) == osl::FileBase::E_None)
     114             :     {
     115           0 :         sal_uInt64 nSize = 0;
     116           0 :         aFile.getSize(nSize);
     117           0 :         char* content = new char[nSize+1];
     118           0 :         sal_uInt64 nBytesRead = 0;
     119           0 :         aFile.read(content, nSize, nBytesRead);
     120           0 :         if(nSize != nBytesRead)
     121             :             assert(false);
     122             : 
     123           0 :         content[nSize] = 0;
     124           0 :         return OString(content);
     125             :     }
     126             :     else
     127             :     {
     128             :         SAL_WARN("chart2.opengl", "could not load the file: " << aFileURL);
     129             :     }
     130             : 
     131           0 :     return OString();
     132             : }
     133             : 
     134             : }
     135             : 
     136           0 : GLint OpenGLRender::LoadShaders(const OUString& rVertexShaderName,const OUString& rFragmentShaderName)
     137             : {
     138             :     // Create the shaders
     139           0 :     GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
     140           0 :     GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
     141             : 
     142           0 :     GLint Result = GL_FALSE;
     143             :     int InfoLogLength;
     144             : 
     145             :     // Compile Vertex Shader
     146           0 :     OString aVertexShaderSource = loadShader(rVertexShaderName);
     147           0 :     char const * VertexSourcePointer = aVertexShaderSource.getStr();
     148           0 :     glShaderSource(VertexShaderID, 1, &VertexSourcePointer , NULL);
     149           0 :     glCompileShader(VertexShaderID);
     150             : 
     151             :     // Check Vertex Shader
     152           0 :     glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);
     153           0 :     if ( !Result )
     154             :     {
     155           0 :         glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
     156           0 :         if ( InfoLogLength > 0 )
     157             :         {
     158           0 :             std::vector<char> VertexShaderErrorMessage(InfoLogLength+1);
     159           0 :             glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]);
     160           0 :             VertexShaderErrorMessage.push_back('\0');
     161           0 :             SAL_WARN("chart2.opengl", "vertex shader compile failed : " << &VertexShaderErrorMessage[0]);
     162             :         }
     163             :         else
     164             :             SAL_WARN("chart2.opengl", "vertex shader compile failed without error log");
     165             : 
     166           0 :         return 0;
     167             :     }
     168             : 
     169             :     // Compile Fragment Shader
     170           0 :     OString aFragmentShaderSource = loadShader(rFragmentShaderName);
     171           0 :     char const * FragmentSourcePointer = aFragmentShaderSource.getStr();
     172           0 :     glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer , NULL);
     173           0 :     glCompileShader(FragmentShaderID);
     174             : 
     175             :     // Check Fragment Shader
     176           0 :     glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);
     177           0 :     if ( !Result )
     178             :     {
     179           0 :         glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
     180           0 :         if ( InfoLogLength > 0 )
     181             :         {
     182           0 :             std::vector<char> FragmentShaderErrorMessage(InfoLogLength+1);
     183           0 :             glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]);
     184           0 :             FragmentShaderErrorMessage.push_back('\0');
     185           0 :             SAL_WARN("chart2.opengl", "fragment shader compile failed : " << &FragmentShaderErrorMessage[0]);
     186             :         }
     187             :         else
     188             :             SAL_WARN("chart2.opengl", "fragment shader compile failed without error log");
     189             : 
     190             : 
     191           0 :         return 0;
     192             :     }
     193             : 
     194             :     // Link the program
     195           0 :     GLint ProgramID = glCreateProgram();
     196           0 :     glAttachShader(ProgramID, VertexShaderID);
     197           0 :     glAttachShader(ProgramID, FragmentShaderID);
     198           0 :     glLinkProgram(ProgramID);
     199             : 
     200             :     // Check the program
     201           0 :     glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
     202           0 :     if ( !Result )
     203             :     {
     204           0 :         glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
     205           0 :         if ( InfoLogLength > 0 )
     206             :         {
     207           0 :             std::vector<char> ProgramErrorMessage(InfoLogLength+1);
     208           0 :             glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]);
     209           0 :             ProgramErrorMessage.push_back('\0');
     210           0 :             SAL_WARN("chart2.opengl", "Shader Program failed : " << &ProgramErrorMessage[0]);
     211             :         }
     212             :         else
     213             :             SAL_WARN("chart2.opengl", "shader program link failed without error log");
     214             : 
     215           0 :         return 0;
     216             :     }
     217             : 
     218           0 :     glDeleteShader(VertexShaderID);
     219           0 :     glDeleteShader(FragmentShaderID);
     220             : 
     221           0 :     return ProgramID;
     222             : }
     223             : 
     224             : namespace {
     225             : 
     226             : GLfloat texCoords[] = {
     227             :     0.0f, 0.0f,
     228             :     1.0f, 0.0f,
     229             :     1.0f, 1.0f,
     230             :     0.0f, 1.0f
     231             : };
     232             : 
     233             : }
     234             : 
     235           0 : int OpenGLRender::InitOpenGL()
     236             : {
     237             :     //TODO: moggi: get the information from the context
     238           0 :     mbArbMultisampleSupported = true;
     239           0 :     if(!bGlewInit)
     240             :     {
     241           0 :         glewExperimental = GL_TRUE;
     242           0 :         if (glewInit() != GLEW_OK)
     243             :         {
     244             :             SAL_WARN("chart2.opengl", "Failed to initialize GLEW");
     245           0 :             return -1;
     246             :         }
     247             :         else
     248           0 :             bGlewInit = true;
     249             :     }
     250             : 
     251             :     // These guys don't just check support but setup the vtables.
     252           0 :     if (glewIsSupported("framebuffer_object") != GLEW_OK)
     253             :     {
     254             :         SAL_WARN("chart2.opengl", "GL stack has no framebuffer support");
     255           0 :         return -1;
     256             :     }
     257             : 
     258           0 :     glEnable(GL_TEXTURE_2D);
     259           0 :     glEnable(GL_CULL_FACE);
     260           0 :     glCullFace(GL_BACK);
     261           0 :     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
     262             :     // Enable depth test
     263           0 :     glEnable(GL_DEPTH_TEST);
     264             :     // Accept fragment if it closer to the camera than the former one
     265           0 :     glDepthFunc(GL_LESS);
     266           0 :     glEnable(GL_POINT_SMOOTH);
     267           0 :     glEnable(GL_LINE_SMOOTH);
     268           0 :     glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
     269           0 :     glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
     270           0 :     glEnable(GL_BLEND);
     271           0 :     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
     272             : 
     273           0 :     glClearColor (1.0, 1.0, 1.0, 1.0);
     274           0 :     glClear(GL_COLOR_BUFFER_BIT);
     275           0 :     glClearDepth(1.0f);
     276           0 :     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     277             : 
     278             :     //Init the Projection matrix
     279           0 :     m_Projection = glm::ortho(0.f, float(m_iWidth), 0.f, float(m_iHeight), -1.f, 1.f);
     280           0 :     m_View       = glm::lookAt(glm::vec3(0,0,1), // Camera is at (4,3,-3), in World Space
     281             :                                glm::vec3(0,0,0), // and looks at the origin
     282             :                                glm::vec3(0,1,0)  // Head is up (set to 0,-1,0 to look upside-down)
     283           0 :                                );
     284           0 :     m_MVP = m_Projection * m_View * m_Model;
     285           0 :     glGenBuffers(1, &m_VertexBuffer);
     286           0 :     glGenBuffers(1, &m_ColorBuffer);
     287             : 
     288           0 :     CHECK_GL_ERROR();
     289             : 
     290           0 :     m_CommonProID = LoadShaders("commonVertexShader", "commonFragmentShader");
     291           0 :     m_MatrixID = glGetUniformLocation(m_CommonProID, "MVP");
     292           0 :     m_2DVertexID = glGetAttribLocation(m_CommonProID, "vPosition");
     293           0 :     m_2DColorID = glGetUniformLocation(m_CommonProID, "vColor");
     294           0 :     CHECK_GL_ERROR();
     295             : 
     296             : #if DEBUG_POSITIONING
     297             :     m_DebugProID = LoadShaders("debugVertexShader", "debugFragmentShader");
     298             :     m_DebugVertexID = glGetAttribLocation(m_DebugProID, "vPosition");
     299             :     CHECK_GL_ERROR();
     300             : #endif
     301             : 
     302           0 :     m_BackgroundProID = LoadShaders("backgroundVertexShader", "backgroundFragmentShader");
     303           0 :     m_BackgroundMatrixID = glGetUniformLocation(m_BackgroundProID, "MVP");
     304           0 :     m_BackgroundVertexID = glGetAttribLocation(m_BackgroundProID, "vPosition");
     305           0 :     m_BackgroundColorID = glGetAttribLocation(m_BackgroundProID, "vColor");
     306             : 
     307           0 :     CHECK_GL_ERROR();
     308             : 
     309           0 :     m_SymbolProID = LoadShaders("symbolVertexShader", "symbolFragmentShader");
     310           0 :     m_SymbolVertexID = glGetAttribLocation(m_SymbolProID, "vPosition");
     311           0 :     m_SymbolMatrixID = glGetUniformLocation(m_SymbolProID, "MVP");
     312           0 :     m_SymbolColorID = glGetUniformLocation(m_SymbolProID, "vColor");
     313           0 :     m_SymbolShapeID = glGetUniformLocation(m_SymbolProID, "shape");
     314             : 
     315           0 :     CHECK_GL_ERROR();
     316             : 
     317           0 :     m_TextProID = LoadShaders("textVertexShader", "textFragmentShader");
     318           0 :     m_TextMatrixID = glGetUniformLocation(m_TextProID, "MVP");
     319           0 :     m_TextVertexID = glGetAttribLocation(m_TextProID, "vPosition");
     320           0 :     m_TextTexCoordID = glGetAttribLocation(m_TextProID, "texCoord");
     321           0 :     m_TextTexID = glGetUniformLocation(m_TextProID, "TextTex");
     322             : 
     323           0 :     CHECK_GL_ERROR();
     324             : 
     325           0 :     glGenBuffers(1, &m_TextTexCoordBuf);
     326           0 :     glBindBuffer(GL_ARRAY_BUFFER, m_TextTexCoordBuf);
     327           0 :     glBufferData(GL_ARRAY_BUFFER, sizeof(texCoords), texCoords, GL_STATIC_DRAW);
     328           0 :     glBindBuffer(GL_ARRAY_BUFFER, 0);
     329             : 
     330           0 :     glEnable(GL_LIGHTING);
     331           0 :     GLfloat light_direction[] = { 0.0 , 0.0 , 1.0 };
     332           0 :     GLfloat materialDiffuse[] = { 1.0 , 1.0 , 1.0 , 1.0};
     333           0 :     glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, light_direction);
     334           0 :     glMaterialfv(GL_FRONT,GL_DIFFUSE,materialDiffuse);
     335           0 :     glEnable(GL_LIGHT0);
     336           0 :     glEnable(GL_NORMALIZE);
     337             : 
     338           0 :     return 0;
     339             : }
     340             : 
     341           0 : BitmapEx OpenGLRender::GetAsBitmap()
     342             : {
     343           0 :     boost::scoped_array<sal_uInt8> buf(new sal_uInt8[m_iWidth * m_iHeight * 4]);
     344           0 :     glReadPixels(0, 0, m_iWidth, m_iHeight, GL_BGRA, GL_UNSIGNED_BYTE, buf.get());
     345             : 
     346           0 :     Bitmap aBitmap( Size(m_iWidth, m_iHeight), 24 );
     347           0 :     AlphaMask aAlpha( Size(m_iWidth, m_iHeight) );
     348             : 
     349             :     {
     350           0 :         Bitmap::ScopedWriteAccess pWriteAccess( aBitmap );
     351           0 :         AlphaMask::ScopedWriteAccess pAlphaWriteAccess( aAlpha );
     352             : 
     353           0 :         size_t nCurPos = 0;
     354           0 :         for( int y = 0; y < m_iHeight; ++y)
     355             :         {
     356           0 :             Scanline pScan = pWriteAccess->GetScanline(y);
     357           0 :             Scanline pAlphaScan = pAlphaWriteAccess->GetScanline(y);
     358           0 :             for( int x = 0; x < m_iWidth; ++x )
     359             :             {
     360           0 :                 *pScan++ = buf[nCurPos];
     361           0 :                 *pScan++ = buf[nCurPos+1];
     362           0 :                 *pScan++ = buf[nCurPos+2];
     363             : 
     364           0 :                 nCurPos += 3;
     365           0 :                 *pAlphaScan++ = static_cast<sal_uInt8>( 255 - buf[nCurPos++] );
     366             :             }
     367           0 :         }
     368             :     }
     369             : 
     370           0 :     BitmapEx aBmp(aBitmap, aAlpha);
     371             : 
     372             : #if DEBUG_PNG // debug PNG writing
     373             :     static int nIdx = 0;
     374             :     OUString aName = OUString( "file:///home/moggi/Documents/work/" ) + OUString::number( nIdx++ ) + ".png";
     375             :     try {
     376             :         vcl::PNGWriter aWriter( aBmp );
     377             :         SvFileStream sOutput( aName, STREAM_WRITE );
     378             :         aWriter.Write( sOutput );
     379             :         sOutput.Close();
     380             :     } catch (...) {
     381             :         SAL_WARN("chart2.opengl", "Error writing png to " << aName);
     382             :     }
     383             : #endif
     384             : 
     385           0 :     return aBmp;
     386             : }
     387             : 
     388           0 : int OpenGLRender::SetLine2DShapePoint(float x, float y, int listLength)
     389             : {
     390           0 :     if (m_Line2DPointList.empty())
     391             :     {
     392           0 :         m_Line2DPointList.reserve(listLength*3);
     393             :     }
     394           0 :     float actualX = (x / OPENGL_SCALE_VALUE);
     395           0 :     float actualY = (y / OPENGL_SCALE_VALUE);
     396           0 :     m_Line2DPointList.push_back(actualX);
     397           0 :     m_Line2DPointList.push_back(actualY);
     398           0 :     m_Line2DPointList.push_back(m_fZStep);
     399             : 
     400           0 :     if (m_Line2DPointList.size() == size_t(listLength * 3))
     401             :     {
     402           0 :         m_Line2DShapePointList.push_back(m_Line2DPointList);
     403           0 :         m_Line2DPointList.clear();
     404             :     }
     405           0 :     return 0;
     406             : }
     407             : 
     408           0 : int OpenGLRender::RenderLine2FBO(int)
     409             : {
     410           0 :     CHECK_GL_ERROR();
     411           0 :     glLineWidth(m_fLineWidth);
     412           0 :     size_t listNum = m_Line2DShapePointList.size();
     413           0 :     PosVecf3 trans = {0.0f, 0.0f, 0.0f};
     414           0 :     PosVecf3 angle = {0.0f, 0.0f, 0.0f};
     415           0 :     PosVecf3 scale = {1.0f, 1.0f, 1.0f};
     416           0 :     MoveModelf(trans, angle, scale);
     417           0 :     m_MVP = m_Projection * m_View * m_Model;
     418           0 :     for (size_t i = 0; i < listNum; i++)
     419             :     {
     420           0 :         Line2DPointList &pointList = m_Line2DShapePointList.front();
     421             :         //fill vertex buffer
     422           0 :         glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer);
     423           0 :         CHECK_GL_ERROR();
     424           0 :         glBufferData(GL_ARRAY_BUFFER, pointList.size() * sizeof(float), &pointList[0], GL_STATIC_DRAW);
     425           0 :         CHECK_GL_ERROR();
     426             :         // Use our shader
     427           0 :         glUseProgram(m_CommonProID);
     428           0 :         CHECK_GL_ERROR();
     429             : 
     430           0 :         glUniform4fv(m_2DColorID, 1, &m_2DColor[0]);
     431           0 :         CHECK_GL_ERROR();
     432           0 :         glUniformMatrix4fv(m_MatrixID, 1, GL_FALSE, &m_MVP[0][0]);
     433             :         //CHECK_GL_ERROR();
     434             : 
     435             :         // 1rst attribute buffer : vertices
     436           0 :         CHECK_GL_ERROR();
     437             :         glVertexAttribPointer(
     438             :             m_2DVertexID,
     439             :             3,                  // size
     440             :             GL_FLOAT,           // type
     441             :             GL_FALSE,           // normalized?
     442             :             0,                  // stride
     443             :             (void*)0            // array buffer offset
     444           0 :             );
     445           0 :         glEnableVertexAttribArray(m_2DVertexID);
     446           0 :         glDrawArrays(GL_LINE_STRIP, 0, pointList.size()/3); // 12*3 indices starting at 0 -> 12 triangles
     447           0 :         CHECK_GL_ERROR();
     448           0 :         glUseProgram(0);
     449           0 :         glDisableVertexAttribArray(m_2DVertexID);
     450           0 :         CHECK_GL_ERROR();
     451           0 :         m_Line2DShapePointList.pop_front();
     452             :     }
     453             :     GLenum status;
     454           0 :     CHECK_GL_ERROR();
     455           0 :     CHECK_GL_FRAME_BUFFER_STATUS();
     456           0 :     m_fZStep += Z_STEP;
     457           0 :     return 0;
     458             : }
     459             : 
     460             : #if DEBUG_POSITIONING
     461             : void OpenGLRender::renderDebug()
     462             : {
     463             :     CHECK_GL_ERROR();
     464             : 
     465             :     GLfloat vertices[4][3] = {
     466             :         {-0.9, -0.9, 0 },
     467             :         {-0.6, -0.2, 0 },
     468             :         {0.3, 0.3, 0 },
     469             :         {0.9, 0.9, 0 } };
     470             : 
     471             :     glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer);
     472             :     CHECK_GL_ERROR();
     473             :     glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
     474             :     CHECK_GL_ERROR();
     475             :     glUseProgram(m_DebugProID);
     476             :     CHECK_GL_ERROR();
     477             :     glVertexAttribPointer(m_DebugVertexID, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
     478             :     CHECK_GL_ERROR();
     479             :     glEnableVertexAttribArray(m_DebugVertexID);
     480             : 
     481             :     glDrawArrays(GL_LINE_STRIP, 0, 3);
     482             :     CHECK_GL_ERROR();
     483             :     glDisableVertexAttribArray(m_DebugVertexID);
     484             : 
     485             :     CHECK_GL_ERROR();
     486             : }
     487             : #endif
     488             : 
     489           0 : void OpenGLRender::prepareToRender()
     490             : {
     491           0 :     glViewport(0, 0, m_iWidth, m_iHeight);
     492           0 :     if (!m_FboID)
     493             :     {
     494             :         // create a texture object
     495           0 :         CreateTextureObj(m_iWidth, m_iHeight);
     496             :         //create render buffer object
     497           0 :         CreateRenderObj(m_iWidth, m_iHeight);
     498             :         //create fbo
     499           0 :         CreateFrameBufferObj();
     500           0 :         if (mbArbMultisampleSupported)
     501             :         {
     502           0 :             CreateMultiSampleFrameBufObj();
     503             :         }
     504             :     }
     505             :     //bind fbo
     506           0 :     if (mbArbMultisampleSupported)
     507             :     {
     508           0 :         glBindFramebuffer(GL_FRAMEBUFFER,m_frameBufferMS);
     509             :     }
     510             :     else
     511             :     {
     512           0 :         glBindFramebuffer(GL_FRAMEBUFFER, m_FboID);
     513             :     }
     514             : 
     515             :     // Clear the screen
     516           0 :     glClearDepth(1.0f);
     517           0 :     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     518           0 :     m_fZStep = 0;
     519           0 : }
     520             : 
     521           0 : void OpenGLRender::renderToBitmap()
     522             : {
     523           0 :     if (mbArbMultisampleSupported)
     524             :     {
     525             :         GLenum status;
     526           0 :         glBindFramebuffer(GL_FRAMEBUFFER, 0);
     527           0 :         glBindFramebuffer(GL_READ_FRAMEBUFFER, m_frameBufferMS);
     528           0 :         status = glCheckFramebufferStatus(GL_READ_FRAMEBUFFER);
     529           0 :         if (status != GL_FRAMEBUFFER_COMPLETE)
     530             :         {
     531             :             SAL_INFO("chart2.opengl", "The frame buffer status is not complete!");
     532             :         }
     533           0 :         glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_FboID);
     534           0 :         status = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
     535           0 :         if (status != GL_FRAMEBUFFER_COMPLETE)
     536             :         {
     537             :             SAL_INFO("chart2.opengl", "The frame buffer status is not complete!");
     538             :         }
     539           0 :         glBlitFramebuffer(0, 0 ,m_iWidth, m_iHeight, 0, 0,m_iWidth ,m_iHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR);
     540           0 :         glBindFramebuffer(GL_READ_FRAMEBUFFER,0);
     541           0 :         glBindFramebuffer(GL_DRAW_FRAMEBUFFER,0);
     542             :     }
     543           0 :     glBindFramebuffer(GL_FRAMEBUFFER, m_FboID);
     544             : 
     545             : #if RENDER_TO_FILE
     546             :     char fileName[256] = {0};
     547             :     sprintf(fileName, "D:\\shaderout_%d_%d.bmp", m_iWidth, m_iHeight);
     548             :     sal_uInt8 *buf = (sal_uInt8 *)malloc(m_iWidth * m_iHeight * 3 + BMP_HEADER_LEN);
     549             :     CreateBMPHeader(buf, m_iWidth, m_iHeight);
     550             :     glReadPixels(0, 0, m_iWidth, m_iHeight, GL_BGR, GL_UNSIGNED_BYTE, buf + BMP_HEADER_LEN);
     551             :     FILE *pfile = fopen(fileName,"wb");
     552             :     fwrite(buf,m_iWidth * m_iHeight * 3 + BMP_HEADER_LEN, 1, pfile);
     553             :     free(buf);
     554             :     fclose(pfile);
     555             : #else
     556           0 :     Graphic aGraphic( GetAsBitmap() );
     557           0 :     uno::Reference< awt::XBitmap> xBmp( aGraphic.GetXGraphic(), uno::UNO_QUERY );
     558           0 :     uno::Reference < beans::XPropertySet > xPropSet ( mxRenderTarget, uno::UNO_QUERY );
     559           0 :     xPropSet->setPropertyValue("Graphic", uno::makeAny(aGraphic.GetXGraphic()));
     560           0 :     mxRenderTarget->setSize(awt::Size(m_iWidth*OPENGL_SCALE_VALUE, m_iHeight*OPENGL_SCALE_VALUE));
     561           0 :     mxRenderTarget->setPosition(awt::Point(0,0));
     562             : #endif
     563           0 :     glBindFramebuffer(GL_FRAMEBUFFER, 0);
     564           0 : }
     565             : 
     566           0 : int OpenGLRender::CreateTextureObj(int width, int height)
     567             : {
     568           0 :     glGenTextures(1, &m_TextureObj);
     569           0 :     glBindTexture(GL_TEXTURE_2D, m_TextureObj);
     570           0 :     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
     571           0 :     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
     572           0 :     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
     573           0 :     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
     574           0 :     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
     575           0 :     CHECK_GL_ERROR();
     576           0 :     glBindTexture(GL_TEXTURE_2D, 0);
     577           0 :     return 0;
     578             : }
     579             : 
     580           0 : int OpenGLRender::CreateRenderObj(int width, int height)
     581             : {
     582           0 :     glGenRenderbuffers(1, &m_RboID);
     583           0 :     CHECK_GL_ERROR();
     584           0 :     glBindRenderbuffer(GL_RENDERBUFFER, m_RboID);
     585           0 :     CHECK_GL_ERROR();
     586           0 :     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height);
     587           0 :     CHECK_GL_ERROR();
     588           0 :     glBindRenderbuffer(GL_RENDERBUFFER, 0);
     589           0 :     CHECK_GL_ERROR();
     590           0 :     return 0;
     591             : }
     592             : 
     593           0 : int OpenGLRender::MoveModelf(PosVecf3 trans, PosVecf3 angle, PosVecf3 scale)
     594             : {
     595           0 :     glm::mat4 aTranslationMatrix = glm::translate(glm::vec3(trans.x, trans.y, trans.z));
     596           0 :     glm::mat4 aScaleMatrix = glm::scale(glm::vec3(scale.x, scale.y, scale.z));
     597           0 :     glm::mat4 aRotationMatrix = glm::eulerAngleYXZ(angle.y, angle.x, angle.z);
     598           0 :     m_Model = aTranslationMatrix * aRotationMatrix * aScaleMatrix;
     599           0 :     return 0;
     600             : }
     601             : 
     602           0 : int OpenGLRender::CreateFrameBufferObj()
     603             : {
     604             :     GLenum status;
     605             :     // create a framebuffer object, you need to delete them when program exits.
     606           0 :     glGenFramebuffers(1, &m_FboID);
     607           0 :     CHECK_GL_FRAME_BUFFER_STATUS();
     608           0 :     glBindFramebuffer(GL_FRAMEBUFFER, m_FboID);
     609           0 :     glBindTexture(GL_TEXTURE_2D, m_TextureObj);
     610             :     // attach a texture to FBO color attachement point
     611           0 :     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_TextureObj, 0);
     612           0 :     CHECK_GL_FRAME_BUFFER_STATUS();
     613           0 :     glBindTexture(GL_TEXTURE_2D, 0);
     614             :     // attach a renderbuffer to depth attachment point
     615           0 :     glBindRenderbuffer(GL_RENDERBUFFER, m_RboID);
     616           0 :     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_RboID);
     617           0 :     CHECK_GL_FRAME_BUFFER_STATUS();
     618           0 :     glBindRenderbuffer(GL_RENDERBUFFER, 0);
     619           0 :     glBindFramebuffer(GL_FRAMEBUFFER, 0);
     620             : 
     621           0 :     return 0;
     622             : }
     623             : 
     624           0 : void OpenGLRender::Release()
     625             : {
     626           0 :     glDeleteBuffers(1, &m_VertexBuffer);
     627           0 :     glDeleteBuffers(1, &m_ColorBuffer);
     628           0 :     glDeleteBuffers(1, &m_TextTexCoordBuf);
     629           0 :     glDeleteProgram(m_CommonProID);
     630           0 :     glDeleteProgram(m_TextProID);
     631           0 :     glDeleteProgram(m_BackgroundProID);
     632           0 :     glDeleteProgram(m_SymbolProID);
     633           0 :     glDeleteFramebuffers(1, &m_FboID);
     634           0 :     glDeleteFramebuffers(1, &m_frameBufferMS);
     635           0 :     glDeleteTextures(1, &m_TextureObj);
     636           0 :     glDeleteRenderbuffers(1, &m_RboID);
     637           0 :     glDeleteRenderbuffers(1, &m_renderBufferColorMS);
     638           0 :     glDeleteRenderbuffers(1, &m_renderBufferDepthMS);
     639           0 : }
     640             : 
     641           0 : OpenGLRender::OpenGLRender(uno::Reference< drawing::XShape > xTarget)
     642             :     : m_Model(glm::mat4(1.0f))
     643             :     , m_TextureObj(0)
     644             :     , m_FboID(0)
     645             :     , m_RboID(0)
     646             :     , m_iWidth(0)
     647             :     , m_iHeight(0)
     648             :     , m_fLineWidth(0.001f)
     649             :     , mxRenderTarget(xTarget)
     650             :     , mbArbMultisampleSupported(false)
     651             : #if defined( _WIN32 )
     652             :     , m_iArbMultisampleFormat(0)
     653             : #endif
     654             :     , m_2DColor(glm::vec4(1.0, 0.0, 0.0, 1.0))
     655             :     , m_frameBufferMS(0)
     656             :     , m_renderBufferColorMS(0)
     657             :     , m_renderBufferDepthMS(0)
     658             :     , m_CommonProID(0)
     659             :     , m_2DVertexID(0)
     660             :     , m_2DColorID(0)
     661             :     , m_fZStep(0)
     662             :     , m_TextProID(0)
     663             :     , m_TextMatrixID(0)
     664             :     , m_TextVertexID(0)
     665             :     , m_TextTexCoordID(0)
     666             :     , m_TextTexCoordBuf(0)
     667             :     , m_TextTexID(0)
     668             :     , m_BackgroundProID(0)
     669             :     , m_BackgroundMatrixID(0)
     670             :     , m_BackgroundVertexID(0)
     671             :     , m_BackgroundColorID(0)
     672             :     , m_SymbolProID(0)
     673             :     , m_SymbolVertexID(0)
     674             :     , m_SymbolMatrixID(0)
     675             :     , m_SymbolColorID(0)
     676           0 :     , m_SymbolShapeID(0)
     677             : {
     678             :     //TODO: moggi: use STL
     679           0 :     memset(&m_Bubble2DCircle, 0, sizeof(m_Bubble2DCircle));
     680             : 
     681             :     //TODO: moggi: use STL
     682           0 :     for (size_t i = 0; i < sizeof(m_BackgroundColor) / sizeof(float); i++)
     683             :     {
     684           0 :         m_BackgroundColor[i] = 1.0;
     685             :     }
     686             : 
     687           0 :     mxRenderTarget->setPosition(awt::Point(0,0));
     688           0 : }
     689             : 
     690           0 : OpenGLRender::~OpenGLRender()
     691             : {
     692           0 :     Release();
     693           0 : }
     694             : 
     695             : // TODO: moggi: that screws up FBO if called after buffers have been created!!!!
     696           0 : void OpenGLRender::SetSize(int width, int height)
     697             : {
     698           0 :     m_iWidth = width;
     699           0 :     m_iHeight = height;
     700           0 :     m_Projection = glm::ortho(0.f, float(m_iWidth), 0.f, float(m_iHeight), -4.f, 3.f);
     701           0 : }
     702             : 
     703             : #if RENDER_TO_FILE
     704             : int OpenGLRender::CreateBMPHeader(sal_uInt8 *bmpHeader, int xsize, int ysize)
     705             : {
     706             :     unsigned char header[BMP_HEADER_LEN] = {
     707             :         0x42, 0x4d, 0, 0, 0, 0, 0, 0, 0, 0,
     708             :         54, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 24, 0,
     709             :         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
     710             :         0, 0, 0, 0
     711             :     };
     712             : 
     713             :     long file_size = (long)xsize * (long)ysize * 3 + 54;
     714             :     header[2] = (unsigned char)(file_size &0x000000ff);
     715             :     header[3] = (file_size >> 8) & 0x000000ff;
     716             :     header[4] = (file_size >> 16) & 0x000000ff;
     717             :     header[5] = (file_size >> 24) & 0x000000ff;
     718             : 
     719             :     long width = xsize;
     720             :     header[18] = width & 0x000000ff;
     721             :     header[19] = (width >> 8) &0x000000ff;
     722             :     header[20] = (width >> 16) &0x000000ff;
     723             :     header[21] = (width >> 24) &0x000000ff;
     724             : 
     725             :     long height = -ysize;
     726             :     header[22] = height &0x000000ff;
     727             :     header[23] = (height >> 8) &0x000000ff;
     728             :     header[24] = (height >> 16) &0x000000ff;
     729             :     header[25] = (height >> 24) &0x000000ff;
     730             :     memcpy(bmpHeader, header, BMP_HEADER_LEN);
     731             :     return 0;
     732             : }
     733             : #endif
     734             : 
     735           0 : void OpenGLRender::SetLine2DColor(sal_uInt8 r, sal_uInt8 g, sal_uInt8 b, sal_uInt8 nAlpha)
     736             : {
     737           0 :     m_2DColor = glm::vec4((float)r / 255.0f, (float)g / 255.0f, (float)b / 255.0f, nAlpha/255.f);
     738           0 : }
     739             : 
     740           0 : void OpenGLRender::SetLine2DWidth(int width)
     741             : {
     742           0 :     m_fLineWidth = std::max((float)width / OPENGL_SCALE_VALUE, 0.001f);
     743           0 : }
     744             : 
     745           0 : void OpenGLRender::SetColor(sal_uInt32 color, sal_uInt8 nAlpha)
     746             : {
     747           0 :     sal_uInt8 r = (color & 0x00FF0000) >> 16;
     748           0 :     sal_uInt8 g = (color & 0x0000FF00) >> 8;
     749           0 :     sal_uInt8 b = (color & 0x000000FF);
     750           0 :     m_2DColor = glm::vec4((float)r / 255.0f, (float)g / 255.0f, (float)b / 255.0f, nAlpha/ 255.f);
     751           0 : }
     752             : 
     753           0 : int OpenGLRender::CreateMultiSampleFrameBufObj()
     754             : {
     755           0 :     glGenFramebuffers(1, &m_frameBufferMS);
     756           0 :     glBindFramebuffer(GL_FRAMEBUFFER, m_frameBufferMS);
     757             : 
     758           0 :     glGenRenderbuffers(1, &m_renderBufferColorMS);
     759           0 :     glBindRenderbuffer(GL_RENDERBUFFER, m_renderBufferColorMS);
     760           0 :     glRenderbufferStorageMultisample(GL_RENDERBUFFER, 8,  GL_RGB, m_iWidth, m_iHeight);
     761           0 :     glBindRenderbuffer(GL_RENDERBUFFER, 0);
     762           0 :     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_renderBufferColorMS);
     763             : 
     764           0 :     glGenRenderbuffers(1, &m_renderBufferDepthMS);
     765           0 :     glBindRenderbuffer(GL_RENDERBUFFER, m_renderBufferDepthMS);
     766           0 :     glRenderbufferStorageMultisample(GL_RENDERBUFFER, 8, GL_DEPTH_COMPONENT24, m_iWidth, m_iHeight);
     767           0 :     glBindRenderbuffer(GL_RENDERBUFFER, 0);
     768           0 :     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_renderBufferDepthMS);
     769           0 :     glBindFramebuffer(GL_FRAMEBUFFER, 0);
     770             : 
     771           0 :     return 0;
     772             : }
     773             : 
     774           0 : int OpenGLRender::Create2DCircle(int detail)
     775             : {
     776             :     float angle;
     777           0 :     if (detail <= 0)
     778             :     {
     779           0 :         return -1;
     780             :     }
     781           0 :     m_Bubble2DCircle.clear();
     782           0 :     m_Bubble2DCircle.reserve(2 * (detail + 3));
     783           0 :     m_Bubble2DCircle.push_back(0);
     784           0 :     m_Bubble2DCircle.push_back(0);
     785           0 :     for(angle = 2.0f * GL_PI; angle > -(2.0f * GL_PI / detail); angle -= (2.0f * GL_PI / detail))
     786             :     {
     787           0 :         m_Bubble2DCircle.push_back(sin(angle));
     788           0 :         m_Bubble2DCircle.push_back(cos(angle));
     789             :     }
     790           0 :     return 0;
     791             : }
     792             : 
     793           0 : int OpenGLRender::Bubble2DShapePoint(float x, float y, float directionX, float directionY)
     794             : {
     795             :     //check whether to create the circle data
     796           0 :     if (m_Bubble2DCircle.empty())
     797             :     {
     798           0 :         Create2DCircle(100);
     799             :     }
     800             : 
     801           0 :     float actualX = (x / OPENGL_SCALE_VALUE);
     802           0 :     float actualY = (y / OPENGL_SCALE_VALUE);
     803             :     Bubble2DPointList aBubble2DPointList;
     804           0 :     aBubble2DPointList.xScale = directionX / OPENGL_SCALE_VALUE;
     805           0 :     aBubble2DPointList.yScale = directionY / OPENGL_SCALE_VALUE;
     806           0 :     aBubble2DPointList.x = actualX + aBubble2DPointList.xScale / 2;
     807           0 :     aBubble2DPointList.y = actualY + aBubble2DPointList.yScale / 2;
     808             : 
     809           0 :     m_Bubble2DShapePointList.push_back(aBubble2DPointList);
     810           0 :     return 0;
     811             : }
     812             : 
     813           0 : int OpenGLRender::RenderBubble2FBO(int)
     814             : {
     815           0 :     CHECK_GL_ERROR();
     816           0 :     glm::vec4 edgeColor = glm::vec4(0.0, 0.0, 0.0, 1.0);
     817           0 :     size_t listNum = m_Bubble2DShapePointList.size();
     818           0 :     for (size_t i = 0; i < listNum; i++)
     819             :     {
     820             :         //move the circle to the pos, and scale using the xScale and Y scale
     821           0 :         Bubble2DPointList &pointList = m_Bubble2DShapePointList.front();
     822           0 :         PosVecf3 trans = {pointList.x, pointList.y, m_fZStep};
     823           0 :         PosVecf3 angle = {0.0f, 0.0f, 0.0f};
     824           0 :         PosVecf3 scale = {pointList.xScale / 2, pointList.yScale / 2 , 1.0f};
     825           0 :         MoveModelf(trans, angle, scale);
     826           0 :         m_MVP = m_Projection * m_View * m_Model;
     827             :         //render to fbo
     828             :         //fill vertex buffer
     829           0 :         glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer);
     830           0 :         if (m_Bubble2DCircle.empty())
     831             :         {
     832           0 :             Create2DCircle(100);
     833             :         }
     834           0 :         glBufferData(GL_ARRAY_BUFFER, m_Bubble2DCircle.size() * sizeof(GLfloat), &m_Bubble2DCircle[0], GL_STATIC_DRAW);
     835             : 
     836           0 :         glUseProgram(m_CommonProID);
     837             : 
     838           0 :         glUniform4fv(m_2DColorID, 1, &m_2DColor[0]);
     839             : 
     840           0 :         glUniformMatrix4fv(m_MatrixID, 1, GL_FALSE, &m_MVP[0][0]);
     841             :         // 1rst attribute buffer : vertices
     842           0 :         glEnableVertexAttribArray(m_2DVertexID);
     843           0 :         glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer);
     844             :         glVertexAttribPointer(
     845             :             m_2DVertexID,                  // attribute. No particular reason for 0, but must match the layout in the shader.
     846             :             2,                  // size
     847             :             GL_FLOAT,           // type
     848             :             GL_FALSE,           // normalized?
     849             :             0,                  // stride
     850             :             (void*)0            // array buffer offset
     851           0 :             );
     852           0 :         glDrawArrays(GL_TRIANGLE_FAN, 0, m_Bubble2DCircle.size() / 2);
     853           0 :         glDisableVertexAttribArray(m_2DVertexID);
     854           0 :         glUseProgram(0);
     855           0 :         glBindBuffer(GL_ARRAY_BUFFER, 0);
     856             :         //add black edge
     857           0 :         glLineWidth(3.0);
     858           0 :         glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer);
     859           0 :         glBufferData(GL_ARRAY_BUFFER, m_Bubble2DCircle.size() * sizeof(GLfloat) -2 , &m_Bubble2DCircle[2], GL_STATIC_DRAW);
     860           0 :         glUseProgram(m_CommonProID);
     861           0 :         glUniform4fv(m_2DColorID, 1, &edgeColor[0]);
     862           0 :         glUniformMatrix4fv(m_MatrixID, 1, GL_FALSE, &m_MVP[0][0]);
     863           0 :         glEnableVertexAttribArray(m_2DVertexID);
     864           0 :         glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer);
     865             :         glVertexAttribPointer(
     866             :             m_2DVertexID,                  // attribute. No particular reason for 0, but must match the layout in the shader.
     867             :             2,                  // size
     868             :             GL_FLOAT,           // type
     869             :             GL_FALSE,           // normalized?
     870             :             0,                  // stride
     871             :             (void*)0            // array buffer offset
     872           0 :             );
     873           0 :         glDrawArrays(GL_LINE_STRIP, 0, (m_Bubble2DCircle.size() * sizeof(GLfloat) -2) / sizeof(float) / 2);
     874           0 :         glDisableVertexAttribArray(m_2DVertexID);
     875           0 :         glUseProgram(0);
     876           0 :         glBindBuffer(GL_ARRAY_BUFFER, 0);
     877           0 :         m_Bubble2DShapePointList.pop_front();
     878           0 :         glLineWidth(m_fLineWidth);
     879             :     }
     880             :     //if use MSAA, we should copy the data to the FBO texture
     881           0 :     GLenum fbResult = glCheckFramebufferStatus(GL_FRAMEBUFFER);
     882           0 :     if( fbResult != GL_FRAMEBUFFER_COMPLETE )
     883             :     {
     884             :         SAL_WARN("chart2.opengl", "error");
     885           0 :         return -1;
     886             :     }
     887           0 :     CHECK_GL_ERROR();
     888           0 :     m_fZStep += Z_STEP;
     889           0 :     return 0;
     890             : }
     891             : 
     892           0 : int OpenGLRender::RectangleShapePoint(float x, float y, float directionX, float directionY)
     893             : {
     894             :     //check whether to create the circle data
     895           0 :     float actualX = x / OPENGL_SCALE_VALUE;
     896           0 :     float actualY = y / OPENGL_SCALE_VALUE;
     897           0 :     float actualSizeX = directionX / OPENGL_SCALE_VALUE;
     898           0 :     float actualSizeY = directionY / OPENGL_SCALE_VALUE;
     899             :     RectanglePointList aRectangle;
     900             : 
     901           0 :     aRectangle.points[0] = actualX;
     902           0 :     aRectangle.points[1] = actualY;
     903           0 :     aRectangle.points[2] = m_fZStep;
     904           0 :     aRectangle.points[3] = actualX + actualSizeX;
     905           0 :     aRectangle.points[4] = actualY;
     906           0 :     aRectangle.points[5] = m_fZStep;
     907           0 :     aRectangle.points[6] = actualX + actualSizeX;
     908           0 :     aRectangle.points[7] = actualY + actualSizeY;
     909           0 :     aRectangle.points[8] = m_fZStep;
     910           0 :     aRectangle.points[9] = actualX;
     911           0 :     aRectangle.points[10] = actualY + actualSizeY;
     912           0 :     aRectangle.points[11] = m_fZStep;
     913             : 
     914           0 :     m_RectangleShapePointList.push_back(aRectangle);
     915           0 :     return 0;
     916             : }
     917             : 
     918           0 : int OpenGLRender::RenderRectangleShape(bool bBorder, bool bFill)
     919             : {
     920           0 :     size_t listNum = m_RectangleShapePointList.size();
     921           0 :     for (size_t i = 0; i < listNum; i++)
     922             :     {
     923             :         //move the circle to the pos, and scale using the xScale and Y scale
     924           0 :         RectanglePointList &pointList = m_RectangleShapePointList.front();
     925             :         {
     926           0 :             PosVecf3 trans = {0, 0, 0};
     927           0 :             PosVecf3 angle = {0.0f, 0.0f, 0.0f};
     928           0 :             PosVecf3 scale = {1, 1, 1.0f};
     929           0 :             MoveModelf(trans, angle, scale);
     930           0 :             m_MVP = m_Projection * m_View * m_Model;
     931             :         }
     932             : 
     933             :         //render to fbo
     934             :         //fill vertex buffer
     935           0 :         glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer);
     936           0 :         glBufferData(GL_ARRAY_BUFFER, sizeof(pointList.points), pointList.points, GL_STATIC_DRAW);
     937             : 
     938           0 :         glBindBuffer(GL_ARRAY_BUFFER, m_ColorBuffer);
     939           0 :         glBufferData(GL_ARRAY_BUFFER, sizeof(m_BackgroundColor), m_BackgroundColor, GL_STATIC_DRAW);
     940           0 :         glUseProgram(m_BackgroundProID);
     941             : 
     942           0 :         glUniformMatrix4fv(m_BackgroundMatrixID, 1, GL_FALSE, &m_MVP[0][0]);
     943           0 :         if(bFill)
     944             :         {
     945           0 :             glEnableVertexAttribArray(m_BackgroundVertexID);
     946           0 :             glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer);
     947             :             glVertexAttribPointer(
     948             :                     m_BackgroundVertexID,                  // attribute. No particular reason for 0, but must match the layout in the shader.
     949             :                     3,                  // size
     950             :                     GL_FLOAT,           // type
     951             :                     GL_FALSE,           // normalized?
     952             :                     0,                  // stride
     953             :                     (void*)0            // array buffer offset
     954           0 :                     );
     955             : 
     956             :             // 2nd attribute buffer : color
     957           0 :             glEnableVertexAttribArray(m_BackgroundColorID);
     958           0 :             glBindBuffer(GL_ARRAY_BUFFER, m_ColorBuffer);
     959             :             glVertexAttribPointer(
     960             :                     m_BackgroundColorID,                  // attribute. No particular reason for 0, but must match the layout in the shader.
     961             :                     4,                  // size
     962             :                     GL_FLOAT,           // type
     963             :                     GL_FALSE,           // normalized?
     964             :                     0,                  // stride
     965             :                     (void*)0            // array buffer offset
     966           0 :                     );
     967             :             //TODO: moggi: get rid of GL_QUADS
     968           0 :             glDrawArrays(GL_QUADS, 0, 4);
     969           0 :             glDisableVertexAttribArray(m_BackgroundVertexID);
     970           0 :             glDisableVertexAttribArray(m_BackgroundColorID);
     971             :         }
     972           0 :         if(bBorder)
     973             :         {
     974           0 :             if(bFill)
     975             :             {
     976           0 :                 PosVecf3 trans = {0.0, 0.0, Z_STEP };
     977           0 :                 PosVecf3 angle = {0.0f, 0.0f, 0.0f};
     978           0 :                 PosVecf3 scale = {1, 1, 1.0f};
     979           0 :                 MoveModelf(trans, angle, scale);
     980           0 :                 m_MVP = m_Projection * m_View * m_Model;
     981             : 
     982           0 :                 m_fZStep += Z_STEP;
     983           0 :                 glUniformMatrix4fv(m_BackgroundMatrixID, 1, GL_FALSE, &m_MVP[0][0]);
     984             :             }
     985           0 :             SetBackGroundColor(COL_BLACK, COL_BLACK, 255);
     986             : 
     987           0 :             glBindBuffer(GL_ARRAY_BUFFER, m_ColorBuffer);
     988           0 :             glBufferData(GL_ARRAY_BUFFER, sizeof(m_BackgroundColor), m_BackgroundColor, GL_STATIC_DRAW);
     989             :             // 1rst attribute buffer : vertices
     990           0 :             glEnableVertexAttribArray(m_BackgroundVertexID);
     991           0 :             glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer);
     992             :             glVertexAttribPointer(
     993             :                     m_BackgroundVertexID,                  // attribute. No particular reason for 0, but must match the layout in the shader.
     994             :                     3,                  // size
     995             :                     GL_FLOAT,           // type
     996             :                     GL_FALSE,           // normalized?
     997             :                     0,                  // stride
     998             :                     (void*)0            // array buffer offset
     999           0 :                     );
    1000             : 
    1001             :             // 2nd attribute buffer : color
    1002           0 :             glEnableVertexAttribArray(m_BackgroundColorID);
    1003           0 :             glBindBuffer(GL_ARRAY_BUFFER, m_ColorBuffer);
    1004             :             glVertexAttribPointer(
    1005             :                     m_BackgroundColorID,                  // attribute. No particular reason for 0, but must match the layout in the shader.
    1006             :                     4,                  // size
    1007             :                     GL_FLOAT,           // type
    1008             :                     GL_FALSE,           // normalized?
    1009             :                     0,                  // stride
    1010             :                     (void*)0            // array buffer offset
    1011           0 :                     );
    1012           0 :             glDrawArrays(GL_LINE_LOOP, 0, 4);
    1013           0 :             glDisableVertexAttribArray(m_BackgroundVertexID);
    1014           0 :             glDisableVertexAttribArray(m_BackgroundColorID);
    1015             :         }
    1016           0 :         glDisableVertexAttribArray(m_BackgroundVertexID);
    1017           0 :         glDisableVertexAttribArray(m_BackgroundColorID);
    1018           0 :         glUseProgram(0);
    1019           0 :         glBindBuffer(GL_ARRAY_BUFFER, 0);
    1020           0 :         m_RectangleShapePointList.pop_front();
    1021             :     }
    1022           0 :     CHECK_GL_ERROR();
    1023             : 
    1024           0 :     m_fZStep += Z_STEP;
    1025           0 :     return 0;
    1026             : }
    1027             : 
    1028           0 : int OpenGLRender::CreateTextTexture(const BitmapEx& rBitmapEx, const awt::Point&, const awt::Size& aSize, long rotation,
    1029             :         const drawing::HomogenMatrix3& rTrans)
    1030             : {
    1031             : #if DEBUG_PNG // debug PNG writing
    1032             :     static int nIdx = 0;
    1033             :     OUString aName = OUString( "file:///home/moggi/Documents/work/text" ) + OUString::number( nIdx++ ) + ".png";
    1034             :     try {
    1035             :         vcl::PNGWriter aWriter( rBitmapEx );
    1036             :         SvFileStream sOutput( aName, STREAM_WRITE );
    1037             :         aWriter.Write( sOutput );
    1038             :         sOutput.Close();
    1039             :     } catch (...) {
    1040             :         SAL_WARN("chart2.opengl", "Error writing png to " << aName);
    1041             :     }
    1042             : #endif
    1043             : 
    1044           0 :     long bmpWidth = rBitmapEx.GetSizePixel().Width();
    1045           0 :     long bmpHeight = rBitmapEx.GetSizePixel().Height();
    1046             : 
    1047           0 :     Bitmap aBitmap (rBitmapEx.GetBitmap());
    1048           0 :     AlphaMask aAlpha (rBitmapEx.GetAlpha());
    1049           0 :     boost::scoped_array<sal_uInt8> bitmapBuf(new sal_uInt8[4* bmpWidth * bmpHeight ]);
    1050           0 :     Bitmap::ScopedReadAccess pReadAccces( aBitmap );
    1051           0 :     AlphaMask::ScopedReadAccess pAlphaReadAccess( aAlpha );
    1052             : 
    1053           0 :     size_t i = 0;
    1054           0 :     for (long ny = 0; ny < bmpHeight; ny++)
    1055             :     {
    1056           0 :         Scanline pAScan = pAlphaReadAccess->GetScanline(ny);
    1057           0 :         for(long nx = 0; nx < bmpWidth; nx++)
    1058             :         {
    1059           0 :             BitmapColor aCol = pReadAccces->GetColor( ny, nx );
    1060           0 :             bitmapBuf[i++] = aCol.GetRed();
    1061           0 :             bitmapBuf[i++] = aCol.GetGreen();
    1062           0 :             bitmapBuf[i++] = aCol.GetBlue();
    1063           0 :             bitmapBuf[i++] = 255 - *pAScan++;
    1064           0 :         }
    1065             :     }
    1066             : 
    1067             :     TextInfo aTextInfo;
    1068           0 :     aTextInfo.rotation = -(double)rotation / 360.0 * 2* GL_PI;
    1069           0 :     aTextInfo.vertex[0] = -aSize.Width / 2 / OPENGL_SCALE_VALUE;
    1070           0 :     aTextInfo.vertex[1] = -aSize.Height / 2 / OPENGL_SCALE_VALUE;
    1071           0 :     aTextInfo.vertex[2] = m_fZStep;
    1072             : 
    1073           0 :     aTextInfo.vertex[3] = aSize.Width / 2 / OPENGL_SCALE_VALUE ;
    1074           0 :     aTextInfo.vertex[4] = -aSize.Height / 2 / OPENGL_SCALE_VALUE;
    1075           0 :     aTextInfo.vertex[5] = m_fZStep;
    1076             : 
    1077           0 :     aTextInfo.vertex[6] = aSize.Width / 2 / OPENGL_SCALE_VALUE;
    1078           0 :     aTextInfo.vertex[7] = aSize.Height / 2 / OPENGL_SCALE_VALUE;
    1079           0 :     aTextInfo.vertex[8] = m_fZStep;
    1080             : 
    1081           0 :     aTextInfo.vertex[9] = -aSize.Width / 2 / OPENGL_SCALE_VALUE;
    1082           0 :     aTextInfo.vertex[10] = aSize.Height / 2 / OPENGL_SCALE_VALUE;
    1083           0 :     aTextInfo.vertex[11] = m_fZStep;
    1084           0 :     aTextInfo.nDx = (rTrans.Line1.Column3 + aSize.Width / 2 ) / OPENGL_SCALE_VALUE - bmpWidth/2;
    1085           0 :     aTextInfo.nDy = (rTrans.Line2.Column3 + aSize.Height / 2 ) / OPENGL_SCALE_VALUE - bmpHeight/2;
    1086             : 
    1087           0 :     CHECK_GL_ERROR();
    1088           0 :     glGenTextures(1, &aTextInfo.texture);
    1089           0 :     CHECK_GL_ERROR();
    1090           0 :     glBindTexture(GL_TEXTURE_2D, aTextInfo.texture);
    1091           0 :     CHECK_GL_ERROR();
    1092           0 :     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    1093           0 :     CHECK_GL_ERROR();
    1094           0 :     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
    1095           0 :     CHECK_GL_ERROR();
    1096           0 :     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    1097           0 :     CHECK_GL_ERROR();
    1098           0 :     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    1099           0 :     CHECK_GL_ERROR();
    1100           0 :     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bmpWidth, bmpHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, bitmapBuf.get());
    1101           0 :     CHECK_GL_ERROR();
    1102           0 :     glBindTexture(GL_TEXTURE_2D, 0);
    1103           0 :     CHECK_GL_ERROR();
    1104           0 :     m_TextInfoList.push_back(aTextInfo);
    1105           0 :     return 0;
    1106             : }
    1107             : 
    1108           0 : int OpenGLRender::RenderTextShape()
    1109             : {
    1110           0 :     CHECK_GL_ERROR();
    1111           0 :     size_t listNum = m_TextInfoList.size();
    1112           0 :     for (size_t i = 0; i < listNum; i++)
    1113             :     {
    1114           0 :         TextInfo &textInfo = m_TextInfoList.front();
    1115           0 :         PosVecf3 trans = { textInfo.nDx, textInfo.nDy, 0};
    1116           0 :         PosVecf3 angle = {0.0f, 0.0f, float(textInfo.rotation)};
    1117           0 :         PosVecf3 scale = {1.0, 1.0, 1.0f};
    1118           0 :         MoveModelf(trans, angle, scale);
    1119           0 :         m_MVP = m_Projection * m_View * m_Model;
    1120           0 :         glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer);
    1121           0 :         CHECK_GL_ERROR();
    1122           0 :         glBufferData(GL_ARRAY_BUFFER, sizeof(textInfo.vertex), textInfo.vertex, GL_STATIC_DRAW);
    1123           0 :         CHECK_GL_ERROR();
    1124           0 :         glUseProgram(m_TextProID);
    1125             : 
    1126           0 :         CHECK_GL_ERROR();
    1127           0 :         glUniformMatrix4fv(m_TextMatrixID, 1, GL_FALSE, &m_MVP[0][0]);
    1128             :         // 1rst attribute buffer : vertices
    1129           0 :         glEnableVertexAttribArray(m_TextVertexID);
    1130           0 :         glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer);
    1131             :         glVertexAttribPointer(
    1132             :             m_TextVertexID,
    1133             :             3,                  // size
    1134             :             GL_FLOAT,           // type
    1135             :             GL_FALSE,           // normalized?
    1136             :             0,                  // stride
    1137             :             (void*)0            // array buffer offset
    1138           0 :             );
    1139             :         //tex coord
    1140           0 :         CHECK_GL_ERROR();
    1141           0 :         glEnableVertexAttribArray(m_TextTexCoordID);
    1142           0 :         glBindBuffer(GL_ARRAY_BUFFER, m_TextTexCoordBuf);
    1143             :         glVertexAttribPointer(
    1144             :             m_TextTexCoordID,
    1145             :             2,                  // size
    1146             :             GL_FLOAT,           // type
    1147             :             GL_FALSE,           // normalized?
    1148             :             0,                  // stride
    1149             :             (void*)0            // array buffer offset
    1150           0 :             );
    1151             :         //texture
    1152           0 :         CHECK_GL_ERROR();
    1153           0 :         glBindTexture(GL_TEXTURE_2D, textInfo.texture);
    1154           0 :         CHECK_GL_ERROR();
    1155           0 :         glUniform1i(m_TextTexID, 0);
    1156           0 :         CHECK_GL_ERROR();
    1157             :         //TODO: moggi: get rid fo GL_QUADS
    1158           0 :         glDrawArrays(GL_QUADS, 0, 4);
    1159           0 :         CHECK_GL_ERROR();
    1160           0 :         glDisableVertexAttribArray(m_TextTexCoordID);
    1161           0 :         CHECK_GL_ERROR();
    1162           0 :         glDisableVertexAttribArray(m_TextVertexID);
    1163           0 :         CHECK_GL_ERROR();
    1164           0 :         glBindTexture(GL_TEXTURE_2D, 0);
    1165           0 :         glUseProgram(0);
    1166           0 :         glDeleteTextures(1, &textInfo.texture);
    1167           0 :         CHECK_GL_ERROR();
    1168           0 :         m_TextInfoList.pop_front();
    1169             :     }
    1170           0 :     CHECK_GL_ERROR();
    1171           0 :     m_fZStep += Z_STEP;
    1172           0 :     return 0;
    1173             : }
    1174             : 
    1175           0 : int OpenGLRender::SetArea2DShapePoint(float x, float y, int listLength)
    1176             : {
    1177           0 :     if (m_Area2DPointList.empty())
    1178             :     {
    1179           0 :         m_Area2DPointList.reserve(listLength);
    1180             :     }
    1181           0 :     float actualX = (x / OPENGL_SCALE_VALUE);
    1182           0 :     float actualY = (y / OPENGL_SCALE_VALUE);
    1183           0 :     m_Area2DPointList.push_back(actualX);
    1184           0 :     m_Area2DPointList.push_back(actualY);
    1185           0 :     m_Area2DPointList.push_back(m_fZStep);
    1186             : 
    1187           0 :     if (m_Area2DPointList.size() == size_t(listLength * 3))
    1188             :     {
    1189           0 :         m_Area2DShapePointList.push_back(m_Area2DPointList);
    1190           0 :         m_Area2DPointList.clear();
    1191             :     }
    1192           0 :     return 0;
    1193             : }
    1194             : 
    1195             : namespace {
    1196             : 
    1197             : // only 2D
    1198           0 : bool checkCCW(const Area2DPointList& rPoints)
    1199             : {
    1200           0 :     if(rPoints.size() < 3)
    1201           0 :         return true;
    1202             : 
    1203           0 :     GLfloat sum = 0;
    1204           0 :     for(size_t i = 1; i < rPoints.size()/3; i += 3)
    1205             :     {
    1206           0 :         GLfloat x1 = rPoints[(i-1)*3];
    1207           0 :         GLfloat x2 = rPoints[i*3];
    1208           0 :         GLfloat y1 = rPoints[(i-1)*3 + 1];
    1209           0 :         GLfloat y2 = rPoints[i*3 + 1];
    1210           0 :         GLfloat prod = (x2-x1)*(y2+y1);
    1211             : 
    1212           0 :         sum += prod;
    1213             :     }
    1214             : 
    1215           0 :     return (sum <= 0);
    1216             : }
    1217             : 
    1218             : }
    1219             : 
    1220           0 : int OpenGLRender::RenderArea2DShape()
    1221             : {
    1222           0 :     CHECK_GL_ERROR();
    1223             : 
    1224           0 :     glDisable(GL_MULTISAMPLE);
    1225           0 :     size_t listNum = m_Area2DShapePointList.size();
    1226           0 :     PosVecf3 trans = {0.0f, 0.0f, 0.0f};
    1227           0 :     PosVecf3 angle = {0.0f, 0.0f, 0.0f};
    1228           0 :     PosVecf3 scale = {1.0f, 1.0f, 1.0f};
    1229           0 :     MoveModelf(trans, angle, scale);
    1230           0 :     m_MVP = m_Projection * m_View * m_Model;
    1231           0 :     for (size_t i = 0; i < listNum; ++i)
    1232             :     {
    1233           0 :         Area2DPointList &pointList = m_Area2DShapePointList.front();
    1234           0 :         bool bIsCCW = checkCCW(pointList); // is it counter clockwise (CCW) or clockwise (CW)
    1235           0 :         if(!bIsCCW)
    1236           0 :             glFrontFace(GL_CW);
    1237             :         //fill vertex buffer
    1238           0 :         glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer);
    1239           0 :         glBufferData(GL_ARRAY_BUFFER, pointList.size() * sizeof(float), &pointList[0], GL_STATIC_DRAW);
    1240             :         // Use our shader
    1241           0 :         glUseProgram(m_CommonProID);
    1242             : 
    1243           0 :         glUniform4fv(m_2DColorID, 1, &m_2DColor[0]);
    1244             : 
    1245           0 :         glUniformMatrix4fv(m_MatrixID, 1, GL_FALSE, &m_MVP[0][0]);
    1246             : 
    1247             :         // 1rst attribute buffer : vertices
    1248           0 :         glEnableVertexAttribArray(m_2DVertexID);
    1249           0 :         glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer);
    1250             :         glVertexAttribPointer(
    1251             :             m_2DVertexID,                  // attribute. No particular reason for 0, but must match the layout in the shader.
    1252             :             3,                  // size
    1253             :             GL_FLOAT,           // type
    1254             :             GL_FALSE,           // normalized?
    1255             :             0,                  // stride
    1256             :             (void*)0            // array buffer offset
    1257           0 :             );
    1258             :         // TODO: moggi: remove deprecated GL_POLYGON
    1259           0 :         glDrawArrays(GL_POLYGON, 0, pointList.size() / 3); // 12*3 indices starting at 0 -> 12 triangles
    1260           0 :         glDisableVertexAttribArray(m_2DVertexID);
    1261           0 :         glUseProgram(0);
    1262           0 :         if(!bIsCCW)
    1263           0 :             glFrontFace(GL_CCW);
    1264           0 :         m_Area2DShapePointList.pop_front();
    1265             :     }
    1266           0 :     glEnable(GL_MULTISAMPLE);
    1267           0 :     m_fZStep += Z_STEP;
    1268             : 
    1269           0 :     CHECK_GL_ERROR();
    1270             : 
    1271           0 :     return 0;
    1272             : }
    1273             : 
    1274           0 : void OpenGLRender::SetBackGroundColor(sal_uInt32 color1, sal_uInt32 color2, sal_uInt8 fillStyle)
    1275             : {
    1276           0 :     sal_uInt8 r = (color1 & 0x00FF0000) >> 16;
    1277           0 :     sal_uInt8 g = (color1 & 0x0000FF00) >> 8;
    1278           0 :     sal_uInt8 b = (color1 & 0x000000FF);
    1279             : 
    1280           0 :     m_BackgroundColor[0] = (float)r / 255.0f;
    1281           0 :     m_BackgroundColor[1] = (float)g / 255.0f;
    1282           0 :     m_BackgroundColor[2] = (float)b / 255.0f;
    1283           0 :     m_BackgroundColor[3] = fillStyle ? 1.0 : 0.0;
    1284             : 
    1285           0 :     m_BackgroundColor[4] = (float)r / 255.0f;
    1286           0 :     m_BackgroundColor[5] = (float)g / 255.0f;
    1287           0 :     m_BackgroundColor[6] = (float)b / 255.0f;
    1288           0 :     m_BackgroundColor[7] = fillStyle ? 1.0 : 0.0;
    1289             : 
    1290           0 :     r = (color2 & 0x00FF0000) >> 16;
    1291           0 :     g = (color2 & 0x0000FF00) >> 8;
    1292           0 :     b = (color2 & 0x000000FF);
    1293             : 
    1294           0 :     m_BackgroundColor[8] = (float)r / 255.0f;
    1295           0 :     m_BackgroundColor[9] = (float)g / 255.0f;
    1296           0 :     m_BackgroundColor[10] = (float)b / 255.0f;
    1297           0 :     m_BackgroundColor[11] = fillStyle ? 1.0 : 0.0;
    1298             : 
    1299           0 :     m_BackgroundColor[12] = (float)r / 255.0f;
    1300           0 :     m_BackgroundColor[13] = (float)g / 255.0f;
    1301           0 :     m_BackgroundColor[14] = (float)b / 255.0f;
    1302           0 :     m_BackgroundColor[15] = fillStyle ? 1.0 : 0.0;
    1303             :     SAL_INFO("chart2.opengl", "color1 = " << color1 << ", color2 = " << color2);
    1304             : 
    1305           0 : }
    1306             : 
    1307           0 : void OpenGLRender::SetChartTransparencyGradient(long transparencyGradient)
    1308             : {
    1309           0 :     if (transparencyGradient == 1)
    1310             :     {
    1311           0 :         m_BackgroundColor[11] = 0.0;
    1312           0 :         m_BackgroundColor[15] = 0.0;
    1313             :     }
    1314           0 : }
    1315             : 
    1316           0 : void OpenGLRender::GeneratePieSegment2D(double fInnerRadius, double fOutterRadius, double nAngleStart, double nAngleWidth)
    1317             : {
    1318           0 :     double nAngleStep = 1;
    1319           0 :     PieSegment2DPointList aPointList;
    1320             :     // TODO: moggi: GL_TRIANGLE_FAN seems not to work
    1321           0 :     bool bInnerRadiusNotZero = true; //!rtl::math::approxEqual(0.0, fInnerRadius);
    1322           0 :     size_t nVectorSize = 3*(nAngleWidth/nAngleStep);
    1323           0 :     if(bInnerRadiusNotZero)
    1324           0 :         nVectorSize *= 2;
    1325             : 
    1326           0 :     nAngleStart += 90;
    1327           0 :     aPointList.reserve(nVectorSize);
    1328             :     // if inner radius = 0 generate a normal pie segment (triangle fan)
    1329             :     // if inner radius != 0 generate a pie segment - inner pie (triangle strip)
    1330           0 :     if(!bInnerRadiusNotZero)
    1331             :     {
    1332           0 :         aPointList.push_back(0);
    1333           0 :         aPointList.push_back(0);
    1334           0 :         aPointList.push_back(m_fZStep);
    1335             :     }
    1336           0 :     for(double nAngle = nAngleStart; nAngle <= nAngleStart + nAngleWidth; nAngle += nAngleStep)
    1337             :     {
    1338           0 :         float xVal = sin(nAngle/360*2*GL_PI);
    1339           0 :         float yVal = cos(nAngle/360*2*GL_PI);
    1340           0 :         aPointList.push_back(fOutterRadius * xVal);
    1341           0 :         aPointList.push_back(fOutterRadius * yVal);
    1342           0 :         aPointList.push_back(m_fZStep);
    1343             : 
    1344           0 :         if(bInnerRadiusNotZero)
    1345             :         {
    1346           0 :             aPointList.push_back(fInnerRadius * xVal);
    1347           0 :             aPointList.push_back(fInnerRadius * yVal);
    1348           0 :             aPointList.push_back(m_fZStep);
    1349             :         }
    1350             :     }
    1351             : 
    1352           0 :     m_PieSegment2DShapePointList.push_back(aPointList);
    1353           0 : }
    1354             : 
    1355           0 : int OpenGLRender::RenderPieSegment2DShape(float fSize, float fPosX, float fPosY)
    1356             : {
    1357           0 :     int listNum = m_PieSegment2DShapePointList.size();
    1358           0 :     PosVecf3 trans = {fPosX/OPENGL_SCALE_VALUE, fPosY/OPENGL_SCALE_VALUE, 0.0f};
    1359           0 :     PosVecf3 angle = {0.0f, 0.0f, 0.0f};
    1360           0 :     PosVecf3 scale = {fSize/OPENGL_SCALE_VALUE, fSize/OPENGL_SCALE_VALUE, 1.0f};
    1361           0 :     MoveModelf(trans, angle, scale);
    1362           0 :     m_MVP = m_Projection * m_View * m_Model;
    1363             : 
    1364           0 :     for (int i = 0; i < listNum; i++)
    1365             :     {
    1366           0 :         PieSegment2DPointList &pointList = m_PieSegment2DShapePointList.back();
    1367             :         //fill vertex buffer
    1368           0 :         glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer);
    1369           0 :         glBufferData(GL_ARRAY_BUFFER, pointList.size() * sizeof(float), &pointList[0] , GL_STATIC_DRAW);
    1370             :         // Use our shader
    1371           0 :         glUseProgram(m_CommonProID);
    1372             : 
    1373           0 :         glUniform4fv(m_2DColorID, 1, &m_2DColor[0]);
    1374             : 
    1375           0 :         glUniformMatrix4fv(m_MatrixID, 1, GL_FALSE, &m_MVP[0][0]);
    1376             : 
    1377             :         // 1rst attribute buffer : vertices
    1378           0 :         glEnableVertexAttribArray(m_2DVertexID);
    1379           0 :         glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer);
    1380             :         glVertexAttribPointer(
    1381             :             m_2DVertexID,                  // attribute. No particular reason for 0, but must match the layout in the shader.
    1382             :             3,                  // size
    1383             :             GL_FLOAT,           // type
    1384             :             GL_FALSE,           // normalized?
    1385             :             0,                  // stride
    1386             :             (void*)0            // array buffer offset
    1387           0 :             );
    1388           0 :         glDrawArrays(GL_TRIANGLE_STRIP, 0, pointList.size() / 3); // 12*3 indices starting at 0 -> 12 triangles
    1389           0 :         glDisableVertexAttribArray(m_2DVertexID);
    1390           0 :         glUseProgram(0);
    1391           0 :         m_PieSegment2DShapePointList.pop_back();
    1392           0 :         CHECK_GL_ERROR();
    1393             : 
    1394             :     }
    1395           0 :     m_fZStep += Z_STEP;
    1396             : 
    1397           0 :     CHECK_GL_ERROR();
    1398           0 :     return 0;
    1399             : }
    1400             : 
    1401           0 : int OpenGLRender::RenderSymbol2DShape(float x, float y, float , float , sal_Int32 nSymbol)
    1402             : {
    1403           0 :     CHECK_GL_ERROR();
    1404             : 
    1405           0 :     glPointSize(20.f);
    1406           0 :     CHECK_GL_ERROR();
    1407           0 :     PosVecf3 trans = {0.0, 0.0, 0.0};
    1408           0 :     PosVecf3 angle = {0.0f, 0.0f, 0.0f};
    1409           0 :     PosVecf3 scale = {1.0, 1.0, 1.0f};
    1410           0 :     MoveModelf(trans, angle, scale);
    1411           0 :     m_MVP = m_Projection * m_View * m_Model;
    1412             : 
    1413           0 :     float aPos[3] = { x/OPENGL_SCALE_VALUE, y/OPENGL_SCALE_VALUE, m_fZStep };
    1414             :     //fill vertex buffer
    1415           0 :     glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer);
    1416           0 :     CHECK_GL_ERROR();
    1417           0 :     glBufferData(GL_ARRAY_BUFFER, 3 * sizeof(float), aPos, GL_STATIC_DRAW);
    1418           0 :     CHECK_GL_ERROR();
    1419             : 
    1420             :     // Use our shader
    1421           0 :     glUseProgram(m_SymbolProID);
    1422           0 :     CHECK_GL_ERROR();
    1423             : 
    1424           0 :     glUniform4fv(m_SymbolColorID, 1, &m_2DColor[0]);
    1425           0 :     glUniform1i(m_SymbolShapeID, nSymbol);
    1426           0 :     CHECK_GL_ERROR();
    1427             : 
    1428           0 :     glUniformMatrix4fv(m_SymbolMatrixID, 1, GL_FALSE, &m_MVP[0][0]);
    1429             : 
    1430           0 :     CHECK_GL_ERROR();
    1431             :     // 1rst attribute buffer : vertices
    1432           0 :     glEnableVertexAttribArray(m_SymbolVertexID);
    1433           0 :     glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer);
    1434             :     glVertexAttribPointer(
    1435             :             m_SymbolVertexID,                  // attribute. No particular reason for 0, but must match the layout in the shader.
    1436             :             3,                  // size
    1437             :             GL_FLOAT,           // type
    1438             :             GL_FALSE,           // normalized?
    1439             :             0,                  // stride
    1440             :             (void*)0            // array buffer offset
    1441           0 :             );
    1442             : 
    1443           0 :     glDrawArrays(GL_POINTS, 0, 1);
    1444             : 
    1445           0 :     glDisableVertexAttribArray(m_SymbolVertexID);
    1446           0 :     CHECK_GL_ERROR();
    1447           0 :     glUseProgram(0);
    1448           0 :     m_fZStep += Z_STEP;
    1449             : 
    1450           0 :     CHECK_GL_ERROR();
    1451           0 :     return 0;
    1452           0 : }
    1453             : 
    1454             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10