[Libreoffice-commits] core.git: Branch 'feature/chart-opengl' - chart2/Library_chartopengl.mk chart2/source

Peilin Xiao peilin at multicorewareinc.com
Sun Dec 8 18:51:05 PST 2013


 chart2/Library_chartopengl.mk                  |    2 
 chart2/source/view/main/DummyXShape.cxx        |   69 +
 chart2/source/view/main/OpenGLRender.cxx       |  929 +++++++++++++++++++++++++
 chart2/source/view/main/OpenGLRender.hxx       |  209 +++++
 chart2/source/view/main/OpenglShapeFactory.cxx |  117 ++-
 5 files changed, 1313 insertions(+), 13 deletions(-)

New commits:
commit 57f047bf6314191923e0fca7ea57d9b8bad3a950
Author: Peilin Xiao <peilin at multicorewareinc.com>
Date:   Mon Dec 9 03:43:33 2013 +0100

    initial work on OpenGL rendering backend
    
    with Linux build fixes and adaption to glm work
    
    Change-Id: I8fc84fd1f6131cd352b97cf5f82309d672e3118c

diff --git a/chart2/Library_chartopengl.mk b/chart2/Library_chartopengl.mk
index f8473eb..220012e 100644
--- a/chart2/Library_chartopengl.mk
+++ b/chart2/Library_chartopengl.mk
@@ -20,6 +20,7 @@ $(eval $(call gb_Library_set_include,chartopengl,\
 $(eval $(call gb_Library_use_externals,chartopengl,\
 	boost_headers \
 	mdds_headers \
+	glm_headers \
 ))
 
 $(eval $(call gb_Library_use_sdk_api,chartopengl))
@@ -42,6 +43,7 @@ $(eval $(call gb_Library_add_exception_objects,chartopengl,\
     chart2/source/glew/glew \
     chart2/source/view/main/OpenglShapeFactory \
     chart2/source/view/main/DummyXShape \
+    chart2/source/view/main/OpenGLRender \
 ))
 
 ifeq ($(strip $(OS)),WNT)
diff --git a/chart2/source/view/main/DummyXShape.cxx b/chart2/source/view/main/DummyXShape.cxx
index b1eb93f..cc2f871 100644
--- a/chart2/source/view/main/DummyXShape.cxx
+++ b/chart2/source/view/main/DummyXShape.cxx
@@ -6,6 +6,15 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
+#include <GL/glew.h>
+#include <stdio.h>
+#include <string>
+#include <vector>
+#include <iostream>
+#include <fstream>
+#include <algorithm>
+#include <stdlib.h>
+#include <string.h>
 
 #include "DummyXShape.hxx"
 #include "CommonConverters.hxx"
@@ -14,10 +23,13 @@
 #include <vcl/window.hxx>
 #include <tools/gen.hxx>
 
+
 #include <algorithm>
 
 using namespace com::sun::star;
 
+using namespace std;
+
 namespace chart {
 
 namespace dummy {
@@ -79,14 +91,14 @@ void DummyXShape::setPropertyValue( const OUString& rName, const uno::Any& rValu
             lang::IllegalArgumentException, lang::WrappedTargetException,
             uno::RuntimeException)
 {
-    SAL_DEBUG("DummyXShape::setProperty: " << rName << " " << "Any");
+    SAL_WARN("chart2", "DummyXShape::setProperty: " << rName << " " << "Any");
     maProperties[rName] = rValue;
 }
 
 uno::Any DummyXShape::getPropertyValue( const OUString& rName )
     throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
 {
-    SAL_DEBUG("DummyXShape::getPropertyValue: " << rName);
+    SAL_WARN("chart2.opengl", "DummyXShape::getPropertyValue: " << rName);
     std::map<OUString, uno::Any>::iterator itr = maProperties.find(rName);
     if(itr != maProperties.end())
         return itr->second;
@@ -488,6 +500,7 @@ bool DummyChart::initWindow()
 {
     const SystemEnvData* sysData(mpWindow->GetSystemData());
 #if defined( WNT )
+
     GLWin.hWnd = sysData->hWnd;
 #elif defined( UNX )
     GLWin.dpy = reinterpret_cast<unx::Display*>(sysData->pDisplay);
@@ -646,6 +659,7 @@ bool DummyChart::initWindow()
 
             ++pAttributeTable;
         }
+
 #endif
 
 #if defined( WNT )
@@ -700,8 +714,10 @@ int oglErrorHandler( unx::Display* /*dpy*/, unx::XErrorEvent* /*evnt*/ )
 
 #endif
 
+
 bool DummyChart::initOpengl()
 {
+    SAL_WARN("chart2.opengl", "DummyChart::initOpengl----start");
     initWindow();
     mpWindow->setPosSizePixel(0,0,0,0);
     GLWin.Width = 0;
@@ -743,10 +759,15 @@ bool DummyChart::initOpengl()
         0,                              // Reserved
         0, 0, 0                         // Layer Masks Ignored
     };
+
     int WindowPix = ChoosePixelFormat(GLWin.hDC,&PixelFormatFront);
     SetPixelFormat(GLWin.hDC,WindowPix,&PixelFormatFront);
     GLWin.hRC  = wglCreateContext(GLWin.hDC);
     wglMakeCurrent(GLWin.hDC,GLWin.hRC);
+//[Mod] GaoWei
+    m_GLRender.InitOpenGL(GLWin.hWnd, GLWin.hDC, GLWin.hRC);
+//[Mod] GaoWei end
+
 #elif defined( UNX )
     if( !glXMakeCurrent( GLWin.dpy, GLWin.win, GLWin.ctx ) )
     {
@@ -797,16 +818,20 @@ bool DummyChart::initOpengl()
     }
 #endif
 
+    glEnable(GL_TEXTURE_2D);
     glEnable(GL_CULL_FACE);
     glCullFace(GL_BACK);
-    glClearColor (0, 0, 0, 0);
-    glClear(GL_COLOR_BUFFER_BIT);
+    // Enable depth test
+    glEnable(GL_DEPTH_TEST);
+    // Accept fragment if it closer to the camera than the former one
+    glDepthFunc(GL_LESS);
+
 #if defined( WNT )
     SwapBuffers(GLWin.hDC);
+    glFlush();
 #elif defined( UNX )
     unx::glXSwapBuffers(GLWin.dpy, GLWin.win);
 #endif
-
     glEnable(GL_LIGHTING);
     GLfloat light_direction[] = { 0.0 , 0.0 , 1.0 };
     GLfloat materialDiffuse[] = { 1.0 , 1.0 , 1.0 , 1.0};
@@ -814,13 +839,16 @@ bool DummyChart::initOpengl()
     glMaterialfv(GL_FRONT,GL_DIFFUSE,materialDiffuse);
     glEnable(GL_LIGHT0);
     glEnable(GL_NORMALIZE);
-
+    SAL_WARN("chart2.opengl", "DummyChart::initOpengl----end");
+//    mpWindow->Show(1, 1);
     return true;
 }
 
+
 DummyChart::DummyChart():
     mpWindow(new Window(0, WB_NOBORDER|WB_NODIALOGCONTROL))
 {
+    SAL_WARN("chart2.opengl", "DummyXShape::DummyChart()-----test: ");
     setName("com.sun.star.chart2.shapes");
     createGLContext();
 }
@@ -836,12 +864,41 @@ void DummyChart::setPosition( const awt::Point& aPosition )
     DummyXShape::setPosition(aPosition);
 }
 
+DummyChart::~DummyChart()
+{
+    m_GLRender.Release();
+}
+
 void DummyChart::setSize( const awt::Size& aSize )
     throw( beans::PropertyVetoException, uno::RuntimeException )
 {
+#if 0
     DummyXShape::setSize(aSize);
     mpWindow->SetSizePixel(Size(aSize.Width, aSize.Height));
     pWindow->SetSizePixel(Size(aSize.Width, aSize.Height));
+#else
+
+//[Mod] GaoWei
+    SAL_WARN("chart2.opengl", "DummyChart::setSize()---aSize.Width = " << aSize.Width << ", aSize.Height = " << aSize.Height);
+//    DummyXShape::setSize(aSize);
+//    mpWindow->SetSizePixel(Size(aSize.Width, aSize.Height));
+//    pWindow->SetSizePixel(Size(aSize.Width, aSize.Height));
+    int width = aSize.Width / 10;
+    int height = aSize.Height / 10;
+    width = (width + 3) & ~3;
+    height = (height + 3) & ~3;
+    awt::Size tempSize;
+    tempSize.Width = width;
+    tempSize.Height = height;
+    mpWindow->SetSizePixel(Size(width, height));
+    pWindow->SetSizePixel(Size(width, height));
+    DummyXShape::setSize(tempSize);
+    m_GLRender.SetWidth(width);
+    m_GLRender.SetHeight(height);
+    SAL_WARN("chart2.opengl", "DummyChart::GLRender.Width = " << width << ", GLRender.Height = " << height);
+#endif
+ //[mod] by gaowei end
+
 }
 
 }
diff --git a/chart2/source/view/main/OpenGLRender.cxx b/chart2/source/view/main/OpenGLRender.cxx
new file mode 100644
index 0000000..0ce94d5
--- /dev/null
+++ b/chart2/source/view/main/OpenGLRender.cxx
@@ -0,0 +1,929 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <GL/glew.h>
+#include <vector>
+#include <iostream>
+#include "OpenGLRender.hxx"
+
+using namespace std;
+
+#define OPENGL_SHADER( ... )# __VA_ARGS__
+
+const char *ColorFragmemtShader = OPENGL_SHADER (
+
+varying vec3 fragmentColor;
+
+void main()
+{
+    gl_FragColor = vec4(fragmentColor, 1);
+}
+
+);
+
+const char *TransformVertexShader = OPENGL_SHADER (
+
+attribute vec3 vertexPosition_modelspace;
+attribute vec3 vertexColor;
+varying vec3 fragmentColor;
+uniform mat4 MVP;
+
+void main()
+{
+    gl_Position =  MVP * vec4(vertexPosition_modelspace,1);
+    fragmentColor = vertexColor;
+}
+
+);
+
+const char *Line2DFragmemtShader = OPENGL_SHADER (
+
+varying vec4 fragmentColor;
+
+void main()
+{
+    gl_FragColor = fragmentColor;
+}
+
+);
+
+const char *Line2DVertexShader = OPENGL_SHADER (
+
+attribute vec4 vPosition;
+uniform vec4 vLineColor;
+varying vec4 fragmentColor;
+
+void main()
+{
+    gl_Position =  vPosition;
+    fragmentColor = vLineColor;
+}
+
+);
+
+const char *RenderFragmentShader = OPENGL_SHADER (
+
+uniform sampler2D RenderTex;
+varying vec2 vTexCoord;
+
+void main()
+{
+    gl_FragColor = vec4(texture2D(RenderTex, vTexCoord).rgb, 1);
+}
+
+);
+
+const char *RenderVertexShader = OPENGL_SHADER (
+
+attribute vec4 vPosition;
+attribute vec2 texCoord;
+varying vec2 vTexCoord;
+
+void main()
+{
+    gl_Position =  vPosition;
+    vTexCoord = texCoord;
+}
+
+);
+
+
+static GLfloat squareVertices[] = {
+    -1.0f, -1.0f, -1.0,
+    1.0f, -1.0f, -1.0,
+    1.0f,  1.0f, -1.0,
+    -1.0f,  1.0f, -1.0
+};
+
+static GLfloat coordVertices[] = {
+    0.0f, 0.0f,
+    1.0f, 0.0f,
+    1.0f, 1.0f,
+    0.0f, 1.0f,
+};
+#if 0
+static const GLfloat g_vertex_buffer_data[] = {
+    -1.0f,-1.0f,-1.0f,
+    -1.0f,-1.0f, 1.0f,
+    -1.0f, 1.0f, 1.0f,
+    1.0f, 1.0f,-1.0f,
+    -1.0f,-1.0f,-1.0f,
+    -1.0f, 1.0f,-1.0f,
+    1.0f,-1.0f, 1.0f,
+    -1.0f,-1.0f,-1.0f,
+    1.0f,-1.0f,-1.0f,
+    1.0f, 1.0f,-1.0f,
+    1.0f,-1.0f,-1.0f,
+    -1.0f,-1.0f,-1.0f,
+    -1.0f,-1.0f,-1.0f,
+    -1.0f, 1.0f, 1.0f,
+    -1.0f, 1.0f,-1.0f,
+    1.0f,-1.0f, 1.0f,
+    -1.0f,-1.0f, 1.0f,
+    -1.0f,-1.0f,-1.0f,
+    -1.0f, 1.0f, 1.0f,
+    -1.0f,-1.0f, 1.0f,
+    1.0f,-1.0f, 1.0f,
+    1.0f, 1.0f, 1.0f,
+    1.0f,-1.0f,-1.0f,
+    1.0f, 1.0f,-1.0f,
+    1.0f,-1.0f,-1.0f,
+    1.0f, 1.0f, 1.0f,
+    1.0f,-1.0f, 1.0f,
+    1.0f, 1.0f, 1.0f,
+    1.0f, 1.0f,-1.0f,
+    -1.0f, 1.0f,-1.0f,
+    1.0f, 1.0f, 1.0f,
+    -1.0f, 1.0f,-1.0f,
+    -1.0f, 1.0f, 1.0f,
+    1.0f, 1.0f, 1.0f,
+    -1.0f, 1.0f, 1.0f,
+    1.0f,-1.0f, 1.0f
+};
+
+// One color for each vertex. They were generated randomly.
+static const GLfloat g_color_buffer_data[] = {
+    0.583f,  0.771f,  0.014f,
+    0.609f,  0.115f,  0.436f,
+    0.327f,  0.483f,  0.844f,
+    0.822f,  0.569f,  0.201f,
+    0.435f,  0.602f,  0.223f,
+    0.310f,  0.747f,  0.185f,
+    0.597f,  0.770f,  0.761f,
+    0.559f,  0.436f,  0.730f,
+    0.359f,  0.583f,  0.152f,
+    0.483f,  0.596f,  0.789f,
+    0.559f,  0.861f,  0.639f,
+    0.195f,  0.548f,  0.859f,
+    0.014f,  0.184f,  0.576f,
+    0.771f,  0.328f,  0.970f,
+    0.406f,  0.615f,  0.116f,
+    0.676f,  0.977f,  0.133f,
+    0.971f,  0.572f,  0.833f,
+    0.140f,  0.616f,  0.489f,
+    0.997f,  0.513f,  0.064f,
+    0.945f,  0.719f,  0.592f,
+    0.543f,  0.021f,  0.978f,
+    0.279f,  0.317f,  0.505f,
+    0.167f,  0.620f,  0.077f,
+    0.347f,  0.857f,  0.137f,
+    0.055f,  0.953f,  0.042f,
+    0.714f,  0.505f,  0.345f,
+    0.783f,  0.290f,  0.734f,
+    0.722f,  0.645f,  0.174f,
+    0.302f,  0.455f,  0.848f,
+    0.225f,  0.587f,  0.040f,
+    0.517f,  0.713f,  0.338f,
+    0.053f,  0.959f,  0.120f,
+    0.393f,  0.621f,  0.362f,
+    0.673f,  0.211f,  0.457f,
+    0.820f,  0.883f,  0.371f,
+    0.982f,  0.099f,  0.879f
+};
+#endif
+int static checkGLError(char *file, int line)
+{
+    GLenum glErr;
+    int    retCode = 0;
+    glErr = glGetError();
+    while (glErr != GL_NO_ERROR)
+    {
+        const GLubyte* sError = gluErrorString(glErr);
+
+        if (sError)
+            cout << "GL Error #" << glErr << "(" << gluErrorString(glErr) << ") " << " in File " << file << " at line: " << line << endl;
+        else
+            cout << "GL Error #" << glErr << " (no message available)" << " in File " << file << " at line: " << line << endl;
+
+        retCode = -1;
+        return retCode;
+    }
+    return retCode;
+}
+
+
+#define CHECK_GL_ERROR() checkGLError(__FILE__, __LINE__)
+
+GLint OpenGLRender::LoadShaders(const char *vertexShader,const char *fragmentShader)
+{
+    // Create the shaders
+    GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
+    GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
+
+    GLint Result = GL_FALSE;
+    int InfoLogLength;
+
+
+
+    // Compile Vertex Shader
+    char const * VertexSourcePointer = vertexShader;
+    glShaderSource(VertexShaderID, 1, &VertexSourcePointer , NULL);
+    glCompileShader(VertexShaderID);
+
+    // Check Vertex Shader
+    glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);
+    glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
+    if ( InfoLogLength > 0 ){
+        std::vector<char> VertexShaderErrorMessage(InfoLogLength+1);
+        glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]);
+        cout << "vertex shader compile fail : " << VertexShaderErrorMessage[0] << endl;
+    }
+
+
+
+    // Compile Fragment Shader
+    char const * FragmentSourcePointer = fragmentShader;
+    glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer , NULL);
+    glCompileShader(FragmentShaderID);
+
+    // Check Fragment Shader
+    glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);
+    glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
+    if ( InfoLogLength > 0 ){
+        std::vector<char> FragmentShaderErrorMessage(InfoLogLength+1);
+        glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]);
+        cout << "fragment shader compile fail : " << FragmentShaderErrorMessage[0] << endl;
+    }
+
+
+
+    // Link the program
+    GLint ProgramID = glCreateProgram();
+    glAttachShader(ProgramID, VertexShaderID);
+    glAttachShader(ProgramID, FragmentShaderID);
+    glLinkProgram(ProgramID);
+
+    // Check the program
+    glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
+    glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
+    if ( InfoLogLength > 0 ){
+        std::vector<char> ProgramErrorMessage(InfoLogLength+1);
+        glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]);
+        cout << "Shader Program fail : " << ProgramErrorMessage[0] << endl;
+    }
+
+    glDeleteShader(VertexShaderID);
+    glDeleteShader(FragmentShaderID);
+
+    return ProgramID;
+}
+
+int OpenGLRender::InitOpenGL(GLWindow aWindow)
+{
+    glWin = aWindow;
+    glewExperimental = GL_TRUE;
+    if (glewInit() != GLEW_OK)
+    {
+        cout << "Failed to initialize GLEW" << endl;
+        return -1;
+    }
+    glEnable(GL_TEXTURE_2D);
+    glEnable(GL_CULL_FACE);
+    glCullFace(GL_BACK);
+    // Enable depth test
+    glEnable(GL_DEPTH_TEST);
+    // Accept fragment if it closer to the camera than the former one
+    glDepthFunc(GL_LESS);
+    //[mod] by gaowei
+    glEnable(GL_POINT_SMOOTH);
+    glEnable(GL_LINE_SMOOTH);
+    glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
+    glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
+    glEnable(GL_BLEND);
+    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+    glClearColor (1.0f, 1.0f, 1.0f, 1.0f);
+    glClear(GL_COLOR_BUFFER_BIT);
+    glClearDepth(1.0f);
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+    //Init the Projection matrix
+    m_Projection = glm::perspective(45.0f, 4.0f / 3.0f, 0.1f, 100.0f);
+    m_View       = glm::lookAt(glm::vec3(0,0,1), // Camera is at (4,3,-3), in World Space
+                               glm::vec3(0,0,0), // and looks at the origin
+                               glm::vec3(0,1,0)  // Head is up (set to 0,-1,0 to look upside-down)
+                               );
+    m_ProgramID = LoadShaders(TransformVertexShader, ColorFragmemtShader);
+    glGenBuffers(1, &m_VertexBuffer);
+    glGenBuffers(1, &m_ColorBuffer);
+    m_MatrixID = glGetUniformLocation(m_ProgramID, "MVP");
+    m_VertexID = glGetAttribLocation(m_ProgramID, "vertexPosition_modelspace");
+    m_ColorID = glGetAttribLocation(m_ProgramID, "vertexColor");
+
+    m_RenderProID = LoadShaders(RenderVertexShader, RenderFragmentShader);
+    m_RenderVertexID = glGetAttribLocation(m_RenderProID, "vPosition");
+    m_RenderTexCoordID = glGetAttribLocation(m_RenderProID, "texCoord");
+    m_RenderTexID = glGetUniformLocation(m_RenderProID, "RenderTex");
+
+    m_Line2DProID = LoadShaders(Line2DVertexShader, Line2DFragmemtShader);
+    m_Line2DVertexID = glGetAttribLocation(m_Line2DProID, "vPosition");
+    m_Line2DColorID = glGetUniformLocation(m_Line2DProID, "vLineColor");
+
+    glGenBuffers(1, &m_RenderVertexBuf);
+    glBindBuffer(GL_ARRAY_BUFFER, m_RenderVertexBuf);
+    glBufferData(GL_ARRAY_BUFFER, sizeof(squareVertices), squareVertices, GL_STATIC_DRAW);
+    glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+    glGenBuffers(1, &m_RenderTexCoordBuf);
+    glBindBuffer(GL_ARRAY_BUFFER, m_RenderTexCoordBuf);
+    glBufferData(GL_ARRAY_BUFFER, sizeof(coordVertices), coordVertices, GL_STATIC_DRAW);
+    glBindBuffer(GL_ARRAY_BUFFER, 0);
+#if defined( WNT )
+    SwapBuffers(glWin.hDC);
+    glFlush();
+#elif defined( UNX )
+    unx::glXSwapBuffers(glWin.dpy, glWin.win);
+#endif
+    glEnable(GL_LIGHTING);
+    GLfloat light_direction[] = { 0.0 , 0.0 , 1.0 };
+    GLfloat materialDiffuse[] = { 1.0 , 1.0 , 1.0 , 1.0};
+    glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, light_direction);
+    glMaterialfv(GL_FRONT,GL_DIFFUSE,materialDiffuse);
+    glEnable(GL_LIGHT0);
+    glEnable(GL_NORMALIZE);
+    return 0;
+}
+
+
+int OpenGLRender::RenderModelf(float *vertexArray, unsigned int vertexArraySize, float *colorArray, unsigned int colorArraySize)
+{
+    if (vertexArraySize != colorArraySize)
+    {
+        return -1;
+    }
+    glViewport(0, 0, m_iWidth, m_iHeight);
+    glClearDepth(1.0f);
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+    //fill vertex buffer
+    glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer);
+    glBufferData(GL_ARRAY_BUFFER, vertexArraySize, vertexArray, GL_STATIC_DRAW);
+    //fill color buffer
+    glBindBuffer(GL_ARRAY_BUFFER, m_ColorBuffer);
+    glBufferData(GL_ARRAY_BUFFER, colorArraySize, colorArray, GL_STATIC_DRAW);
+    m_MVP = m_Projection * m_View * m_Model;
+    // Clear the screen
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+    // Use our shader
+    glUseProgram(m_ProgramID);
+
+    // Send our transformation to the currently bound shader,
+    // in the "MVP" uniform
+    glUniformMatrix4fv(m_MatrixID, 1, GL_FALSE, &m_MVP[0][0]);
+
+    // 1rst attribute buffer : vertices
+    glEnableVertexAttribArray(m_VertexID);
+    glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer);
+    glVertexAttribPointer(
+        m_VertexID,                  // attribute. No particular reason for 0, but must match the layout in the shader.
+        3,                  // size
+        GL_FLOAT,           // type
+        GL_FALSE,           // normalized?
+        0,                  // stride
+        (void*)0            // array buffer offset
+        );
+    // 2nd attribute buffer : colors
+    glEnableVertexAttribArray(m_ColorID);
+    glBindBuffer(GL_ARRAY_BUFFER, m_ColorBuffer);
+    glVertexAttribPointer(
+        m_ColorID,                                // attribute. No particular reason for 1, but must match the layout in the shader.
+        3,                                // size
+        GL_FLOAT,                         // type
+        GL_FALSE,                         // normalized?
+        0,                                // stride
+        (void*)0                          // array buffer offset
+        );
+    // Draw the triangle !
+    glDrawArrays(GL_TRIANGLES, 0, vertexArraySize / sizeof(float)); // 12*3 indices starting at 0 -> 12 triangles
+
+    glDisableVertexAttribArray(m_VertexID);
+    glDisableVertexAttribArray(m_ColorID);
+    glUseProgram(0);
+#if defined( WNT )
+    SwapBuffers(glWin.hDC);
+    glFlush();
+#elif defined( UNX )
+    unx::glXSwapBuffers(glWin.dpy, glWin.win);
+#endif
+    return 0;
+}
+int OpenGLRender::RenderModelf2FBO(float *vertexArray, unsigned int vertexArraySize, float *colorArray, unsigned int colorArraySize)
+{
+    char fileName[256] = {0};
+    sprintf(fileName, "D:\\shaderout_%d_%d.bmp", m_iWidth, m_iHeight);
+    if (vertexArraySize != colorArraySize)
+    {
+        return -1;
+    }
+    glViewport(0, 0, m_iWidth, m_iHeight);
+    glClearDepth(1.0f);
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+    // create a texture object
+    CreateTextureObj(m_iWidth, m_iHeight);
+    //create render buffer object
+    CreateRenderObj(m_iWidth, m_iHeight);
+    //create fbo
+    CreateFrameBufferObj();
+    //fill vertex buffer
+    glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer);
+    glBufferData(GL_ARRAY_BUFFER, vertexArraySize, vertexArray, GL_STATIC_DRAW);
+    //fill color buffer
+    glBindBuffer(GL_ARRAY_BUFFER, m_ColorBuffer);
+    glBufferData(GL_ARRAY_BUFFER, colorArraySize, colorArray, GL_STATIC_DRAW);
+    m_MVP = m_Projection * m_View * m_Model;
+    //bind fbo
+    glBindFramebuffer(GL_FRAMEBUFFER, m_FboID[0]);
+
+    // Clear the screen
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+    // Use our shader
+    glUseProgram(m_ProgramID);
+
+    // Send our transformation to the currently bound shader,
+    // in the "MVP" uniform
+    glUniformMatrix4fv(m_MatrixID, 1, GL_FALSE, &m_MVP[0][0]);
+
+    // 1rst attribute buffer : vertices
+    glEnableVertexAttribArray(m_VertexID);
+    glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer);
+    glVertexAttribPointer(
+        m_VertexID,                  // attribute. No particular reason for 0, but must match the layout in the shader.
+        3,                  // size
+        GL_FLOAT,           // type
+        GL_FALSE,           // normalized?
+        0,                  // stride
+        (void*)0            // array buffer offset
+        );
+    // 2nd attribute buffer : colors
+    glEnableVertexAttribArray(m_ColorID);
+    glBindBuffer(GL_ARRAY_BUFFER, m_ColorBuffer);
+    glVertexAttribPointer(
+        m_ColorID,                                // attribute. No particular reason for 1, but must match the layout in the shader.
+        3,                                // size
+        GL_FLOAT,                         // type
+        GL_FALSE,                         // normalized?
+        0,                                // stride
+        (void*)0                          // array buffer offset
+        );
+    // Draw the triangle !
+    glDrawArrays(GL_TRIANGLES, 0, vertexArraySize / sizeof(float)); // 12*3 indices starting at 0 -> 12 triangles
+    glDisableVertexAttribArray(m_VertexID);
+    glDisableVertexAttribArray(m_ColorID);
+    glUseProgram(0);
+    int result = 0;
+    GLenum fbResult = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+    if( fbResult != GL_FRAMEBUFFER_COMPLETE )
+    {
+        result = -1;
+    }
+#if 1
+    sal_uInt8 *buf = (sal_uInt8 *)malloc(m_iWidth * m_iHeight * 3 + BMP_HEADER_LEN);
+    CreateBMPHeader(buf, m_iWidth, -m_iHeight);
+    glReadPixels(0, 0, m_iWidth, m_iHeight, GL_BGR, GL_UNSIGNED_BYTE, buf + BMP_HEADER_LEN);
+    FILE *pfile = fopen(fileName,"wb");
+    fwrite(buf,m_iWidth * m_iHeight * 3 + BMP_HEADER_LEN, 1, pfile);
+    free(buf);
+    fclose(pfile);
+
+#else
+    boost::scoped_array<sal_uInt8> buf = new sal_uInt8[m_iWidth * m_iHeight * 4];
+    glBindTexture(GL_TEXTURE_2D, m_TextureObj);
+    glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, buf.get());
+    FILE *pfile = fopen(fileName,"wb");
+    fwrite(buf,m_iWidth * m_iHeight * 3, 1, pfile);
+    fclose(pfile);
+    glBindTexture(GL_TEXTURE_2D, 0);
+#endif
+    glBindFramebuffer(GL_FRAMEBUFFER, 0);
+    RenderTexture(m_TextureObj[0]);
+#if 0
+    sal_uInt8 *buf = (sal_uInt8 *)malloc(m_iWidth * m_iHeight * 3);
+    glBindTexture(GL_TEXTURE_2D, m_TextureObj);
+    glGetTexImage(GL_TEXTURE_2D, 0, GL_BGR, GL_UNSIGNED_BYTE, buf);
+    FILE *pfile = fopen(fileName,"wb");
+    fwrite(buf,m_iWidth * m_iHeight * 3, 1, pfile);
+    fclose(pfile);
+    free(buf);
+    glBindTexture(GL_TEXTURE_2D, 0);
+#endif
+    return 0;
+}
+
+int OpenGLRender::SetLine2DShapePoint(float x, float y, int listLength)
+{
+    if (!m_Line2DPoitList.pointBuf)
+    {
+        //a new point buffer should be alloc, we should push the old buffer first
+        m_Line2DPoitList.bufLen = listLength * sizeof(float) * 2;
+        m_Line2DPoitList.pointBuf = (float *)malloc(m_Line2DPoitList.bufLen);
+    }
+
+    float zeroX = (float)m_iWidth * 10;
+    float zeroY = (float)m_iHeight * 10;
+    m_Line2DPoitList.pointBuf[m_iPointNum++] = 3.5 * ((x - zeroX) / zeroX + 0.3);
+    m_Line2DPoitList.pointBuf[m_iPointNum++] = 3.5 * ((y - zeroY) / zeroY + 0.25);
+
+    if (m_iPointNum == (listLength << 1))
+    {
+        m_Line2DShapePointList.push_back(m_Line2DPoitList);
+        m_Line2DPoitList.pointBuf = NULL;
+        m_iPointNum = 0;
+    }
+    return 0;
+}
+
+int OpenGLRender::RenderLine2FBO(int wholeFlag)
+{
+    char fileName[256] = {0};
+    sprintf(fileName, "D:\\shaderout_%d_%d_%d.bmp", m_iWidth, m_iHeight, m_iFboIdx);
+
+    glViewport(0, 0, m_iWidth, m_iHeight);
+    glClearDepth(1.0f);
+    // Clear the screen
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+    if ((!m_FboID[0]) || (!m_FboID[1]))
+    {
+        // create a texture object
+        CreateTextureObj(m_iWidth, m_iHeight);
+        //create render buffer object
+        CreateRenderObj(m_iWidth, m_iHeight);
+        //create fbo
+        CreateFrameBufferObj();
+    }
+    //bind fbo
+    glBindFramebuffer(GL_FRAMEBUFFER, m_FboID[m_iFboIdx % 2]);
+
+    // Clear the screen
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+    if (wholeFlag)
+    {
+        if (m_iFboIdx > 0)
+        {
+           RenderTexture2FBO(m_TextureObj[(m_iFboIdx - 1) % 2]);
+        }
+    }
+    glLineWidth(m_fLineWidth);
+    int listNum = m_Line2DShapePointList.size();
+    for (int i = 0; i < listNum; i++)
+    {
+        Line2DPointList &pointList = m_Line2DShapePointList.front();
+        //fill vertex buffer
+        glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer);
+        glBufferData(GL_ARRAY_BUFFER, pointList.bufLen, pointList.pointBuf, GL_STATIC_DRAW);
+        // Use our shader
+        glUseProgram(m_Line2DProID);
+
+        glUniform4fv(m_Line2DColorID, 1, &m_Line2DColor[0]);
+
+        // 1rst attribute buffer : vertices
+        glEnableVertexAttribArray(m_Line2DVertexID);
+        glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer);
+        glVertexAttribPointer(
+            m_Line2DVertexID,                  // attribute. No particular reason for 0, but must match the layout in the shader.
+            2,                  // size
+            GL_FLOAT,           // type
+            GL_FALSE,           // normalized?
+            0,                  // stride
+            (void*)0            // array buffer offset
+            );
+        glDrawArrays(GL_LINE_STRIP, 0, pointList.bufLen / sizeof(float) / 2); // 12*3 indices starting at 0 -> 12 triangles
+        glDisableVertexAttribArray(m_Line2DWholeVertexID);
+        glUseProgram(0);
+        m_Line2DShapePointList.pop_front();
+        free(pointList.pointBuf);
+    }
+    m_iPointNum = 0;
+    int result = 0;
+    GLenum fbResult = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+    if( fbResult != GL_FRAMEBUFFER_COMPLETE )
+    {
+        result = -1;
+    }
+    sal_uInt8 *buf = (sal_uInt8 *)malloc(m_iWidth * m_iHeight * 3 + BMP_HEADER_LEN);
+    CreateBMPHeader(buf, m_iWidth, m_iHeight);
+    glReadPixels(0, 0, m_iWidth, m_iHeight, GL_BGR, GL_UNSIGNED_BYTE, buf + BMP_HEADER_LEN);
+    FILE *pfile = fopen(fileName,"wb");
+    fwrite(buf,m_iWidth * m_iHeight * 3 + BMP_HEADER_LEN, 1, pfile);
+    free(buf);
+    fclose(pfile);
+    glBindFramebuffer(GL_FRAMEBUFFER, 0);
+#if defined( WNT )
+    SwapBuffers(glWin.hDC);
+    glFlush();
+#elif defined( UNX )
+    unx::glXSwapBuffers(glWin.dpy, glWin.win);
+#endif
+    RenderTexture(m_TextureObj[m_iFboIdx % 2]);
+    m_iFboIdx++;
+    return 0;
+}
+
+int OpenGLRender::RenderTexture2FBO(GLuint TexID)
+{
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+    glDepthMask(GL_FALSE);
+    glUseProgram(m_RenderProID);
+    glEnableVertexAttribArray(m_RenderVertexID);
+    glBindBuffer(GL_ARRAY_BUFFER, m_RenderVertexBuf);
+    glVertexAttribPointer(
+        m_RenderVertexID,                  // attribute. No particular reason for 0, but must match the layout in the shader.
+        3,                  // size
+        GL_FLOAT,           // type
+        GL_FALSE,           // normalized?
+        0,                  // stride
+        (void*)0            // array buffer offset
+        );
+    glEnableVertexAttribArray(m_RenderTexCoordID);
+    glBindBuffer(GL_ARRAY_BUFFER, m_RenderTexCoordBuf);
+    glVertexAttribPointer(
+        m_RenderTexCoordID,                  // attribute. No particular reason for 0, but must match the layout in the shader.
+        2,                  // size
+        GL_FLOAT,           // type
+        GL_FALSE,           // normalized?
+        0,                  // stride
+        (void*)0            // array buffer offset
+        );
+    glBindTexture(GL_TEXTURE_2D, TexID);
+    glUniform1i(m_RenderTexID, 0);
+    glDrawArrays(GL_QUADS, 0, 4);
+    glDisableVertexAttribArray(m_RenderTexCoordID);
+    glDisableVertexAttribArray(m_RenderVertexID);
+    glBindTexture(GL_TEXTURE_2D, 0);
+    glUseProgram(0);
+    glDepthMask(GL_TRUE);
+    return 0;
+}
+
+
+int OpenGLRender::RenderTexture(GLuint TexID)
+{
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+    glUseProgram(m_RenderProID);
+
+    glEnableVertexAttribArray(m_RenderVertexID);
+    glBindBuffer(GL_ARRAY_BUFFER, m_RenderVertexBuf);
+    glVertexAttribPointer(
+        m_RenderVertexID,                  // attribute. No particular reason for 0, but must match the layout in the shader.
+        3,                  // size
+        GL_FLOAT,           // type
+        GL_FALSE,           // normalized?
+        0,                  // stride
+        (void*)0            // array buffer offset
+        );
+    glEnableVertexAttribArray(m_RenderTexCoordID);
+    glBindBuffer(GL_ARRAY_BUFFER, m_RenderTexCoordBuf);
+    glVertexAttribPointer(
+        m_RenderTexCoordID,                  // attribute. No particular reason for 0, but must match the layout in the shader.
+        2,                  // size
+        GL_FLOAT,           // type
+        GL_FALSE,           // normalized?
+        0,                  // stride
+        (void*)0            // array buffer offset
+        );
+    glBindTexture(GL_TEXTURE_2D, TexID);
+    glUniform1i(m_RenderTexID, 0);
+    glDrawArrays(GL_QUADS, 0, 4);
+    glDisableVertexAttribArray(m_RenderTexCoordID);
+    glDisableVertexAttribArray(m_RenderVertexID);
+    glBindTexture(GL_TEXTURE_2D, 0);
+    glUseProgram(0);
+#if defined( WNT )
+    SwapBuffers(glWin.hDC);
+    glFlush();
+#elif defined( UNX )
+    unx::glXSwapBuffers(glWin.dpy, glWin.win);
+#endif
+    return 0;
+}
+
+
+int OpenGLRender::CreateTextureObj(int width, int height)
+{
+    glGenTextures(1, &m_TextureObj[0]);
+    glBindTexture(GL_TEXTURE_2D, m_TextureObj[0]);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
+    CHECK_GL_ERROR();
+    glBindTexture(GL_TEXTURE_2D, 0);
+
+    glGenTextures(1, &m_TextureObj[1]);
+    glBindTexture(GL_TEXTURE_2D, m_TextureObj[1]);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
+    CHECK_GL_ERROR();
+    glBindTexture(GL_TEXTURE_2D, 0);
+    return 0;
+}
+
+int OpenGLRender::CreateRenderObj(int width, int height)
+{
+    glGenRenderbuffers(1, &m_RboID[0]);
+    CHECK_GL_ERROR();
+    glBindRenderbuffer(GL_RENDERBUFFER, m_RboID[0]);
+    CHECK_GL_ERROR();
+    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height);
+    CHECK_GL_ERROR();
+    glBindRenderbuffer(GL_RENDERBUFFER, 0);
+    CHECK_GL_ERROR();
+
+    glGenRenderbuffers(1, &m_RboID[1]);
+    CHECK_GL_ERROR();
+    glBindRenderbuffer(GL_RENDERBUFFER, m_RboID[1]);
+    CHECK_GL_ERROR();
+    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height);
+    CHECK_GL_ERROR();
+    glBindRenderbuffer(GL_RENDERBUFFER, 0);
+    CHECK_GL_ERROR();
+    return 0;
+}
+
+int OpenGLRender::SetViewPoint(PosVeci3 camPos, PosVeci3 orgPos, int headUpFlag)
+{
+    m_View = glm::lookAt(glm::vec3(camPos.x, camPos.y, camPos.z), // Camera is at (4,3,-3), in World Space
+                         glm::vec3(orgPos.x, orgPos.y ,orgPos.z), // and looks at the origin
+                         glm::vec3(0, (headUpFlag >= 0 ? 1 : -1) , 0)  // Head is up (set to 0,-1,0 to look upside-down)
+                         );
+    m_Projection = glm::perspective(45.0f, (float)m_iWidth / (float)m_iHeight, 0.1f, 100.0f);
+    return 0;
+}
+
+int OpenGLRender::MoveModelf(PosVecf3 trans, PosVecf3 angle, PosVecf3 scale)
+{
+    m_TranslationMatrix = glm::translate(glm::vec3(trans.x, trans.y, trans.z));
+    m_ScaleMatrix = glm::scale(glm::vec3(scale.x, scale.y, scale.z));
+    m_RotationMatrix = glm::eulerAngleYXZ(angle.y, angle.x, angle.z);
+    m_Model = m_TranslationMatrix * m_RotationMatrix * m_ScaleMatrix;
+    return 0;
+}
+
+
+int OpenGLRender::CreateFrameBufferObj()
+{
+    GLenum status;
+    // create a framebuffer object, you need to delete them when program exits.
+    glGenFramebuffers(1, &m_FboID[0]);
+    status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+    glBindFramebuffer(GL_FRAMEBUFFER, m_FboID[0]);
+    glBindTexture(GL_TEXTURE_2D, m_TextureObj[0]);
+    // attach a texture to FBO color attachement point
+    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_TextureObj[0], 0);
+    status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+    glBindTexture(GL_TEXTURE_2D, 0);
+    // attach a renderbuffer to depth attachment point
+    glBindRenderbuffer(GL_RENDERBUFFER, m_RboID[0]);
+    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_RboID[0]);
+    status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+    glBindRenderbuffer(GL_RENDERBUFFER, 0);
+    glBindFramebuffer(GL_FRAMEBUFFER, 0);
+
+    glGenFramebuffers(1, &m_FboID[1]);
+    status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+    glBindFramebuffer(GL_FRAMEBUFFER, m_FboID[1]);
+    glBindTexture(GL_TEXTURE_2D, m_TextureObj[1]);
+    // attach a texture to FBO color attachement point
+    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_TextureObj[1], 0);
+    status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+    glBindTexture(GL_TEXTURE_2D, 0);
+    // attach a renderbuffer to depth attachment point
+    glBindRenderbuffer(GL_RENDERBUFFER, m_RboID[1]);
+    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_RboID[1]);
+    status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+    glBindRenderbuffer(GL_RENDERBUFFER, 0);
+    glBindFramebuffer(GL_FRAMEBUFFER, 0);
+
+    return 0;
+}
+
+void OpenGLRender::Release()
+{
+    glDeleteBuffers(1, &m_VertexBuffer);
+    glDeleteBuffers(1, &m_ColorBuffer);
+    glDeleteProgram(m_ProgramID);
+    glDeleteBuffers(1, &m_RenderVertexBuf);
+    glDeleteBuffers(1, &m_RenderTexCoordBuf);
+    glDeleteProgram(m_RenderProID);
+    glDeleteFramebuffers(1, &m_FboID[0]);
+    glDeleteFramebuffers(1, &m_FboID[1]);
+    glDeleteTextures(1, &m_TextureObj[0]);
+    glDeleteTextures(1, &m_TextureObj[1]);
+    glDeleteRenderbuffers(1, &m_RboID[0]);
+    glDeleteRenderbuffers(1, &m_RboID[1]);
+#if defined( WNT )
+    wglMakeCurrent(NULL, NULL);
+    if (!m_iExternRC)
+        wglDeleteContext(m_hRC);
+    if (!m_iExternDC)
+        ReleaseDC(m_hWnd, m_hDC);
+#elif defined( UNX )
+
+    glXMakeCurrent(glWin.dpy, None, NULL);
+    if( glGetError() != GL_NO_ERROR ) {
+        SAL_INFO("slideshow.opengl", "glError: " << (char *)gluErrorString(glGetError()));
+    }
+    glXDestroyContext(glWin.dpy, glWin.ctx);
+    glWin.ctx = NULL;
+    glWin.win = 0;
+
+#endif
+}
+
+
+OpenGLRender::OpenGLRender()
+{
+    //[mod] by gaowei
+    m_Model = glm::mat4(1.0f);
+    m_TranslationMatrix = glm::translate(m_Model, glm::vec3(0.0f, 0.0f, 0.0f));
+    m_ScaleMatrix = glm::scale(m_Model, glm::vec3(1.0f, 1.0f, 1.0f));
+    m_RotationMatrix = glm::eulerAngleYXZ(0.0f, 0.0f, 0.0f);
+    m_iWidth = 0;
+    m_iHeight = 0;
+    m_Line2DColor = glm::vec4(1.0, 0.0, 0.0, 1.0);
+    m_iPointNum = 0;
+    memset(&m_Line2DPoitList, 0, sizeof(Line2DPointList));
+    m_iFboIdx = 0;
+    m_FboID[0] = 0;
+    m_FboID[1] = 0;
+    m_TextureObj[0] = 0;
+    m_TextureObj[1] = 0;
+    m_RboID[0] = 0;
+    m_RboID[1] = 0;
+    m_fLineAlpha = 1.0;
+}
+OpenGLRender::~OpenGLRender()
+{
+}
+
+void OpenGLRender::SetWidth(int width)
+{
+    m_iWidth = width;
+}
+void OpenGLRender::SetHeight(int height)
+{
+    m_iHeight = height;
+}
+
+int OpenGLRender::GetWidth()
+{
+    return m_iWidth;
+}
+int OpenGLRender::GetHeight()
+{
+    return m_iHeight;
+}
+int OpenGLRender::CreateBMPHeader(sal_uInt8 *bmpHeader, int xsize, int ysize)
+{
+    unsigned char header[BMP_HEADER_LEN] = {
+        0x42, 0x4d, 0, 0, 0, 0, 0, 0, 0, 0,
+        54, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 24, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0
+    };
+
+    long file_size = (long)xsize * (long)ysize * 3 + 54;
+    header[2] = (unsigned char)(file_size &0x000000ff);
+    header[3] = (file_size >> 8) & 0x000000ff;
+    header[4] = (file_size >> 16) & 0x000000ff;
+    header[5] = (file_size >> 24) & 0x000000ff;
+
+    long width = xsize;
+    header[18] = width & 0x000000ff;
+    header[19] = (width >> 8) &0x000000ff;
+    header[20] = (width >> 16) &0x000000ff;
+    header[21] = (width >> 24) &0x000000ff;
+
+    long height = -ysize;
+    header[22] = height &0x000000ff;
+    header[23] = (height >> 8) &0x000000ff;
+    header[24] = (height >> 16) &0x000000ff;
+    header[25] = (height >> 24) &0x000000ff;
+    memcpy(bmpHeader, header, BMP_HEADER_LEN);
+    return 0;
+
+}
+
+void OpenGLRender::SetLine2DColor(sal_uInt8 r, sal_uInt8 g, sal_uInt8 b)
+{
+    m_Line2DColor = glm::vec4((float)r / 255.0f, (float)g / 255.0f, (float)b / 255.0f, m_fLineAlpha);
+}
+
+void OpenGLRender::SetLine2DWidth(int width)
+{
+    m_fLineWidth = (float)width / 10.0f;
+    m_fLineWidth = (m_fLineWidth < 0.001) ? 0.001 : m_fLineWidth;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/view/main/OpenGLRender.hxx b/chart2/source/view/main/OpenGLRender.hxx
new file mode 100644
index 0000000..db36dbe
--- /dev/null
+++ b/chart2/source/view/main/OpenGLRender.hxx
@@ -0,0 +1,209 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#if defined( _WIN32 )
+#include "prewin.h"
+#include "windows.h"
+#include "postwin.h"
+#endif
+
+
+#include <GL/gl.h>
+#include <GL/glu.h>
+#include <vcl/window.hxx>
+#include <vcl/syschild.hxx>
+#include <vcl/sysdata.hxx>
+
+#if defined( _WIN32 )
+    #include <GL/glu.h>
+    #include <GL/glext.h>
+    #include <GL/wglext.h>
+#elif defined( MACOSX )
+    #include "premac.h"
+    #include <Cocoa/Cocoa.h>
+    #include "postmac.h"
+#elif defined( UNX )
+    #include <GL/glu.h>
+    #include <GL/glext.h>
+
+namespace unx
+{
+    #include <X11/keysym.h>
+    #include <X11/X.h>
+    #define GLX_GLXEXT_PROTOTYPES 1
+    #include <GL/glx.h>
+    #include <GL/glxext.h>
+}
+#endif
+
+// Include GLM
+#include <list>
+#include "glm/glm.hpp"
+#include "glm/gtx/transform.hpp"
+#include "glm/gtx/euler_angles.hpp"
+#include "glm/gtx/quaternion.hpp"
+#define BMP_HEADER_LEN 54
+
+using namespace std;
+
+typedef struct PosVeci3
+{
+    int x;
+    int y;
+    int z;
+}PosVeci3;
+typedef struct PosVecf3
+{
+    float x;
+    float y;
+    float z;
+}PosVecf3;
+
+typedef struct Line2DPointList
+{
+    float *pointBuf;;
+    int bufLen;
+}Line2DPointList;
+
+/// Holds the information of our new child window
+struct GLWindow
+{
+#if defined( _WIN32 )
+    HWND                    hWnd;
+    HDC                     hDC;
+    HGLRC                   hRC;
+#elif defined( MACOSX )
+#elif defined( UNX )
+    unx::Display*           dpy;
+    int                     screen;
+    unx::Window             win;
+#if defined( GLX_VERSION_1_3 ) && defined( GLX_EXT_texture_from_pixmap )
+    unx::GLXFBConfig        fbc;
+#endif
+    unx::XVisualInfo*       vi;
+    unx::GLXContext         ctx;
+
+    bool HasGLXExtension( const char* name ) { return gluCheckExtension( (const GLubyte*) name, (const GLubyte*) GLXExtensions ); }
+    const char*             GLXExtensions;
+#endif
+    unsigned int            bpp;
+    unsigned int            Width;
+    unsigned int            Height;
+    const GLubyte*          GLExtensions;
+
+    bool HasGLExtension( const char* name ) { return gluCheckExtension( (const GLubyte*) name, GLExtensions ); }
+};
+
+class OpenGLRender
+{
+public:
+    OpenGLRender();
+    ~OpenGLRender();
+    int InitOpenGL(GLWindow);
+    int SetViewPoint(PosVeci3 camPos, PosVeci3 orgPos, int headUpFlag);
+    int MoveModelf(PosVecf3 trans, PosVecf3 angle, PosVecf3 scale);
+    int RenderModelf(float *vertexArray, unsigned int vertexArraySize, float *colorArray, unsigned int colorArraySize);
+    int RenderModelf2FBO(float *vertexArray, unsigned int vertexArraySize, float *colorArray, unsigned int colorArraySize);
+    void SetWidth(int width);
+    void SetHeight(int height);
+    int GetWidth();
+    int GetHeight();
+    void Release();
+    int CreateBMPHeader(sal_uInt8 *bmpHeader, int xsize, int ysize);
+    int RenderLine2FBO(int wholeFlag);
+    int SetLine2DShapePoint(float x, float y, int listLength);
+    void SetLine2DColor(sal_uInt8 r, sal_uInt8 g, sal_uInt8 b);
+    void SetLine2DWidth(int width);
+private:
+    GLint LoadShaders(const char *vertexShader,const char *fragmentShader);
+    int CreateTextureObj(int width, int height);
+    int CreateRenderObj(int width, int height);
+    int CreateFrameBufferObj();
+    int RenderTexture(GLuint TexID);
+    int RenderTexture2FBO(GLuint TexID);
+private:
+    // Projection matrix : default 45 degree Field of View, 4:3 ratio, display range : 0.1 unit <-> 100 units
+    glm::mat4 m_Projection;
+    // Camera matrix
+    glm::mat4 m_View;
+    // Model matrix : an identity matrix (model will be at the origin)
+    glm::mat4 m_Model;
+    // Our ModelViewProjection : multiplication of our 3 matrices
+    glm::mat4 m_MVP;
+
+    glm::mat4 m_TranslationMatrix;
+
+    glm::mat4 m_RotationMatrix;
+
+    glm::mat4 m_ScaleMatrix;
+
+    GLuint m_ProgramID;
+
+    GLint m_RenderProID;
+
+    GLint m_Line2DProID;
+
+    glm::vec4 m_Line2DColor;
+
+    GLuint m_VertexBuffer;
+
+    GLuint m_ColorBuffer;
+
+    GLint m_MatrixID;
+
+    GLint m_VertexID;
+
+    GLint m_ColorID;
+
+    GLint m_RenderVertexID;
+
+    GLint m_RenderTexCoordID;
+
+    GLint m_Line2DVertexID;
+
+    GLint m_Line2DWholeVertexID;
+
+    GLint m_Line2DColorID;
+
+    GLint m_RenderTexID;
+
+    GLuint m_RenderVertexBuf;
+
+    GLuint m_RenderTexCoordBuf;
+
+    GLuint m_TextureObj[2];
+
+    GLuint m_FboID[2];
+
+    GLuint m_RboID[2];
+
+    int m_iWidth;
+
+    int m_iHeight;
+
+    GLWindow glWin;
+
+    int m_iExternDC;
+
+    int m_iExternRC;
+
+    int m_iPointNum;
+
+    Line2DPointList m_Line2DPoitList;
+
+    int m_iFboIdx;
+
+    float m_fLineWidth;
+
+    float m_fLineAlpha;
+
+    list <Line2DPointList> m_Line2DShapePointList;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/view/main/OpenglShapeFactory.cxx b/chart2/source/view/main/OpenglShapeFactory.cxx
index 2f4b6cf..bb956ee 100644
--- a/chart2/source/view/main/OpenglShapeFactory.cxx
+++ b/chart2/source/view/main/OpenglShapeFactory.cxx
@@ -55,18 +55,14 @@
 using namespace ::com::sun::star;
 using ::com::sun::star::uno::Reference;
 
-
 namespace chart
 {
 
 extern "C" {
+    SAL_DLLPUBLIC_EXPORT opengl::OpenglShapeFactory* getOpenglShapeFactory(uno::Reference< lang::XMultiServiceFactory> xFactory)
+                              {    return new opengl::OpenglShapeFactory(xFactory);}
+    }
 
-SAL_DLLPUBLIC_EXPORT opengl::OpenglShapeFactory* getOpenglShapeFactory()
-{
-    return new opengl::OpenglShapeFactory();
-}
-
-}
 
 using dummy::DummyXShape;
 using dummy::DummyXShapes;
@@ -117,7 +113,14 @@ uno::Reference< drawing::XShapes > OpenglShapeFactory::getOrCreateChartRootShape
     if( !xRet.is()  )
     {
         //create the root shape
+        SAL_WARN("chart2.opengl", "getOrCreateChartRootShape");
+        dummy::DummyChart *pChart = new dummy::DummyChart();
+        m_pChart = (void *)pChart;
+        xRet = pChart;
+#if 0
         xRet = new dummy::DummyChart();
+        m_pChart = (void *)((dummy::DummyChart *)xRet);
+#endif
         xDrawPage->add(uno::Reference< drawing::XShape >(xRet, uno::UNO_QUERY_THROW));
     }
     return xRet;
@@ -340,8 +343,101 @@ uno::Reference< drawing::XShape >
                     , const drawing::PointSequenceSequence& rPoints
                     , const VLineProperties* pLineProperties )
 {
+    SAL_WARN("chart2.opengl", "OpenglShapeFactory::createLine2D()-----test:");
     dummy::DummyLine2D* pLine = new dummy::DummyLine2D(rPoints, pLineProperties);
     xTarget->add(pLine);
+
+    dummy::DummyChart *pChart = (dummy::DummyChart *)m_pChart;
+    if (!m_pChart)
+    {
+        SAL_WARN("chart2.opengl", "createLine2D::DummyChart = NULL");
+    }
+
+
+//create shape
+    uno::Reference< drawing::XShape > xShape(
+        m_xShapeFactory->createInstance(
+            "com.sun.star.drawing.PolyLineShape" ), uno::UNO_QUERY );
+//    xTarget->add(xShape);
+
+    //set properties
+    uno::Reference< beans::XPropertySet > xProp( xShape, uno::UNO_QUERY );
+    OSL_ENSURE(xProp.is(), "created shape offers no XPropertySet");
+    if( xProp.is())
+    {
+        try
+        {
+            //Polygon
+            xProp->setPropertyValue( UNO_NAME_POLYPOLYGON
+                , uno::makeAny( rPoints ) );
+
+            if(pLineProperties)
+            {
+                //Transparency
+                if(pLineProperties->Transparence.hasValue())
+                    xProp->setPropertyValue( UNO_NAME_LINETRANSPARENCE
+                        , pLineProperties->Transparence );
+
+                //LineStyle
+                if(pLineProperties->LineStyle.hasValue())
+                    xProp->setPropertyValue( UNO_NAME_LINESTYLE
+                        , pLineProperties->LineStyle );
+
+                //LineWidth
+                if(pLineProperties->Width.hasValue())
+                    xProp->setPropertyValue( UNO_NAME_LINEWIDTH
+                        , pLineProperties->Width );
+
+                //LineColor
+                if(pLineProperties->Color.hasValue())
+                    xProp->setPropertyValue( UNO_NAME_LINECOLOR
+                        , pLineProperties->Color );
+
+                //LineDashName
+                if(pLineProperties->DashName.hasValue())
+                    xProp->setPropertyValue( "LineDashName"
+                        , pLineProperties->DashName );
+            }
+        }
+        catch( const uno::Exception& e )
+        {
+            ASSERT_EXCEPTION( e );
+        }
+
+    }
+    //set line color
+    uno::Any co =  xProp->getPropertyValue(UNO_NAME_LINECOLOR);
+    long *colorvalue = (long*)co.getValue();
+    SAL_WARN("chart2.opengl", "*colorvalue = " << (*colorvalue));
+    sal_uInt8 R = ((*colorvalue) & 0x00FF0000) >> 16;
+    sal_uInt8 G = ((*colorvalue) & 0x0000FF00) >> 8;
+    sal_uInt8 B = ((*colorvalue) & 0x000000FF);
+    pChart->m_GLRender.SetLine2DColor(R, G, B);
+
+    SAL_WARN("chart2.opengl", "*colorvalue = " << (*colorvalue) << ", R = " << (int)R << ", G = " << (int)G << ", B = " << (int)B);
+
+    //set line width
+    uno::Any cow =  xProp->getPropertyValue(UNO_NAME_LINEWIDTH);
+    long *width = (long*)cow.getValue();
+    pChart->m_GLRender.SetLine2DWidth((int)(*width));
+
+    SAL_WARN("chart2.opengl", "width = " << (*width));
+
+    com::sun::star::uno::Sequence<drawing::PointSequence> pointss =  rPoints;
+    int pointsscount = pointss.getLength();
+    for(int i = 0; i < pointsscount; i++)
+    {
+        com::sun::star::uno::Sequence<com::sun::star::awt::Point> points = pointss[i];
+        int pointscount = points.getLength();
+        for(int j = 0; j < pointscount; j++)
+        {
+            com::sun::star::awt::Point p = points[j];
+            pChart->m_GLRender.SetLine2DShapePoint((float)p.X, (float)p.Y, pointscount);
+ //           printf("point x:%ld,y:%ld\n",p.X,p.Y);
+        }
+
+    }
+    pChart->m_GLRender.RenderLine2FBO(GL_TRUE);
     return pLine;
 }
 
@@ -416,6 +512,7 @@ void OpenglShapeFactory::createSeries( const uno::Reference<
         drawing::XShapes> & ,
         const DataSeriesState& )
 {
+    SAL_WARN("chart2.opengl", "OpenglShapeFactory::createSeries()-----test:");
 }
 
 void OpenglShapeFactory::renderSeries( const uno::Reference<
@@ -424,6 +521,12 @@ void OpenglShapeFactory::renderSeries( const uno::Reference<
         const DataSeriesState&,
         double )
 {
+    SAL_WARN("chart2.opengl", "OpenglShapeFactory::renderSeries()-----test:");
+}
+
+OpenglShapeFactory::OpenglShapeFactory()
+{
+    m_pChart = NULL;
 }
 
 } //namespace dummy


More information about the Libreoffice-commits mailing list