0030748: Visualization - Marker displayed in immediate layer ruins QT Quick view...
[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>
3bffef55 21#include <OpenGl_View.hxx>
c04c30b3 22#include <Graphic3d_TextureParams.hxx>
0b0320e7 23
24// =======================================================================
25// method : Constructor
26// purpose :
27// =======================================================================
28OpenGl_BackgroundArray::OpenGl_BackgroundArray (const Graphic3d_TypeOfBackground theType)
29: OpenGl_PrimitiveArray (NULL, Graphic3d_TOPA_TRIANGLESTRIPS, NULL, NULL, NULL),
778cd667 30 myTrsfPers (Graphic3d_TMF_2d, theType == Graphic3d_TOB_TEXTURE ? Aspect_TOTP_CENTER : Aspect_TOTP_LEFT_LOWER),
0b0320e7 31 myType (theType),
3bffef55 32 myFillMethod (Aspect_FM_NONE),
0b0320e7 33 myViewWidth (0),
34 myViewHeight (0),
3bffef55 35 myToUpdate (Standard_False)
0b0320e7 36{
37 Handle(NCollection_AlignedAllocator) anAlloc = new NCollection_AlignedAllocator (16);
38 myAttribs = new Graphic3d_Buffer (anAlloc);
39
d5846489 40 myDrawMode = GL_TRIANGLE_STRIP;
6ef0d6f1 41 myIsFillType = true;
0b0320e7 42
43 myGradientParams.color1 = OpenGl_Vec4 (0.0f, 0.0f, 0.0f, 1.0f);
44 myGradientParams.color2 = OpenGl_Vec4 (0.0f, 0.0f, 0.0f, 1.0f);
45 myGradientParams.type = Aspect_GFM_NONE;
46}
47
48// =======================================================================
49// method : SetTextureParameters
50// purpose :
51// =======================================================================
52void OpenGl_BackgroundArray::SetTextureParameters (const Aspect_FillMethod theFillMethod)
53{
54 if (myType != Graphic3d_TOB_TEXTURE)
55 {
56 return;
57 }
58
59 myFillMethod = theFillMethod;
60 invalidateData();
61}
62
63// =======================================================================
64// method : SetTextureFillMethod
65// purpose :
66// =======================================================================
67void OpenGl_BackgroundArray::SetTextureFillMethod (const Aspect_FillMethod theFillMethod)
68{
69 myFillMethod = theFillMethod;
70 invalidateData();
71}
72
73// =======================================================================
74// method : SetGradientParameters
75// purpose :
76// =======================================================================
77void OpenGl_BackgroundArray::SetGradientParameters (const Quantity_Color& theColor1,
78 const Quantity_Color& theColor2,
79 const Aspect_GradientFillMethod theType)
80{
81 if (myType != Graphic3d_TOB_GRADIENT)
82 {
83 return;
84 }
85
86 Standard_Real anR, aG, aB;
87 theColor1.Values (anR, aG, aB, Quantity_TOC_RGB);
88 myGradientParams.color1 = OpenGl_Vec4 ((float)anR, (float)aG, (float)aB, 0.0f);
89
90 theColor2.Values (anR, aG, aB, Quantity_TOC_RGB);
91 myGradientParams.color2 = OpenGl_Vec4 ((float)anR, (float)aG, (float)aB, 0.0f);
92
93 myGradientParams.type = theType;
94 invalidateData();
95}
96
97// =======================================================================
98// method : SetGradientFillMethod
99// purpose :
100// =======================================================================
101void OpenGl_BackgroundArray::SetGradientFillMethod (const Aspect_GradientFillMethod theType)
102{
103 if (myType != Graphic3d_TOB_GRADIENT)
104 {
105 return;
106 }
107
108 myGradientParams.type = theType;
109 invalidateData();
110}
111
112// =======================================================================
113// method : IsDefined
114// purpose :
115// =======================================================================
116bool OpenGl_BackgroundArray::IsDefined() const
117{
118 switch (myType)
119 {
120 case Graphic3d_TOB_GRADIENT: return myGradientParams.type != Aspect_GFM_NONE;
121 case Graphic3d_TOB_TEXTURE: return myFillMethod != Aspect_FM_NONE;
122 case Graphic3d_TOB_NONE: return Standard_False;
123 }
124 return Standard_False;
125}
126
127// =======================================================================
128// method : invalidateData
129// purpose :
130// =======================================================================
131void OpenGl_BackgroundArray::invalidateData()
132{
133 myToUpdate = Standard_True;
134}
135
136// =======================================================================
3bffef55 137// method : init
0b0320e7 138// purpose :
139// =======================================================================
3bffef55 140Standard_Boolean OpenGl_BackgroundArray::init (const Handle(OpenGl_Workspace)& theWorkspace) const
0b0320e7 141{
142 switch (myType)
143 {
144 case Graphic3d_TOB_GRADIENT:
145 {
146 if (!createGradientArray())
147 {
148 return Standard_False;
149 }
150 break;
151 }
152 case Graphic3d_TOB_TEXTURE:
153 {
0b0320e7 154 if (!createTextureArray (theWorkspace))
155 {
156 return Standard_False;
157 }
158 break;
159 }
160 case Graphic3d_TOB_NONE:
161 default:
162 {
163 return Standard_False;
164 }
165 }
166
167 // Init VBO
168 const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
169 if (myIsVboInit)
170 {
171 clearMemoryGL (aCtx);
172 }
173 buildVBO (aCtx, Standard_True);
174 myIsVboInit = Standard_True;
175
176 // Data is up-to-date
177 myToUpdate = Standard_False;
178 return Standard_True;
179}
180
181// =======================================================================
182// method : createGradientArray
183// purpose :
184// =======================================================================
3bffef55 185Standard_Boolean OpenGl_BackgroundArray::createGradientArray() const
0b0320e7 186{
187 // Initialize data for primitive array
188 Graphic3d_Attribute aGragientAttribInfo[] =
189 {
190 { Graphic3d_TOA_POS, Graphic3d_TOD_VEC2 },
191 { Graphic3d_TOA_COLOR, Graphic3d_TOD_VEC3 }
192 };
193
194 if (!myAttribs->Init (4, aGragientAttribInfo, 2))
195 {
196 return Standard_False;
197 }
198
199 OpenGl_Vec2 aVertices[4] =
200 {
3bffef55 201 OpenGl_Vec2(float(myViewWidth), 0.0f),
202 OpenGl_Vec2(float(myViewWidth), float(myViewHeight)),
203 OpenGl_Vec2(0.0f, 0.0f),
204 OpenGl_Vec2(0.0f, float(myViewHeight))
0b0320e7 205 };
206
b6472664 207 float* aCorners[4] = {};
208 float aDiagCorner1[3] = {};
209 float aDiagCorner2[3] = {};
0b0320e7 210
211 switch (myGradientParams.type)
212 {
213 case Aspect_GFM_HOR:
214 {
bc379358 215 aCorners[0] = myGradientParams.color2.ChangeData();
216 aCorners[1] = myGradientParams.color2.ChangeData();
217 aCorners[2] = myGradientParams.color1.ChangeData();
218 aCorners[3] = myGradientParams.color1.ChangeData();
0b0320e7 219 break;
220 }
221 case Aspect_GFM_VER:
222 {
bc379358 223 aCorners[0] = myGradientParams.color2.ChangeData();
224 aCorners[1] = myGradientParams.color1.ChangeData();
225 aCorners[2] = myGradientParams.color2.ChangeData();
226 aCorners[3] = myGradientParams.color1.ChangeData();
0b0320e7 227 break;
228 }
229 case Aspect_GFM_DIAG1:
230 {
bc379358 231 aCorners[0] = myGradientParams.color2.ChangeData();
232 aCorners[3] = myGradientParams.color1.ChangeData();
d5846489 233 aDiagCorner1[0] = aDiagCorner2[0] = 0.5f * (aCorners[0][0] + aCorners[3][0]);
234 aDiagCorner1[1] = aDiagCorner2[1] = 0.5f * (aCorners[0][1] + aCorners[3][1]);
235 aDiagCorner1[2] = aDiagCorner2[2] = 0.5f * (aCorners[0][2] + aCorners[3][2]);
236 aCorners[1] = aDiagCorner1;
0b0320e7 237 aCorners[2] = aDiagCorner2;
238 break;
239 }
240 case Aspect_GFM_DIAG2:
241 {
bc379358 242 aCorners[1] = myGradientParams.color1.ChangeData();
243 aCorners[2] = myGradientParams.color2.ChangeData();
d5846489 244 aDiagCorner1[0] = aDiagCorner2[0] = 0.5f * (aCorners[1][0] + aCorners[2][0]);
245 aDiagCorner1[1] = aDiagCorner2[1] = 0.5f * (aCorners[1][1] + aCorners[2][1]);
246 aDiagCorner1[2] = aDiagCorner2[2] = 0.5f * (aCorners[1][2] + aCorners[2][2]);
247 aCorners[0] = aDiagCorner1;
0b0320e7 248 aCorners[3] = aDiagCorner2;
249 break;
250 }
251 case Aspect_GFM_CORNER1:
252 {
3bffef55 253 aVertices[0] = OpenGl_Vec2(float(myViewWidth), float(myViewHeight));
254 aVertices[1] = OpenGl_Vec2(0.0f, float(myViewHeight));
255 aVertices[2] = OpenGl_Vec2(float(myViewWidth), 0.0f);
256 aVertices[3] = OpenGl_Vec2(0.0f, 0.0f);
d5846489 257
bc379358 258 aCorners[0] = myGradientParams.color2.ChangeData();
259 aCorners[1] = myGradientParams.color1.ChangeData();
260 aCorners[2] = myGradientParams.color2.ChangeData();
261 aCorners[3] = myGradientParams.color2.ChangeData();
0b0320e7 262 break;
263 }
264 case Aspect_GFM_CORNER2:
265 {
bc379358 266 aCorners[0] = myGradientParams.color2.ChangeData();
267 aCorners[1] = myGradientParams.color1.ChangeData();
268 aCorners[2] = myGradientParams.color2.ChangeData();
269 aCorners[3] = myGradientParams.color2.ChangeData();
0b0320e7 270 break;
271 }
272 case Aspect_GFM_CORNER3:
273 {
3bffef55 274 aVertices[0] = OpenGl_Vec2(float(myViewWidth), float(myViewHeight));
275 aVertices[1] = OpenGl_Vec2(0.0f, float(myViewHeight));
276 aVertices[2] = OpenGl_Vec2(float(myViewWidth), 0.0f);
277 aVertices[3] = OpenGl_Vec2(0.0f, 0.0f);
d5846489 278
bc379358 279 aCorners[0] = myGradientParams.color2.ChangeData();
280 aCorners[1] = myGradientParams.color2.ChangeData();
281 aCorners[2] = myGradientParams.color1.ChangeData();
282 aCorners[3] = myGradientParams.color2.ChangeData();
0b0320e7 283 break;
284 }
285 case Aspect_GFM_CORNER4:
286 {
bc379358 287 aCorners[0] = myGradientParams.color2.ChangeData();
288 aCorners[1] = myGradientParams.color2.ChangeData();
289 aCorners[2] = myGradientParams.color1.ChangeData();
290 aCorners[3] = myGradientParams.color2.ChangeData();
0b0320e7 291 break;
292 }
293 case Aspect_GFM_NONE:
294 {
295 break;
296 }
297 }
298
d5846489 299 for (Standard_Integer anIt = 0; anIt < 4; ++anIt)
0b0320e7 300 {
d5846489 301 OpenGl_Vec2* aVertData = reinterpret_cast<OpenGl_Vec2* >(myAttribs->changeValue (anIt));
302 *aVertData = aVertices[anIt];
0b0320e7 303
d5846489 304 OpenGl_Vec3* aColorData = reinterpret_cast<OpenGl_Vec3* >(myAttribs->changeValue (anIt) + myAttribs->AttributeOffset (1));
305 *aColorData = OpenGl_Vec3(aCorners[anIt][0], aCorners[anIt][1], aCorners[anIt][2]);
0b0320e7 306 }
307
308 return Standard_True;
309}
310
311// =======================================================================
312// method : createTextureArray
313// purpose :
314// =======================================================================
3bffef55 315Standard_Boolean OpenGl_BackgroundArray::createTextureArray (const Handle(OpenGl_Workspace)& theWorkspace) const
0b0320e7 316{
317 Graphic3d_Attribute aTextureAttribInfo[] =
318 {
319 { Graphic3d_TOA_POS, Graphic3d_TOD_VEC2 },
320 { Graphic3d_TOA_UV, Graphic3d_TOD_VEC2 }
321 };
322
323 if (!myAttribs->Init (4, aTextureAttribInfo, 2))
324 {
325 return Standard_False;
326 }
327
328 GLfloat aTexRangeX = 1.0f; // texture <s> coordinate
329 GLfloat aTexRangeY = 1.0f; // texture <t> coordinate
330
331 // Set up for stretching or tiling
3bffef55 332 GLfloat anOffsetX = 0.5f * (float )myViewWidth;
333 GLfloat anOffsetY = 0.5f * (float )myViewHeight;
0b0320e7 334
335 // Setting this coefficient to -1.0f allows to tile textures relatively to the top-left corner of the view
336 // (value 1.0f corresponds to the initial behavior - tiling from the bottom-left corner)
337 GLfloat aCoef = -1.0f;
338
339 // Get texture parameters
340 const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
bf5f0ca2 341 const OpenGl_Aspects* anAspectFace = theWorkspace->Aspects();
cc8cbabe 342 GLfloat aTextureWidth = (GLfloat )anAspectFace->TextureSet (aCtx)->First()->SizeX();
343 GLfloat aTextureHeight = (GLfloat )anAspectFace->TextureSet (aCtx)->First()->SizeY();
0b0320e7 344
345 if (myFillMethod == Aspect_FM_CENTERED)
346 {
3bffef55 347 anOffsetX = 0.5f * aTextureWidth;
348 anOffsetY = 0.5f * aTextureHeight;
0b0320e7 349 }
350 else if (myFillMethod == Aspect_FM_TILED)
351 {
352 aTexRangeX = (GLfloat )myViewWidth / aTextureWidth;
353 aTexRangeY = (GLfloat )myViewHeight / aTextureHeight;
354 }
355
356 // NOTE: texture is mapped using GL_REPEAT wrapping mode so integer part
357 // is simply ignored, and negative multiplier is here for convenience only
358 // and does not result e.g. in texture mirroring
359
0b0320e7 360
d5846489 361 OpenGl_Vec2* aData = reinterpret_cast<OpenGl_Vec2* >(myAttribs->changeValue (0));
0b0320e7 362 aData[0] = OpenGl_Vec2 (anOffsetX, -aCoef * anOffsetY);
363 aData[1] = OpenGl_Vec2 (aTexRangeX, 0.0f);
364
d5846489 365 aData = reinterpret_cast<OpenGl_Vec2* >(myAttribs->changeValue (1));
0b0320e7 366 aData[0] = OpenGl_Vec2 (anOffsetX, aCoef * anOffsetY);
367 aData[1] = OpenGl_Vec2 (aTexRangeX, aCoef * aTexRangeY);
368
d5846489 369 aData = reinterpret_cast<OpenGl_Vec2* >(myAttribs->changeValue (2));
370 aData[0] = OpenGl_Vec2 (-anOffsetX, -aCoef * anOffsetY);
371 aData[1] = OpenGl_Vec2 (0.0f, 0.0f);
372
0b0320e7 373 aData = reinterpret_cast<OpenGl_Vec2* >(myAttribs->changeValue (3));
374 aData[0] = OpenGl_Vec2 (-anOffsetX, aCoef * anOffsetY);
375 aData[1] = OpenGl_Vec2 (0.0f, aCoef * aTexRangeY);
376
377 return Standard_True;
378}
3bffef55 379
380// =======================================================================
381// method : createTextureArray
382// purpose :
383// =======================================================================
384void OpenGl_BackgroundArray::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
385{
386 const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
387 Standard_Integer aViewSizeX = aCtx->Viewport()[2];
388 Standard_Integer aViewSizeY = aCtx->Viewport()[3];
389 if (theWorkspace->View()->Camera()->Tile().IsValid())
390 {
391 aViewSizeX = theWorkspace->View()->Camera()->Tile().TotalSize.x();
392 aViewSizeY = theWorkspace->View()->Camera()->Tile().TotalSize.y();
393 }
394 if (myToUpdate
395 || myViewWidth != aViewSizeX
396 || myViewHeight != aViewSizeY)
397 {
398 myViewWidth = aViewSizeX;
399 myViewHeight = aViewSizeY;
400 init (theWorkspace);
401 }
402
403 OpenGl_Mat4 aProjection = aCtx->ProjectionState.Current();
404 OpenGl_Mat4 aWorldView = aCtx->WorldViewState.Current();
405 myTrsfPers.Apply (theWorkspace->View()->Camera(), aProjection, aWorldView,
406 aCtx->Viewport()[2], aCtx->Viewport()[3]);
407
408 aCtx->ProjectionState.Push();
409 aCtx->WorldViewState.Push();
410 aCtx->ProjectionState.SetCurrent (aProjection);
411 aCtx->WorldViewState.SetCurrent (aWorldView);
412 aCtx->ApplyProjectionMatrix();
413 aCtx->ApplyModelViewMatrix();
414
415 OpenGl_PrimitiveArray::Render (theWorkspace);
416
417 aCtx->ProjectionState.Pop();
418 aCtx->WorldViewState.Pop();
419 aCtx->ApplyProjectionMatrix();
420}