LCOV - code coverage report
Current view: top level - chart2/source/view/main - OpenGLRender.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 0 558 0.0 %
Date: 2014-11-03 Functions: 0 32 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/graph.hxx>
      14             : #include <com/sun/star/awt/XBitmap.hpp>
      15             : #include <com/sun/star/beans/XPropertySet.hpp>
      16             : #include <com/sun/star/graphic/XGraphic.hpp>
      17             : #include <comphelper/InlineContainer.hxx>
      18             : #include <com/sun/star/drawing/CircleKind.hpp>
      19             : #include <com/sun/star/drawing/DoubleSequence.hpp>
      20             : #include <com/sun/star/drawing/FlagSequence.hpp>
      21             : #include <com/sun/star/drawing/FillStyle.hpp>
      22             : #include <com/sun/star/drawing/LineStyle.hpp>
      23             : #include <com/sun/star/drawing/NormalsKind.hpp>
      24             : #include <com/sun/star/drawing/PointSequence.hpp>
      25             : #include <com/sun/star/drawing/PolygonKind.hpp>
      26             : #include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp>
      27             : #include <com/sun/star/drawing/ProjectionMode.hpp>
      28             : #include <com/sun/star/drawing/ShadeMode.hpp>
      29             : #include <com/sun/star/drawing/TextFitToSizeType.hpp>
      30             : #include <com/sun/star/drawing/TextureProjectionMode.hpp>
      31             : #include <com/sun/star/text/XText.hpp>
      32             : #include <com/sun/star/uno/Any.hxx>
      33             : #include <editeng/unoprnms.hxx>
      34             : #include <vcl/virdev.hxx>
      35             : #include <vcl/dibtools.hxx>
      36             : #include <vcl/svapp.hxx>
      37             : 
      38             : #include <vcl/opengl/OpenGLHelper.hxx>
      39             : 
      40             : #include "CommonConverters.hxx"
      41             : 
      42             : using namespace com::sun::star;
      43             : 
      44             : #define DEBUG_PNG 0
      45             : 
      46             : #if DEBUG_PNG
      47             : #include <vcl/pngwrite.hxx>
      48             : #endif
      49             : 
      50             : #define GL_PI 3.14159f
      51             : 
      52             : #define Z_STEP 0.001f
      53             : 
      54             : static GLfloat squareVertices[] = {
      55             :     -1.0f, -1.0f, -1.0,
      56             :     1.0f, -1.0f, -1.0,
      57             :     1.0f,  1.0f, -1.0,
      58             :     -1.0f,  1.0f, -1.0
      59             : };
      60             : 
      61             : static GLfloat coordReverseVertices[] = {
      62             :     0.0f, 1.0f,
      63             :     1.0f, 1.0f,
      64             :     1.0f, 0.0f,
      65             :     0.0f, 0.0f,
      66             : };
      67             : 
      68             : #define CHECK_GL_FRAME_BUFFER_STATUS() \
      69             :     GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);\
      70             :     if( status != GL_FRAMEBUFFER_COMPLETE ) {\
      71             :         SAL_WARN("chart2.opengl", "OpenGL error: " << status );\
      72             :         return -1;\
      73             :     }
      74             : 
      75             : namespace {
      76             : 
      77             : GLfloat texCoords[] = {
      78             :     0.0f, 0.0f,
      79             :     1.0f, 0.0f,
      80             :     1.0f, 1.0f,
      81             :     0.0f, 1.0f
      82             : };
      83             : 
      84             : }
      85             : 
      86           0 : int OpenGLRender::InitOpenGL()
      87             : {
      88           0 :     glEnable(GL_TEXTURE_2D);
      89           0 :     glDisable(GL_CULL_FACE);
      90           0 :     glCullFace(GL_BACK);
      91           0 :     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
      92             :     // Enable depth test
      93           0 :     glEnable(GL_DEPTH_TEST);
      94             :     // Accept fragment if it closer to the camera than the former one
      95           0 :     glDepthFunc(GL_LESS);
      96           0 :     glEnable(GL_POINT_SMOOTH);
      97           0 :     glEnable(GL_LINE_SMOOTH);
      98           0 :     glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
      99           0 :     glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
     100           0 :     glEnable(GL_BLEND);
     101           0 :     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
     102             : 
     103           0 :     glClearColor (1.0, 1.0, 1.0, 1.0);
     104           0 :     glClear(GL_COLOR_BUFFER_BIT);
     105           0 :     glClearDepth(1.0f);
     106           0 :     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     107             : 
     108           0 :     glGenBuffers(1, &m_VertexBuffer);
     109           0 :     glGenBuffers(1, &m_ColorBuffer);
     110             : 
     111           0 :     CHECK_GL_ERROR();
     112             : 
     113           0 :     m_CommonProID = OpenGLHelper::LoadShaders("commonVertexShader", "commonFragmentShader");
     114           0 :     m_MatrixID = glGetUniformLocation(m_CommonProID, "MVP");
     115           0 :     m_2DVertexID = glGetAttribLocation(m_CommonProID, "vPosition");
     116           0 :     m_2DColorID = glGetUniformLocation(m_CommonProID, "vColor");
     117           0 :     CHECK_GL_ERROR();
     118             : 
     119             : #if DEBUG_POSITIONING
     120             :     m_DebugProID = OpenGLHelper::LoadShaders("debugVertexShader", "debugFragmentShader");
     121             :     m_DebugVertexID = glGetAttribLocation(m_DebugProID, "vPosition");
     122             :     CHECK_GL_ERROR();
     123             : #endif
     124             : 
     125           0 :     m_BackgroundProID = OpenGLHelper::LoadShaders("backgroundVertexShader", "backgroundFragmentShader");
     126           0 :     m_BackgroundMatrixID = glGetUniformLocation(m_BackgroundProID, "MVP");
     127           0 :     m_BackgroundVertexID = glGetAttribLocation(m_BackgroundProID, "vPosition");
     128           0 :     m_BackgroundColorID = glGetAttribLocation(m_BackgroundProID, "vColor");
     129             : 
     130           0 :     CHECK_GL_ERROR();
     131             : 
     132           0 :     m_SymbolProID = OpenGLHelper::LoadShaders("symbolVertexShader", "symbolFragmentShader");
     133           0 :     m_SymbolVertexID = glGetAttribLocation(m_SymbolProID, "vPosition");
     134           0 :     m_SymbolMatrixID = glGetUniformLocation(m_SymbolProID, "MVP");
     135           0 :     m_SymbolColorID = glGetUniformLocation(m_SymbolProID, "vColor");
     136           0 :     m_SymbolShapeID = glGetUniformLocation(m_SymbolProID, "shape");
     137             : 
     138           0 :     CHECK_GL_ERROR();
     139             : 
     140           0 :     m_TextProID = OpenGLHelper::LoadShaders("textVertexShader", "textFragmentShader");
     141           0 :     m_TextMatrixID = glGetUniformLocation(m_TextProID, "MVP");
     142           0 :     m_TextVertexID = glGetAttribLocation(m_TextProID, "vPosition");
     143           0 :     m_TextTexCoordID = glGetAttribLocation(m_TextProID, "texCoord");
     144           0 :     m_TextTexID = glGetUniformLocation(m_TextProID, "TextTex");
     145           0 :     CHECK_GL_ERROR();
     146             : 
     147           0 :     glGenBuffers(1, &m_RenderVertexBuf);
     148           0 :     glBindBuffer(GL_ARRAY_BUFFER, m_RenderVertexBuf);
     149           0 :     glBufferData(GL_ARRAY_BUFFER, sizeof(squareVertices), squareVertices, GL_STATIC_DRAW);
     150           0 :     glBindBuffer(GL_ARRAY_BUFFER, 0);
     151             : 
     152           0 :     glGenBuffers(1, &m_RenderTexCoordBuf);
     153           0 :     glBindBuffer(GL_ARRAY_BUFFER, m_RenderTexCoordBuf);
     154           0 :     glBufferData(GL_ARRAY_BUFFER, sizeof(coordReverseVertices), coordReverseVertices, GL_STATIC_DRAW);
     155           0 :     glBindBuffer(GL_ARRAY_BUFFER, 0);
     156             : 
     157           0 :     glGenBuffers(1, &m_TextTexCoordBuf);
     158           0 :     glBindBuffer(GL_ARRAY_BUFFER, m_TextTexCoordBuf);
     159           0 :     glBufferData(GL_ARRAY_BUFFER, sizeof(texCoords), texCoords, GL_STATIC_DRAW);
     160           0 :     glBindBuffer(GL_ARRAY_BUFFER, 0);
     161             : 
     162           0 :     glEnable(GL_LIGHTING);
     163           0 :     GLfloat light_direction[] = { 0.0 , 0.0 , 1.0 };
     164           0 :     GLfloat materialDiffuse[] = { 1.0 , 1.0 , 1.0 , 1.0};
     165           0 :     glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, light_direction);
     166           0 :     glMaterialfv(GL_FRONT,GL_DIFFUSE,materialDiffuse);
     167           0 :     glEnable(GL_LIGHT0);
     168           0 :     glEnable(GL_NORMALIZE);
     169             : 
     170           0 :     return 0;
     171             : }
     172             : 
     173           0 : int OpenGLRender::SetLine2DShapePoint(float x, float y, int listLength)
     174             : {
     175           0 :     if (m_Line2DPointList.empty())
     176             :     {
     177           0 :         m_Line2DPointList.reserve(listLength*3);
     178             :     }
     179           0 :     m_Line2DPointList.push_back(x);
     180           0 :     m_Line2DPointList.push_back(y);
     181           0 :     m_Line2DPointList.push_back(m_fZStep);
     182             : 
     183           0 :     if (m_Line2DPointList.size() == size_t(listLength * 3))
     184             :     {
     185           0 :         m_Line2DShapePointList.push_back(m_Line2DPointList);
     186           0 :         m_Line2DPointList.clear();
     187             :     }
     188           0 :     return 0;
     189             : }
     190             : 
     191           0 : int OpenGLRender::RenderLine2FBO(int)
     192             : {
     193           0 :     CHECK_GL_ERROR();
     194           0 :     glLineWidth(m_fLineWidth);
     195           0 :     size_t listNum = m_Line2DShapePointList.size();
     196           0 :     PosVecf3 trans = {0.0f, 0.0f, 0.0f};
     197           0 :     PosVecf3 angle = {0.0f, 0.0f, 0.0f};
     198           0 :     PosVecf3 scale = {1.0f, 1.0f, 1.0f};
     199           0 :     MoveModelf(trans, angle, scale);
     200           0 :     m_MVP = m_Projection * m_View * m_Model;
     201           0 :     for (size_t i = 0; i < listNum; i++)
     202             :     {
     203           0 :         PointList &pointList = m_Line2DShapePointList.front();
     204             :         //fill vertex buffer
     205           0 :         glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer);
     206           0 :         CHECK_GL_ERROR();
     207           0 :         glBufferData(GL_ARRAY_BUFFER, pointList.size() * sizeof(float), &pointList[0], GL_STATIC_DRAW);
     208           0 :         CHECK_GL_ERROR();
     209             :         // Use our shader
     210           0 :         glUseProgram(m_CommonProID);
     211           0 :         CHECK_GL_ERROR();
     212             : 
     213           0 :         glUniform4fv(m_2DColorID, 1, &m_2DColor[0]);
     214           0 :         CHECK_GL_ERROR();
     215           0 :         glUniformMatrix4fv(m_MatrixID, 1, GL_FALSE, &m_MVP[0][0]);
     216             :         //CHECK_GL_ERROR();
     217             : 
     218             :         // 1rst attribute buffer : vertices
     219           0 :         CHECK_GL_ERROR();
     220             :         glVertexAttribPointer(
     221             :             m_2DVertexID,
     222             :             3,                  // size
     223             :             GL_FLOAT,           // type
     224             :             GL_FALSE,           // normalized?
     225             :             0,                  // stride
     226             :             (void*)0            // array buffer offset
     227           0 :             );
     228           0 :         glEnableVertexAttribArray(m_2DVertexID);
     229           0 :         glDrawArrays(GL_LINE_STRIP, 0, pointList.size()/3); // 12*3 indices starting at 0 -> 12 triangles
     230           0 :         CHECK_GL_ERROR();
     231           0 :         glUseProgram(0);
     232           0 :         glDisableVertexAttribArray(m_2DVertexID);
     233           0 :         CHECK_GL_ERROR();
     234           0 :         m_Line2DShapePointList.pop_front();
     235             :     }
     236           0 :     CHECK_GL_ERROR();
     237           0 :     CHECK_GL_FRAME_BUFFER_STATUS();
     238           0 :     m_fZStep += Z_STEP;
     239           0 :     return 0;
     240             : }
     241             : 
     242             : #if DEBUG_POSITIONING
     243             : void OpenGLRender::renderDebug()
     244             : {
     245             :     CHECK_GL_ERROR();
     246             : 
     247             :     GLfloat vertices[4][3] = {
     248             :         {-0.9, -0.9, 0 },
     249             :         {-0.6, -0.2, 0 },
     250             :         {0.3, 0.3, 0 },
     251             :         {0.9, 0.9, 0 } };
     252             : 
     253             :     glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer);
     254             :     CHECK_GL_ERROR();
     255             :     glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
     256             :     CHECK_GL_ERROR();
     257             :     glUseProgram(m_DebugProID);
     258             :     CHECK_GL_ERROR();
     259             :     glVertexAttribPointer(m_DebugVertexID, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
     260             :     CHECK_GL_ERROR();
     261             :     glEnableVertexAttribArray(m_DebugVertexID);
     262             : 
     263             :     glDrawArrays(GL_LINE_STRIP, 0, 3);
     264             :     CHECK_GL_ERROR();
     265             :     glDisableVertexAttribArray(m_DebugVertexID);
     266             : 
     267             :     CHECK_GL_ERROR();
     268             : }
     269             : #endif
     270             : 
     271           0 : void OpenGLRender::prepareToRender()
     272             : {
     273           0 :     glViewport(0, 0, m_iWidth, m_iHeight);
     274             : 
     275             :     // Clear the screen
     276           0 :     glClearDepth(1.0f);
     277           0 :     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     278           0 :     m_fZStep = 0;
     279           0 : }
     280             : 
     281           0 : int OpenGLRender::MoveModelf(PosVecf3 trans, PosVecf3 angle, PosVecf3 scale)
     282             : {
     283           0 :     glm::mat4 aTranslationMatrix = glm::translate(glm::vec3(trans.x, trans.y, trans.z));
     284           0 :     glm::mat4 aScaleMatrix = glm::scale(glm::vec3(scale.x, scale.y, scale.z));
     285           0 :     glm::mat4 aRotationMatrix = glm::eulerAngleYXZ(angle.y, angle.x, angle.z);
     286           0 :     m_Model = aTranslationMatrix * aRotationMatrix * aScaleMatrix;
     287           0 :     return 0;
     288             : }
     289             : 
     290           0 : void OpenGLRender::Release()
     291             : {
     292           0 :     glDeleteBuffers(1, &m_VertexBuffer);
     293           0 :     glDeleteBuffers(1, &m_ColorBuffer);
     294           0 :     glDeleteBuffers(1, &m_TextTexCoordBuf);
     295           0 :     glDeleteProgram(m_CommonProID);
     296           0 :     glDeleteProgram(m_TextProID);
     297           0 :     glDeleteProgram(m_BackgroundProID);
     298           0 :     glDeleteProgram(m_SymbolProID);
     299           0 : }
     300             : 
     301           0 : OpenGLRender::OpenGLRender()
     302             :     : m_iWidth(1600)
     303             :     , m_iHeight(900)
     304             :     , m_Model(glm::mat4(1.0f))
     305             :     , m_VertexBuffer(0)
     306             :     , m_ColorBuffer(0)
     307             :     , m_MatrixID(0)
     308             :     , m_RenderVertexBuf(0)
     309             :     , m_RenderTexCoordBuf(0)
     310             :     , m_fLineWidth(0.001f)
     311             :     , m_2DColor(glm::vec4(1.0, 0.0, 0.0, 1.0))
     312             :     , m_CommonProID(0)
     313             :     , m_2DVertexID(0)
     314             :     , m_2DColorID(0)
     315             :     , m_fZStep(0)
     316             :     , m_TextProID(0)
     317             :     , m_TextMatrixID(0)
     318             :     , m_TextVertexID(0)
     319             :     , m_TextTexCoordID(0)
     320             :     , m_TextTexCoordBuf(0)
     321             :     , m_TextTexID(0)
     322             :     , m_BackgroundProID(0)
     323             :     , m_BackgroundMatrixID(0)
     324             :     , m_BackgroundVertexID(0)
     325             :     , m_BackgroundColorID(0)
     326             :     , m_SymbolProID(0)
     327             :     , m_SymbolVertexID(0)
     328             :     , m_SymbolMatrixID(0)
     329             :     , m_SymbolColorID(0)
     330           0 :     , m_SymbolShapeID(0)
     331             : {
     332             :     //TODO: moggi: use STL
     333           0 :     for (size_t i = 0; i < sizeof(m_BackgroundColor) / sizeof(float); i++)
     334             :     {
     335           0 :         m_BackgroundColor[i] = 1.0;
     336             :     }
     337           0 : }
     338             : 
     339           0 : OpenGLRender::~OpenGLRender()
     340             : {
     341           0 :     Release();
     342           0 : }
     343             : 
     344             : // TODO: moggi: that screws up FBO if called after buffers have been created!!!!
     345           0 : void OpenGLRender::SetSize(int width, int height)
     346             : {
     347           0 :     m_iWidth = width;
     348           0 :     m_iHeight = height;
     349           0 : }
     350             : 
     351           0 : void OpenGLRender::SetSizePixel(int width, int height)
     352             : {
     353           0 :     m_Projection = glm::ortho(0.f, float(m_iWidth), 0.f, float(m_iHeight), -4.f, 3.f);
     354           0 :     m_Projection = m_Projection * glm::scale(glm::vec3((float)width / m_iWidth, -(float)height / m_iHeight, 1.0f));
     355             : 
     356           0 :     m_View       = glm::lookAt(glm::vec3(0,m_iHeight,1),
     357             :                                glm::vec3(0,m_iHeight,0),
     358           0 :                                glm::vec3(0,1,0) );
     359           0 : }
     360             : 
     361           0 : void OpenGLRender::SetLine2DColor(sal_uInt8 r, sal_uInt8 g, sal_uInt8 b, sal_uInt8 nAlpha)
     362             : {
     363           0 :     m_2DColor = glm::vec4((float)r / 255.0f, (float)g / 255.0f, (float)b / 255.0f, nAlpha/255.f);
     364           0 : }
     365             : 
     366           0 : void OpenGLRender::SetLine2DWidth(int width)
     367             : {
     368           0 :     m_fLineWidth = std::max((float)width, 0.001f);
     369           0 : }
     370             : 
     371           0 : void OpenGLRender::SetColor(sal_uInt32 color, sal_uInt8 nAlpha)
     372             : {
     373           0 :     sal_uInt8 r = (color & 0x00FF0000) >> 16;
     374           0 :     sal_uInt8 g = (color & 0x0000FF00) >> 8;
     375           0 :     sal_uInt8 b = (color & 0x000000FF);
     376           0 :     m_2DColor = glm::vec4((float)r / 255.0f, (float)g / 255.0f, (float)b / 255.0f, nAlpha/ 255.f);
     377           0 : }
     378             : 
     379           0 : int OpenGLRender::Create2DCircle(int detail)
     380             : {
     381             :     float angle;
     382           0 :     if (detail <= 0)
     383             :     {
     384           0 :         return -1;
     385             :     }
     386           0 :     m_Bubble2DCircle.clear();
     387           0 :     m_Bubble2DCircle.reserve(2 * (detail + 3));
     388           0 :     m_Bubble2DCircle.push_back(0);
     389           0 :     m_Bubble2DCircle.push_back(0);
     390           0 :     for(angle = 2.0f * GL_PI; angle > -(2.0f * GL_PI / detail); angle -= (2.0f * GL_PI / detail))
     391             :     {
     392           0 :         m_Bubble2DCircle.push_back(sin(angle));
     393           0 :         m_Bubble2DCircle.push_back(cos(angle));
     394             :     }
     395           0 :     return 0;
     396             : }
     397             : 
     398           0 : int OpenGLRender::Bubble2DShapePoint(float x, float y, float directionX, float directionY)
     399             : {
     400             :     //check whether to create the circle data
     401           0 :     if (m_Bubble2DCircle.empty())
     402             :     {
     403           0 :         Create2DCircle(100);
     404             :     }
     405             : 
     406             :     Bubble2DPointList aBubble2DPointList;
     407           0 :     aBubble2DPointList.xScale = directionX;
     408           0 :     aBubble2DPointList.yScale = directionY;
     409           0 :     aBubble2DPointList.x = x + aBubble2DPointList.xScale / 2;
     410           0 :     aBubble2DPointList.y = y + aBubble2DPointList.yScale / 2;
     411             : 
     412           0 :     m_Bubble2DShapePointList.push_back(aBubble2DPointList);
     413           0 :     return 0;
     414             : }
     415             : 
     416           0 : int OpenGLRender::RenderBubble2FBO(int)
     417             : {
     418           0 :     CHECK_GL_ERROR();
     419           0 :     glm::vec4 edgeColor = glm::vec4(0.0, 0.0, 0.0, 1.0);
     420           0 :     size_t listNum = m_Bubble2DShapePointList.size();
     421           0 :     for (size_t i = 0; i < listNum; i++)
     422             :     {
     423             :         //move the circle to the pos, and scale using the xScale and Y scale
     424           0 :         Bubble2DPointList &pointList = m_Bubble2DShapePointList.front();
     425           0 :         PosVecf3 trans = {pointList.x, pointList.y, m_fZStep};
     426           0 :         PosVecf3 angle = {0.0f, 0.0f, 0.0f};
     427           0 :         PosVecf3 scale = {pointList.xScale / 2, pointList.yScale / 2 , 1.0f};
     428           0 :         MoveModelf(trans, angle, scale);
     429           0 :         m_MVP = m_Projection * m_View * m_Model;
     430             :         //render to fbo
     431             :         //fill vertex buffer
     432           0 :         glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer);
     433           0 :         if (m_Bubble2DCircle.empty())
     434             :         {
     435           0 :             Create2DCircle(100);
     436             :         }
     437           0 :         glBufferData(GL_ARRAY_BUFFER, m_Bubble2DCircle.size() * sizeof(GLfloat), &m_Bubble2DCircle[0], GL_STATIC_DRAW);
     438             : 
     439           0 :         glUseProgram(m_CommonProID);
     440             : 
     441           0 :         glUniform4fv(m_2DColorID, 1, &m_2DColor[0]);
     442             : 
     443           0 :         glUniformMatrix4fv(m_MatrixID, 1, GL_FALSE, &m_MVP[0][0]);
     444             :         // 1rst attribute buffer : vertices
     445           0 :         glEnableVertexAttribArray(m_2DVertexID);
     446           0 :         glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer);
     447             :         glVertexAttribPointer(
     448             :             m_2DVertexID,                  // attribute. No particular reason for 0, but must match the layout in the shader.
     449             :             2,                  // size
     450             :             GL_FLOAT,           // type
     451             :             GL_FALSE,           // normalized?
     452             :             0,                  // stride
     453             :             (void*)0            // array buffer offset
     454           0 :             );
     455           0 :         glDrawArrays(GL_TRIANGLE_FAN, 0, m_Bubble2DCircle.size() / 2);
     456           0 :         glDisableVertexAttribArray(m_2DVertexID);
     457           0 :         glUseProgram(0);
     458           0 :         glBindBuffer(GL_ARRAY_BUFFER, 0);
     459             :         //add black edge
     460           0 :         glLineWidth(3.0);
     461           0 :         glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer);
     462           0 :         glBufferData(GL_ARRAY_BUFFER, m_Bubble2DCircle.size() * sizeof(GLfloat) -2 , &m_Bubble2DCircle[2], GL_STATIC_DRAW);
     463           0 :         glUseProgram(m_CommonProID);
     464           0 :         glUniform4fv(m_2DColorID, 1, &edgeColor[0]);
     465           0 :         glUniformMatrix4fv(m_MatrixID, 1, GL_FALSE, &m_MVP[0][0]);
     466           0 :         glEnableVertexAttribArray(m_2DVertexID);
     467           0 :         glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer);
     468             :         glVertexAttribPointer(
     469             :             m_2DVertexID,                  // attribute. No particular reason for 0, but must match the layout in the shader.
     470             :             2,                  // size
     471             :             GL_FLOAT,           // type
     472             :             GL_FALSE,           // normalized?
     473             :             0,                  // stride
     474             :             (void*)0            // array buffer offset
     475           0 :             );
     476           0 :         glDrawArrays(GL_LINE_STRIP, 0, (m_Bubble2DCircle.size() * sizeof(GLfloat) -2) / sizeof(float) / 2);
     477           0 :         glDisableVertexAttribArray(m_2DVertexID);
     478           0 :         glUseProgram(0);
     479           0 :         glBindBuffer(GL_ARRAY_BUFFER, 0);
     480           0 :         m_Bubble2DShapePointList.pop_front();
     481           0 :         glLineWidth(m_fLineWidth);
     482             :     }
     483             :     //if use MSAA, we should copy the data to the FBO texture
     484           0 :     GLenum fbResult = glCheckFramebufferStatus(GL_FRAMEBUFFER);
     485           0 :     if( fbResult != GL_FRAMEBUFFER_COMPLETE )
     486             :     {
     487             :         SAL_WARN("chart2.opengl", "error");
     488           0 :         return -1;
     489             :     }
     490           0 :     CHECK_GL_ERROR();
     491           0 :     m_fZStep += Z_STEP;
     492           0 :     return 0;
     493             : }
     494             : 
     495           0 : int OpenGLRender::RectangleShapePoint(float x, float y, float directionX, float directionY)
     496             : {
     497             :     RectanglePointList aRectangle;
     498             : 
     499           0 :     aRectangle.points[0] = x;
     500           0 :     aRectangle.points[1] = y;
     501           0 :     aRectangle.points[2] = m_fZStep;
     502           0 :     aRectangle.points[3] = x + directionX;
     503           0 :     aRectangle.points[4] = y;
     504           0 :     aRectangle.points[5] = m_fZStep;
     505           0 :     aRectangle.points[6] = x + directionX;
     506           0 :     aRectangle.points[7] = y + directionY;
     507           0 :     aRectangle.points[8] = m_fZStep;
     508           0 :     aRectangle.points[9] = x;
     509           0 :     aRectangle.points[10] = y + directionY;
     510           0 :     aRectangle.points[11] = m_fZStep;
     511             : 
     512           0 :     m_RectangleShapePointList.push_back(aRectangle);
     513           0 :     return 0;
     514             : }
     515             : 
     516           0 : int OpenGLRender::RenderRectangleShape(bool bBorder, bool bFill)
     517             : {
     518           0 :     size_t listNum = m_RectangleShapePointList.size();
     519           0 :     for (size_t i = 0; i < listNum; i++)
     520             :     {
     521             :         //move the circle to the pos, and scale using the xScale and Y scale
     522           0 :         RectanglePointList &pointList = m_RectangleShapePointList.front();
     523             :         {
     524           0 :             PosVecf3 trans = {0, 0, 0};
     525           0 :             PosVecf3 angle = {0.0f, 0.0f, 0.0f};
     526           0 :             PosVecf3 scale = {1, 1, 1.0f};
     527           0 :             MoveModelf(trans, angle, scale);
     528           0 :             m_MVP = m_Projection * m_View * m_Model;
     529             :         }
     530             : 
     531             :         //render to fbo
     532             :         //fill vertex buffer
     533           0 :         glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer);
     534           0 :         glBufferData(GL_ARRAY_BUFFER, sizeof(pointList.points), pointList.points, GL_STATIC_DRAW);
     535             : 
     536           0 :         glBindBuffer(GL_ARRAY_BUFFER, m_ColorBuffer);
     537           0 :         glBufferData(GL_ARRAY_BUFFER, sizeof(m_BackgroundColor), m_BackgroundColor, GL_STATIC_DRAW);
     538           0 :         glUseProgram(m_BackgroundProID);
     539             : 
     540           0 :         glUniformMatrix4fv(m_BackgroundMatrixID, 1, GL_FALSE, &m_MVP[0][0]);
     541           0 :         if(bFill)
     542             :         {
     543           0 :             glEnableVertexAttribArray(m_BackgroundVertexID);
     544           0 :             glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer);
     545             :             glVertexAttribPointer(
     546             :                     m_BackgroundVertexID,                  // attribute. No particular reason for 0, but must match the layout in the shader.
     547             :                     3,                  // size
     548             :                     GL_FLOAT,           // type
     549             :                     GL_FALSE,           // normalized?
     550             :                     0,                  // stride
     551             :                     (void*)0            // array buffer offset
     552           0 :                     );
     553             : 
     554             :             // 2nd attribute buffer : color
     555           0 :             glEnableVertexAttribArray(m_BackgroundColorID);
     556           0 :             glBindBuffer(GL_ARRAY_BUFFER, m_ColorBuffer);
     557             :             glVertexAttribPointer(
     558             :                     m_BackgroundColorID,                  // attribute. No particular reason for 0, but must match the layout in the shader.
     559             :                     4,                  // size
     560             :                     GL_FLOAT,           // type
     561             :                     GL_FALSE,           // normalized?
     562             :                     0,                  // stride
     563             :                     (void*)0            // array buffer offset
     564           0 :                     );
     565             :             //TODO: moggi: get rid of GL_QUADS
     566           0 :             glDrawArrays(GL_QUADS, 0, 4);
     567           0 :             glDisableVertexAttribArray(m_BackgroundVertexID);
     568           0 :             glDisableVertexAttribArray(m_BackgroundColorID);
     569             :         }
     570           0 :         if(bBorder)
     571             :         {
     572           0 :             if(bFill)
     573             :             {
     574           0 :                 PosVecf3 trans = {0.0, 0.0, Z_STEP };
     575           0 :                 PosVecf3 angle = {0.0f, 0.0f, 0.0f};
     576           0 :                 PosVecf3 scale = {1, 1, 1.0f};
     577           0 :                 MoveModelf(trans, angle, scale);
     578           0 :                 m_MVP = m_Projection * m_View * m_Model;
     579             : 
     580           0 :                 m_fZStep += Z_STEP;
     581           0 :                 glUniformMatrix4fv(m_BackgroundMatrixID, 1, GL_FALSE, &m_MVP[0][0]);
     582             :             }
     583           0 :             SetBackGroundColor(COL_BLACK, COL_BLACK, 255);
     584             : 
     585           0 :             glBindBuffer(GL_ARRAY_BUFFER, m_ColorBuffer);
     586           0 :             glBufferData(GL_ARRAY_BUFFER, sizeof(m_BackgroundColor), m_BackgroundColor, GL_STATIC_DRAW);
     587             :             // 1rst attribute buffer : vertices
     588           0 :             glEnableVertexAttribArray(m_BackgroundVertexID);
     589           0 :             glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer);
     590             :             glVertexAttribPointer(
     591             :                     m_BackgroundVertexID,                  // attribute. No particular reason for 0, but must match the layout in the shader.
     592             :                     3,                  // size
     593             :                     GL_FLOAT,           // type
     594             :                     GL_FALSE,           // normalized?
     595             :                     0,                  // stride
     596             :                     (void*)0            // array buffer offset
     597           0 :                     );
     598             : 
     599             :             // 2nd attribute buffer : color
     600           0 :             glEnableVertexAttribArray(m_BackgroundColorID);
     601           0 :             glBindBuffer(GL_ARRAY_BUFFER, m_ColorBuffer);
     602             :             glVertexAttribPointer(
     603             :                     m_BackgroundColorID,                  // attribute. No particular reason for 0, but must match the layout in the shader.
     604             :                     4,                  // size
     605             :                     GL_FLOAT,           // type
     606             :                     GL_FALSE,           // normalized?
     607             :                     0,                  // stride
     608             :                     (void*)0            // array buffer offset
     609           0 :                     );
     610           0 :             glDrawArrays(GL_LINE_LOOP, 0, 4);
     611           0 :             glDisableVertexAttribArray(m_BackgroundVertexID);
     612           0 :             glDisableVertexAttribArray(m_BackgroundColorID);
     613             :         }
     614           0 :         glDisableVertexAttribArray(m_BackgroundVertexID);
     615           0 :         glDisableVertexAttribArray(m_BackgroundColorID);
     616           0 :         glUseProgram(0);
     617           0 :         glBindBuffer(GL_ARRAY_BUFFER, 0);
     618           0 :         m_RectangleShapePointList.pop_front();
     619             :     }
     620           0 :     CHECK_GL_ERROR();
     621             : 
     622           0 :     m_fZStep += Z_STEP;
     623           0 :     return 0;
     624             : }
     625             : 
     626           0 : int OpenGLRender::CreateTextTexture(::rtl::OUString const &textValue, vcl::Font aFont, long , awt::Point aPos, awt::Size aSize, long rotation)
     627             : {
     628           0 :     VirtualDevice aDevice(*Application::GetDefaultDevice(), 0, 0);
     629           0 :     aDevice.Erase();
     630           0 :     Rectangle aRect;
     631           0 :     aDevice.SetFont(aFont);
     632           0 :     aDevice.GetTextBoundRect(aRect, textValue);
     633           0 :     int screenWidth = (aRect.BottomRight().X() + 3) & ~3;
     634           0 :     int screenHeight = (aRect.BottomRight().Y() + 3) & ~3;
     635           0 :     aDevice.SetOutputSizePixel(Size(screenWidth * 3, screenHeight));
     636           0 :     aDevice.SetBackground(Wallpaper(COL_TRANSPARENT));
     637           0 :     aDevice.DrawText(Point(0, 0), textValue);
     638           0 :     int bmpWidth = (aRect.Right() - aRect.Left() + 3) & ~3;
     639           0 :     int bmpHeight = (aRect.Bottom() - aRect.Top() + 3) & ~3;
     640           0 :     BitmapEx aBitmap = BitmapEx(aDevice.GetBitmapEx(aRect.TopLeft(), Size(bmpWidth, bmpHeight)));
     641             : 
     642           0 :     sal_Int32 nXPos = aPos.X;
     643           0 :     sal_Int32 nYPos = aPos.Y;
     644           0 :     ::basegfx::B2DHomMatrix aM;
     645           0 :     aM.rotate( -rotation*F_PI/180.0 );//#i78696#->#i80521#
     646           0 :     aM.translate( nXPos, nYPos );
     647           0 :     drawing::HomogenMatrix3 aTrans = chart::B2DHomMatrixToHomogenMatrix3(aM);
     648           0 :     aTrans.Line1.Column1 = 20 * bmpWidth;
     649           0 :     aTrans.Line2.Column2 = 20 * bmpHeight;
     650           0 :     return CreateTextTexture(aBitmap,aPos,aSize,rotation,aTrans);
     651             : }
     652             : 
     653           0 : int OpenGLRender::CreateTextTexture(const BitmapEx& rBitmapEx, const awt::Point&, const awt::Size& aSize, long rotation,
     654             :         const drawing::HomogenMatrix3& rTrans)
     655             : {
     656             : #if DEBUG_PNG // debug PNG writing
     657             :     static int nIdx = 0;
     658             :     OUString aName = OUString( "file:///home/moggi/Documents/work/text" ) + OUString::number( nIdx++ ) + ".png";
     659             :     try {
     660             :         vcl::PNGWriter aWriter( rBitmapEx );
     661             :         SvFileStream sOutput( aName, STREAM_WRITE );
     662             :         aWriter.Write( sOutput );
     663             :         sOutput.Close();
     664             :     } catch (...) {
     665             :         SAL_WARN("chart2.opengl", "Error writing png to " << aName);
     666             :     }
     667             : #endif
     668             : 
     669           0 :     boost::shared_array<sal_uInt8> bitmapBuf(new sal_uInt8[4 * rBitmapEx.GetSizePixel().Width() * rBitmapEx.GetSizePixel().Height()]);
     670             : 
     671           0 :     OpenGLHelper::ConvertBitmapExToRGBATextureBuffer(rBitmapEx, bitmapBuf.get());
     672             : 
     673           0 :     return CreateTextTexture(bitmapBuf, rBitmapEx.GetSizePixel(),
     674           0 :                              awt::Point(), aSize, rotation, rTrans);
     675             : }
     676             : 
     677           0 : int OpenGLRender::CreateTextTexture(const boost::shared_array<sal_uInt8> &rPixels,
     678             :                                     const ::Size &aPixelSize,
     679             :                                     const awt::Point&,
     680             :                                     const awt::Size& aSize,
     681             :                                     long rotation,
     682             :                                     const drawing::HomogenMatrix3& rTrans)
     683             : {
     684           0 :     long bmpWidth = aPixelSize.Width();
     685           0 :     long bmpHeight = aPixelSize.Height();
     686             : 
     687             :     TextInfo aTextInfo;
     688           0 :     aTextInfo.rotation = -(double)rotation / 360.0 * 2* GL_PI;
     689           0 :     aTextInfo.vertex[0] = -aSize.Width / 2;
     690           0 :     aTextInfo.vertex[1] = -aSize.Height / 2;
     691           0 :     aTextInfo.vertex[2] = m_fZStep;
     692             : 
     693           0 :     aTextInfo.vertex[3] = aSize.Width / 2;
     694           0 :     aTextInfo.vertex[4] = -aSize.Height / 2;
     695           0 :     aTextInfo.vertex[5] = m_fZStep;
     696             : 
     697           0 :     aTextInfo.vertex[6] = aSize.Width / 2;
     698           0 :     aTextInfo.vertex[7] = aSize.Height / 2;
     699           0 :     aTextInfo.vertex[8] = m_fZStep;
     700             : 
     701           0 :     aTextInfo.vertex[9] = -aSize.Width / 2;
     702           0 :     aTextInfo.vertex[10] = aSize.Height / 2;
     703           0 :     aTextInfo.vertex[11] = m_fZStep;
     704           0 :     aTextInfo.nDx = (rTrans.Line1.Column3 + aSize.Width / 2 ) - bmpWidth/2;
     705           0 :     aTextInfo.nDy = (rTrans.Line2.Column3 + aSize.Height / 2 ) - bmpHeight/2;
     706             : 
     707           0 :     CHECK_GL_ERROR();
     708           0 :     glGenTextures(1, &aTextInfo.texture);
     709           0 :     CHECK_GL_ERROR();
     710           0 :     glBindTexture(GL_TEXTURE_2D, aTextInfo.texture);
     711           0 :     CHECK_GL_ERROR();
     712           0 :     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
     713           0 :     CHECK_GL_ERROR();
     714           0 :     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
     715           0 :     CHECK_GL_ERROR();
     716           0 :     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
     717           0 :     CHECK_GL_ERROR();
     718           0 :     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
     719           0 :     CHECK_GL_ERROR();
     720           0 :     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bmpWidth, bmpHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, rPixels.get());
     721           0 :     CHECK_GL_ERROR();
     722           0 :     glBindTexture(GL_TEXTURE_2D, 0);
     723           0 :     CHECK_GL_ERROR();
     724           0 :     m_TextInfoList.push_back(aTextInfo);
     725           0 :     return 0;
     726             : }
     727             : 
     728           0 : int OpenGLRender::RenderTextShape()
     729             : {
     730           0 :     CHECK_GL_ERROR();
     731           0 :     size_t listNum = m_TextInfoList.size();
     732           0 :     for (size_t i = 0; i < listNum; i++)
     733             :     {
     734           0 :         TextInfo &textInfo = m_TextInfoList.front();
     735           0 :         PosVecf3 trans = { textInfo.nDx, textInfo.nDy, 0};
     736           0 :         PosVecf3 angle = {0.0f, 0.0f, float(textInfo.rotation)};
     737           0 :         PosVecf3 scale = {1.0, 1.0, 1.0f};
     738           0 :         MoveModelf(trans, angle, scale);
     739           0 :         m_MVP = m_Projection * m_View * m_Model;
     740           0 :         glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer);
     741           0 :         CHECK_GL_ERROR();
     742           0 :         glBufferData(GL_ARRAY_BUFFER, sizeof(textInfo.vertex), textInfo.vertex, GL_STATIC_DRAW);
     743           0 :         CHECK_GL_ERROR();
     744           0 :         glUseProgram(m_TextProID);
     745             : 
     746           0 :         CHECK_GL_ERROR();
     747           0 :         glUniformMatrix4fv(m_TextMatrixID, 1, GL_FALSE, &m_MVP[0][0]);
     748             :         // 1rst attribute buffer : vertices
     749           0 :         glEnableVertexAttribArray(m_TextVertexID);
     750           0 :         glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer);
     751             :         glVertexAttribPointer(
     752             :             m_TextVertexID,
     753             :             3,                  // size
     754             :             GL_FLOAT,           // type
     755             :             GL_FALSE,           // normalized?
     756             :             0,                  // stride
     757             :             (void*)0            // array buffer offset
     758           0 :             );
     759             :         //tex coord
     760           0 :         CHECK_GL_ERROR();
     761           0 :         glEnableVertexAttribArray(m_TextTexCoordID);
     762           0 :         glBindBuffer(GL_ARRAY_BUFFER, m_TextTexCoordBuf);
     763             :         glVertexAttribPointer(
     764             :             m_TextTexCoordID,
     765             :             2,                  // size
     766             :             GL_FLOAT,           // type
     767             :             GL_FALSE,           // normalized?
     768             :             0,                  // stride
     769             :             (void*)0            // array buffer offset
     770           0 :             );
     771             :         //texture
     772           0 :         CHECK_GL_ERROR();
     773           0 :         glBindTexture(GL_TEXTURE_2D, textInfo.texture);
     774           0 :         CHECK_GL_ERROR();
     775           0 :         glUniform1i(m_TextTexID, 0);
     776           0 :         CHECK_GL_ERROR();
     777             :         //TODO: moggi: get rid fo GL_QUADS
     778           0 :         glDrawArrays(GL_QUADS, 0, 4);
     779           0 :         CHECK_GL_ERROR();
     780           0 :         glDisableVertexAttribArray(m_TextTexCoordID);
     781           0 :         CHECK_GL_ERROR();
     782           0 :         glDisableVertexAttribArray(m_TextVertexID);
     783           0 :         CHECK_GL_ERROR();
     784           0 :         glBindTexture(GL_TEXTURE_2D, 0);
     785           0 :         glUseProgram(0);
     786           0 :         glDeleteTextures(1, &textInfo.texture);
     787           0 :         CHECK_GL_ERROR();
     788           0 :         m_TextInfoList.pop_front();
     789             :     }
     790           0 :     CHECK_GL_ERROR();
     791           0 :     m_fZStep += Z_STEP;
     792           0 :     return 0;
     793             : }
     794             : 
     795           0 : int OpenGLRender::SetArea2DShapePoint(float x, float y, int listLength)
     796             : {
     797           0 :     if (m_Area2DPointList.empty())
     798             :     {
     799           0 :         m_Area2DPointList.reserve(listLength);
     800             :     }
     801           0 :     m_Area2DPointList.push_back(x);
     802           0 :     m_Area2DPointList.push_back(y);
     803           0 :     m_Area2DPointList.push_back(m_fZStep);
     804             : 
     805           0 :     if (m_Area2DPointList.size() == size_t(listLength * 3))
     806             :     {
     807           0 :         m_Area2DShapePointList.push_back(m_Area2DPointList);
     808           0 :         m_Area2DPointList.clear();
     809             :     }
     810           0 :     return 0;
     811             : }
     812             : 
     813             : namespace {
     814             : 
     815             : // only 2D
     816           0 : bool checkCCW(const PointList& rPoints)
     817             : {
     818           0 :     if(rPoints.size() < 3)
     819           0 :         return true;
     820             : 
     821           0 :     GLfloat sum = 0;
     822           0 :     for(size_t i = 1; i < rPoints.size()/3; i += 3)
     823             :     {
     824           0 :         GLfloat x1 = rPoints[(i-1)*3];
     825           0 :         GLfloat x2 = rPoints[i*3];
     826           0 :         GLfloat y1 = rPoints[(i-1)*3 + 1];
     827           0 :         GLfloat y2 = rPoints[i*3 + 1];
     828           0 :         GLfloat prod = (x2-x1)*(y2+y1);
     829             : 
     830           0 :         sum += prod;
     831             :     }
     832             : 
     833           0 :     return (sum <= 0);
     834             : }
     835             : 
     836             : }
     837             : 
     838           0 : int OpenGLRender::RenderArea2DShape()
     839             : {
     840           0 :     CHECK_GL_ERROR();
     841             : 
     842           0 :     glDisable(GL_MULTISAMPLE);
     843           0 :     size_t listNum = m_Area2DShapePointList.size();
     844           0 :     PosVecf3 trans = {0.0f, 0.0f, 0.0f};
     845           0 :     PosVecf3 angle = {0.0f, 0.0f, 0.0f};
     846           0 :     PosVecf3 scale = {1.0f, 1.0f, 1.0f};
     847           0 :     MoveModelf(trans, angle, scale);
     848           0 :     m_MVP = m_Projection * m_View * m_Model;
     849           0 :     for (size_t i = 0; i < listNum; ++i)
     850             :     {
     851           0 :         PointList &pointList = m_Area2DShapePointList.front();
     852           0 :         bool bIsCCW = checkCCW(pointList); // is it counter clockwise (CCW) or clockwise (CW)
     853           0 :         if(!bIsCCW)
     854           0 :             glFrontFace(GL_CW);
     855             :         //fill vertex buffer
     856           0 :         glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer);
     857           0 :         glBufferData(GL_ARRAY_BUFFER, pointList.size() * sizeof(float), &pointList[0], GL_STATIC_DRAW);
     858             :         // Use our shader
     859           0 :         glUseProgram(m_CommonProID);
     860             : 
     861           0 :         glUniform4fv(m_2DColorID, 1, &m_2DColor[0]);
     862             : 
     863           0 :         glUniformMatrix4fv(m_MatrixID, 1, GL_FALSE, &m_MVP[0][0]);
     864             : 
     865             :         // 1rst attribute buffer : vertices
     866           0 :         glEnableVertexAttribArray(m_2DVertexID);
     867           0 :         glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer);
     868             :         glVertexAttribPointer(
     869             :             m_2DVertexID,                  // attribute. No particular reason for 0, but must match the layout in the shader.
     870             :             3,                  // size
     871             :             GL_FLOAT,           // type
     872             :             GL_FALSE,           // normalized?
     873             :             0,                  // stride
     874             :             (void*)0            // array buffer offset
     875           0 :             );
     876             :         // TODO: moggi: remove deprecated GL_POLYGON
     877           0 :         glDrawArrays(GL_POLYGON, 0, pointList.size() / 3); // 12*3 indices starting at 0 -> 12 triangles
     878           0 :         glDisableVertexAttribArray(m_2DVertexID);
     879           0 :         glUseProgram(0);
     880           0 :         if(!bIsCCW)
     881           0 :             glFrontFace(GL_CCW);
     882           0 :         m_Area2DShapePointList.pop_front();
     883             :     }
     884           0 :     glEnable(GL_MULTISAMPLE);
     885           0 :     m_fZStep += Z_STEP;
     886             : 
     887           0 :     CHECK_GL_ERROR();
     888             : 
     889           0 :     return 0;
     890             : }
     891             : 
     892           0 : void OpenGLRender::SetBackGroundColor(sal_uInt32 color1, sal_uInt32 color2, sal_uInt8 fillStyle)
     893             : {
     894           0 :     sal_uInt8 r = (color1 & 0x00FF0000) >> 16;
     895           0 :     sal_uInt8 g = (color1 & 0x0000FF00) >> 8;
     896           0 :     sal_uInt8 b = (color1 & 0x000000FF);
     897             : 
     898           0 :     m_BackgroundColor[0] = (float)r / 255.0f;
     899           0 :     m_BackgroundColor[1] = (float)g / 255.0f;
     900           0 :     m_BackgroundColor[2] = (float)b / 255.0f;
     901           0 :     m_BackgroundColor[3] = fillStyle ? 1.0 : 0.0;
     902             : 
     903           0 :     m_BackgroundColor[4] = (float)r / 255.0f;
     904           0 :     m_BackgroundColor[5] = (float)g / 255.0f;
     905           0 :     m_BackgroundColor[6] = (float)b / 255.0f;
     906           0 :     m_BackgroundColor[7] = fillStyle ? 1.0 : 0.0;
     907             : 
     908           0 :     r = (color2 & 0x00FF0000) >> 16;
     909           0 :     g = (color2 & 0x0000FF00) >> 8;
     910           0 :     b = (color2 & 0x000000FF);
     911             : 
     912           0 :     m_BackgroundColor[8] = (float)r / 255.0f;
     913           0 :     m_BackgroundColor[9] = (float)g / 255.0f;
     914           0 :     m_BackgroundColor[10] = (float)b / 255.0f;
     915           0 :     m_BackgroundColor[11] = fillStyle ? 1.0 : 0.0;
     916             : 
     917           0 :     m_BackgroundColor[12] = (float)r / 255.0f;
     918           0 :     m_BackgroundColor[13] = (float)g / 255.0f;
     919           0 :     m_BackgroundColor[14] = (float)b / 255.0f;
     920           0 :     m_BackgroundColor[15] = fillStyle ? 1.0 : 0.0;
     921             :     SAL_INFO("chart2.opengl", "color1 = " << color1 << ", color2 = " << color2);
     922             : 
     923           0 : }
     924             : 
     925           0 : void OpenGLRender::SetChartTransparencyGradient(long transparencyGradient)
     926             : {
     927           0 :     if (transparencyGradient == 1)
     928             :     {
     929           0 :         m_BackgroundColor[11] = 0.0;
     930           0 :         m_BackgroundColor[15] = 0.0;
     931             :     }
     932           0 : }
     933             : 
     934           0 : void OpenGLRender::GeneratePieSegment2D(double fInnerRadius, double fOutterRadius, double nAngleStart, double nAngleWidth)
     935             : {
     936           0 :     double nAngleStep = 1;
     937           0 :     PointList aPointList;
     938             :     // TODO: moggi: GL_TRIANGLE_FAN seems not to work
     939           0 :     const bool bInnerRadiusNotZero = true; //!rtl::math::approxEqual(0.0, fInnerRadius);
     940           0 :     size_t nVectorSize = 3*(nAngleWidth/nAngleStep);
     941             :     if(bInnerRadiusNotZero)
     942           0 :         nVectorSize *= 2;
     943             : 
     944           0 :     nAngleStart += 90;
     945           0 :     aPointList.reserve(nVectorSize);
     946             :     // if inner radius = 0 generate a normal pie segment (triangle fan)
     947             :     // if inner radius != 0 generate a pie segment - inner pie (triangle strip)
     948             :     if(!bInnerRadiusNotZero)
     949             :     {
     950             :         aPointList.push_back(0);
     951             :         aPointList.push_back(0);
     952             :         aPointList.push_back(m_fZStep);
     953             :     }
     954           0 :     for(double nAngle = nAngleStart; nAngle <= nAngleStart + nAngleWidth; nAngle += nAngleStep)
     955             :     {
     956           0 :         float xVal = sin(nAngle/360*2*GL_PI);
     957           0 :         float yVal = cos(nAngle/360*2*GL_PI);
     958           0 :         aPointList.push_back(fOutterRadius * xVal);
     959           0 :         aPointList.push_back(fOutterRadius * yVal);
     960           0 :         aPointList.push_back(m_fZStep);
     961             : 
     962             :         if(bInnerRadiusNotZero)
     963             :         {
     964           0 :             aPointList.push_back(fInnerRadius * xVal);
     965           0 :             aPointList.push_back(fInnerRadius * yVal);
     966           0 :             aPointList.push_back(m_fZStep);
     967             :         }
     968             :     }
     969             : 
     970           0 :     m_PieSegment2DShapePointList.push_back(aPointList);
     971           0 : }
     972             : 
     973           0 : int OpenGLRender::RenderPieSegment2DShape(float fSize, float fPosX, float fPosY)
     974             : {
     975           0 :     int listNum = m_PieSegment2DShapePointList.size();
     976           0 :     PosVecf3 trans = {fPosX, fPosY, 0.0f};
     977           0 :     PosVecf3 angle = {0.0f, 0.0f, 0.0f};
     978           0 :     PosVecf3 scale = {fSize, fSize, 1.0f};
     979           0 :     MoveModelf(trans, angle, scale);
     980           0 :     m_MVP = m_Projection * m_View * m_Model;
     981             : 
     982           0 :     for (int i = 0; i < listNum; i++)
     983             :     {
     984           0 :         PointList &pointList = m_PieSegment2DShapePointList.back();
     985             :         //fill vertex buffer
     986           0 :         glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer);
     987           0 :         glBufferData(GL_ARRAY_BUFFER, pointList.size() * sizeof(float), &pointList[0] , GL_STATIC_DRAW);
     988             :         // Use our shader
     989           0 :         glUseProgram(m_CommonProID);
     990             : 
     991           0 :         glUniform4fv(m_2DColorID, 1, &m_2DColor[0]);
     992             : 
     993           0 :         glUniformMatrix4fv(m_MatrixID, 1, GL_FALSE, &m_MVP[0][0]);
     994             : 
     995             :         // 1rst attribute buffer : vertices
     996           0 :         glEnableVertexAttribArray(m_2DVertexID);
     997           0 :         glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer);
     998             :         glVertexAttribPointer(
     999             :             m_2DVertexID,                  // attribute. No particular reason for 0, but must match the layout in the shader.
    1000             :             3,                  // size
    1001             :             GL_FLOAT,           // type
    1002             :             GL_FALSE,           // normalized?
    1003             :             0,                  // stride
    1004             :             (void*)0            // array buffer offset
    1005           0 :             );
    1006           0 :         glDrawArrays(GL_TRIANGLE_STRIP, 0, pointList.size() / 3); // 12*3 indices starting at 0 -> 12 triangles
    1007           0 :         glDisableVertexAttribArray(m_2DVertexID);
    1008           0 :         glUseProgram(0);
    1009           0 :         m_PieSegment2DShapePointList.pop_back();
    1010           0 :         CHECK_GL_ERROR();
    1011             : 
    1012             :     }
    1013           0 :     m_fZStep += Z_STEP;
    1014             : 
    1015           0 :     CHECK_GL_ERROR();
    1016           0 :     return 0;
    1017             : }
    1018             : 
    1019           0 : int OpenGLRender::RenderSymbol2DShape(float x, float y, float , float , sal_Int32 nSymbol)
    1020             : {
    1021           0 :     CHECK_GL_ERROR();
    1022             : 
    1023           0 :     glPointSize(20.f);
    1024           0 :     CHECK_GL_ERROR();
    1025           0 :     PosVecf3 trans = {0.0, 0.0, 0.0};
    1026           0 :     PosVecf3 angle = {0.0f, 0.0f, 0.0f};
    1027           0 :     PosVecf3 scale = {1.0, 1.0, 1.0f};
    1028           0 :     MoveModelf(trans, angle, scale);
    1029           0 :     m_MVP = m_Projection * m_View * m_Model;
    1030             : 
    1031           0 :     float aPos[3] = { x, y, m_fZStep };
    1032             :     //fill vertex buffer
    1033           0 :     glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer);
    1034           0 :     CHECK_GL_ERROR();
    1035           0 :     glBufferData(GL_ARRAY_BUFFER, 3 * sizeof(float), aPos, GL_STATIC_DRAW);
    1036           0 :     CHECK_GL_ERROR();
    1037             : 
    1038             :     // Use our shader
    1039           0 :     glUseProgram(m_SymbolProID);
    1040           0 :     CHECK_GL_ERROR();
    1041             : 
    1042           0 :     glUniform4fv(m_SymbolColorID, 1, &m_2DColor[0]);
    1043           0 :     glUniform1i(m_SymbolShapeID, nSymbol);
    1044           0 :     CHECK_GL_ERROR();
    1045             : 
    1046           0 :     glUniformMatrix4fv(m_SymbolMatrixID, 1, GL_FALSE, &m_MVP[0][0]);
    1047             : 
    1048           0 :     CHECK_GL_ERROR();
    1049             :     // 1rst attribute buffer : vertices
    1050           0 :     glEnableVertexAttribArray(m_SymbolVertexID);
    1051           0 :     glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer);
    1052             :     glVertexAttribPointer(
    1053             :             m_SymbolVertexID,                  // attribute. No particular reason for 0, but must match the layout in the shader.
    1054             :             3,                  // size
    1055             :             GL_FLOAT,           // type
    1056             :             GL_FALSE,           // normalized?
    1057             :             0,                  // stride
    1058             :             (void*)0            // array buffer offset
    1059           0 :             );
    1060             : 
    1061           0 :     glDrawArrays(GL_POINTS, 0, 1);
    1062             : 
    1063           0 :     glDisableVertexAttribArray(m_SymbolVertexID);
    1064           0 :     CHECK_GL_ERROR();
    1065           0 :     glUseProgram(0);
    1066           0 :     m_fZStep += Z_STEP;
    1067             : 
    1068           0 :     CHECK_GL_ERROR();
    1069           0 :     return 0;
    1070           0 : }
    1071             : 
    1072             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10