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