0025804: Visualization, TKOpenGl - specify correct primitives type in OpenGl_Backgrou...
[occt.git] / src / OpenGl / OpenGl_BackgroundArray.cxx
CommitLineData
0b0320e7 1// Created on: 2015-01-16
2// Created by: Anastasia BORISOVA
3// Copyright (c) 2015 OPEN CASCADE SAS
4//
5// This file is part of Open CASCADE Technology software library.
6//
7// This library is free software; you can redistribute it and/or modify it under
8// the terms of the GNU Lesser General Public License version 2.1 as published
9// by the Free Software Foundation, with special exception defined in the file
10// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11// distribution for complete text of the license and disclaimer of any warranty.
12//
13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
15
16#include <OpenGl_BackgroundArray.hxx>
17
18#include <Aspect_FillMethod.hxx>
19#include <NCollection_AlignedAllocator.hxx>
20#include <OpenGl_Texture.hxx>
21
22// =======================================================================
23// method : Constructor
24// purpose :
25// =======================================================================
26OpenGl_BackgroundArray::OpenGl_BackgroundArray (const Graphic3d_TypeOfBackground theType)
27: OpenGl_PrimitiveArray (NULL, Graphic3d_TOPA_TRIANGLESTRIPS, NULL, NULL, NULL),
28 myToUpdate (Standard_False),
29 myType (theType),
30 myViewWidth (0),
31 myViewHeight (0),
32 myFillMethod (Aspect_FM_NONE)
33{
34 Handle(NCollection_AlignedAllocator) anAlloc = new NCollection_AlignedAllocator (16);
35 myAttribs = new Graphic3d_Buffer (anAlloc);
36
d5846489 37 myDrawMode = GL_TRIANGLE_STRIP;
0b0320e7 38
39 myGradientParams.color1 = OpenGl_Vec4 (0.0f, 0.0f, 0.0f, 1.0f);
40 myGradientParams.color2 = OpenGl_Vec4 (0.0f, 0.0f, 0.0f, 1.0f);
41 myGradientParams.type = Aspect_GFM_NONE;
42}
43
44// =======================================================================
45// method : SetTextureParameters
46// purpose :
47// =======================================================================
48void OpenGl_BackgroundArray::SetTextureParameters (const Aspect_FillMethod theFillMethod)
49{
50 if (myType != Graphic3d_TOB_TEXTURE)
51 {
52 return;
53 }
54
55 myFillMethod = theFillMethod;
56 invalidateData();
57}
58
59// =======================================================================
60// method : SetTextureFillMethod
61// purpose :
62// =======================================================================
63void OpenGl_BackgroundArray::SetTextureFillMethod (const Aspect_FillMethod theFillMethod)
64{
65 myFillMethod = theFillMethod;
66 invalidateData();
67}
68
69// =======================================================================
70// method : SetGradientParameters
71// purpose :
72// =======================================================================
73void OpenGl_BackgroundArray::SetGradientParameters (const Quantity_Color& theColor1,
74 const Quantity_Color& theColor2,
75 const Aspect_GradientFillMethod theType)
76{
77 if (myType != Graphic3d_TOB_GRADIENT)
78 {
79 return;
80 }
81
82 Standard_Real anR, aG, aB;
83 theColor1.Values (anR, aG, aB, Quantity_TOC_RGB);
84 myGradientParams.color1 = OpenGl_Vec4 ((float)anR, (float)aG, (float)aB, 0.0f);
85
86 theColor2.Values (anR, aG, aB, Quantity_TOC_RGB);
87 myGradientParams.color2 = OpenGl_Vec4 ((float)anR, (float)aG, (float)aB, 0.0f);
88
89 myGradientParams.type = theType;
90 invalidateData();
91}
92
93// =======================================================================
94// method : SetGradientFillMethod
95// purpose :
96// =======================================================================
97void OpenGl_BackgroundArray::SetGradientFillMethod (const Aspect_GradientFillMethod theType)
98{
99 if (myType != Graphic3d_TOB_GRADIENT)
100 {
101 return;
102 }
103
104 myGradientParams.type = theType;
105 invalidateData();
106}
107
108// =======================================================================
109// method : IsDefined
110// purpose :
111// =======================================================================
112bool OpenGl_BackgroundArray::IsDefined() const
113{
114 switch (myType)
115 {
116 case Graphic3d_TOB_GRADIENT: return myGradientParams.type != Aspect_GFM_NONE;
117 case Graphic3d_TOB_TEXTURE: return myFillMethod != Aspect_FM_NONE;
118 case Graphic3d_TOB_NONE: return Standard_False;
119 }
120 return Standard_False;
121}
122
123// =======================================================================
124// method : invalidateData
125// purpose :
126// =======================================================================
127void OpenGl_BackgroundArray::invalidateData()
128{
129 myToUpdate = Standard_True;
130}
131
132// =======================================================================
133// method : Init
134// purpose :
135// =======================================================================
136Standard_Boolean OpenGl_BackgroundArray::Init (const Handle(OpenGl_Workspace)& theWorkspace)
137{
138 switch (myType)
139 {
140 case Graphic3d_TOB_GRADIENT:
141 {
142 if (!createGradientArray())
143 {
144 return Standard_False;
145 }
146 break;
147 }
148 case Graphic3d_TOB_TEXTURE:
149 {
150 myViewWidth = theWorkspace->Width();
151 myViewHeight = theWorkspace->Height();
152 if (!createTextureArray (theWorkspace))
153 {
154 return Standard_False;
155 }
156 break;
157 }
158 case Graphic3d_TOB_NONE:
159 default:
160 {
161 return Standard_False;
162 }
163 }
164
165 // Init VBO
166 const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
167 if (myIsVboInit)
168 {
169 clearMemoryGL (aCtx);
170 }
171 buildVBO (aCtx, Standard_True);
172 myIsVboInit = Standard_True;
173
174 // Data is up-to-date
175 myToUpdate = Standard_False;
176 return Standard_True;
177}
178
179// =======================================================================
180// method : createGradientArray
181// purpose :
182// =======================================================================
183Standard_Boolean OpenGl_BackgroundArray::createGradientArray()
184{
185 // Initialize data for primitive array
186 Graphic3d_Attribute aGragientAttribInfo[] =
187 {
188 { Graphic3d_TOA_POS, Graphic3d_TOD_VEC2 },
189 { Graphic3d_TOA_COLOR, Graphic3d_TOD_VEC3 }
190 };
191
192 if (!myAttribs->Init (4, aGragientAttribInfo, 2))
193 {
194 return Standard_False;
195 }
196
197 OpenGl_Vec2 aVertices[4] =
198 {
0b0320e7 199 OpenGl_Vec2( 1.0f, -1.0f),
200 OpenGl_Vec2( 1.0f, 1.0f),
d5846489 201 OpenGl_Vec2(-1.0f, -1.0f),
0b0320e7 202 OpenGl_Vec2(-1.0f, 1.0f)
203 };
204
205 Tfloat* aCorners[4] = {};
206 Tfloat aDiagCorner1[3] = {};
207 Tfloat aDiagCorner2[3] = {};
208
209 switch (myGradientParams.type)
210 {
211 case Aspect_GFM_HOR:
212 {
d5846489 213 aCorners[0] = myGradientParams.color2.xyz().ChangeData();
0b0320e7 214 aCorners[1] = myGradientParams.color2.xyz().ChangeData();
d5846489 215 aCorners[2] = myGradientParams.color1.xyz().ChangeData();
0b0320e7 216 aCorners[3] = myGradientParams.color1.xyz().ChangeData();
217 break;
218 }
219 case Aspect_GFM_VER:
220 {
221 aCorners[0] = myGradientParams.color2.xyz().ChangeData();
d5846489 222 aCorners[1] = myGradientParams.color1.xyz().ChangeData();
223 aCorners[2] = myGradientParams.color2.xyz().ChangeData();
0b0320e7 224 aCorners[3] = myGradientParams.color1.xyz().ChangeData();
225 break;
226 }
227 case Aspect_GFM_DIAG1:
228 {
d5846489 229 aCorners[0] = myGradientParams.color2.xyz().ChangeData();
0b0320e7 230 aCorners[3] = myGradientParams.color1.xyz().ChangeData();
d5846489 231 aDiagCorner1[0] = aDiagCorner2[0] = 0.5f * (aCorners[0][0] + aCorners[3][0]);
232 aDiagCorner1[1] = aDiagCorner2[1] = 0.5f * (aCorners[0][1] + aCorners[3][1]);
233 aDiagCorner1[2] = aDiagCorner2[2] = 0.5f * (aCorners[0][2] + aCorners[3][2]);
234 aCorners[1] = aDiagCorner1;
0b0320e7 235 aCorners[2] = aDiagCorner2;
236 break;
237 }
238 case Aspect_GFM_DIAG2:
239 {
d5846489 240 aCorners[1] = myGradientParams.color1.xyz().ChangeData();
241 aCorners[2] = myGradientParams.color2.xyz().ChangeData();
242 aDiagCorner1[0] = aDiagCorner2[0] = 0.5f * (aCorners[1][0] + aCorners[2][0]);
243 aDiagCorner1[1] = aDiagCorner2[1] = 0.5f * (aCorners[1][1] + aCorners[2][1]);
244 aDiagCorner1[2] = aDiagCorner2[2] = 0.5f * (aCorners[1][2] + aCorners[2][2]);
245 aCorners[0] = aDiagCorner1;
0b0320e7 246 aCorners[3] = aDiagCorner2;
247 break;
248 }
249 case Aspect_GFM_CORNER1:
250 {
d5846489 251 aVertices[0] = OpenGl_Vec2( 1.0f, 1.0f);
252 aVertices[1] = OpenGl_Vec2(-1.0f, 1.0f);
253 aVertices[2] = OpenGl_Vec2( 1.0f, -1.0f);
254 aVertices[3] = OpenGl_Vec2(-1.0f, -1.0f);
255
0b0320e7 256 aCorners[0] = myGradientParams.color2.xyz().ChangeData();
d5846489 257 aCorners[1] = myGradientParams.color1.xyz().ChangeData();
0b0320e7 258 aCorners[2] = myGradientParams.color2.xyz().ChangeData();
d5846489 259 aCorners[3] = myGradientParams.color2.xyz().ChangeData();
0b0320e7 260 break;
261 }
262 case Aspect_GFM_CORNER2:
263 {
264 aCorners[0] = myGradientParams.color2.xyz().ChangeData();
d5846489 265 aCorners[1] = myGradientParams.color1.xyz().ChangeData();
266 aCorners[2] = myGradientParams.color2.xyz().ChangeData();
0b0320e7 267 aCorners[3] = myGradientParams.color2.xyz().ChangeData();
268 break;
269 }
270 case Aspect_GFM_CORNER3:
271 {
d5846489 272 aVertices[0] = OpenGl_Vec2( 1.0f, 1.0f);
273 aVertices[1] = OpenGl_Vec2(-1.0f, 1.0f);
274 aVertices[2] = OpenGl_Vec2( 1.0f, -1.0f);
275 aVertices[3] = OpenGl_Vec2(-1.0f, -1.0f);
276
0b0320e7 277 aCorners[0] = myGradientParams.color2.xyz().ChangeData();
d5846489 278 aCorners[1] = myGradientParams.color2.xyz().ChangeData();
279 aCorners[2] = myGradientParams.color1.xyz().ChangeData();
0b0320e7 280 aCorners[3] = myGradientParams.color2.xyz().ChangeData();
281 break;
282 }
283 case Aspect_GFM_CORNER4:
284 {
d5846489 285 aCorners[0] = myGradientParams.color2.xyz().ChangeData();
0b0320e7 286 aCorners[1] = myGradientParams.color2.xyz().ChangeData();
d5846489 287 aCorners[2] = myGradientParams.color1.xyz().ChangeData();
0b0320e7 288 aCorners[3] = myGradientParams.color2.xyz().ChangeData();
289 break;
290 }
291 case Aspect_GFM_NONE:
292 {
293 break;
294 }
295 }
296
d5846489 297 for (Standard_Integer anIt = 0; anIt < 4; ++anIt)
0b0320e7 298 {
d5846489 299 OpenGl_Vec2* aVertData = reinterpret_cast<OpenGl_Vec2* >(myAttribs->changeValue (anIt));
300 *aVertData = aVertices[anIt];
0b0320e7 301
d5846489 302 OpenGl_Vec3* aColorData = reinterpret_cast<OpenGl_Vec3* >(myAttribs->changeValue (anIt) + myAttribs->AttributeOffset (1));
303 *aColorData = OpenGl_Vec3(aCorners[anIt][0], aCorners[anIt][1], aCorners[anIt][2]);
0b0320e7 304 }
305
306 return Standard_True;
307}
308
309// =======================================================================
310// method : createTextureArray
311// purpose :
312// =======================================================================
313Standard_Boolean OpenGl_BackgroundArray::createTextureArray (const Handle(OpenGl_Workspace)& theWorkspace)
314{
315 Graphic3d_Attribute aTextureAttribInfo[] =
316 {
317 { Graphic3d_TOA_POS, Graphic3d_TOD_VEC2 },
318 { Graphic3d_TOA_UV, Graphic3d_TOD_VEC2 }
319 };
320
321 if (!myAttribs->Init (4, aTextureAttribInfo, 2))
322 {
323 return Standard_False;
324 }
325
326 GLfloat aTexRangeX = 1.0f; // texture <s> coordinate
327 GLfloat aTexRangeY = 1.0f; // texture <t> coordinate
328
329 // Set up for stretching or tiling
330 GLfloat anOffsetX = 1.0f;
331 GLfloat anOffsetY = 1.0f;
332
333 // Setting this coefficient to -1.0f allows to tile textures relatively to the top-left corner of the view
334 // (value 1.0f corresponds to the initial behavior - tiling from the bottom-left corner)
335 GLfloat aCoef = -1.0f;
336
337 // Get texture parameters
338 const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
339 const OpenGl_AspectFace* anAspectFace = theWorkspace->AspectFace (Standard_False);
340 GLfloat aTextureWidth = (GLfloat )anAspectFace->TextureRes (aCtx)->SizeX();
341 GLfloat aTextureHeight = (GLfloat )anAspectFace->TextureRes (aCtx)->SizeY();
342
343 if (myFillMethod == Aspect_FM_CENTERED)
344 {
345 anOffsetX = aTextureWidth / (GLfloat )myViewWidth;
346 anOffsetY = aTextureHeight / (GLfloat )myViewHeight;
347 }
348 else if (myFillMethod == Aspect_FM_TILED)
349 {
350 aTexRangeX = (GLfloat )myViewWidth / aTextureWidth;
351 aTexRangeY = (GLfloat )myViewHeight / aTextureHeight;
352 }
353
354 // NOTE: texture is mapped using GL_REPEAT wrapping mode so integer part
355 // is simply ignored, and negative multiplier is here for convenience only
356 // and does not result e.g. in texture mirroring
357
0b0320e7 358
d5846489 359 OpenGl_Vec2* aData = reinterpret_cast<OpenGl_Vec2* >(myAttribs->changeValue (0));
0b0320e7 360 aData[0] = OpenGl_Vec2 (anOffsetX, -aCoef * anOffsetY);
361 aData[1] = OpenGl_Vec2 (aTexRangeX, 0.0f);
362
d5846489 363 aData = reinterpret_cast<OpenGl_Vec2* >(myAttribs->changeValue (1));
0b0320e7 364 aData[0] = OpenGl_Vec2 (anOffsetX, aCoef * anOffsetY);
365 aData[1] = OpenGl_Vec2 (aTexRangeX, aCoef * aTexRangeY);
366
d5846489 367 aData = reinterpret_cast<OpenGl_Vec2* >(myAttribs->changeValue (2));
368 aData[0] = OpenGl_Vec2 (-anOffsetX, -aCoef * anOffsetY);
369 aData[1] = OpenGl_Vec2 (0.0f, 0.0f);
370
0b0320e7 371 aData = reinterpret_cast<OpenGl_Vec2* >(myAttribs->changeValue (3));
372 aData[0] = OpenGl_Vec2 (-anOffsetX, aCoef * anOffsetY);
373 aData[1] = OpenGl_Vec2 (0.0f, aCoef * aTexRangeY);
374
375 return Standard_True;
376}