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 <pei...@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 _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits