1 // Created on: 2015-01-16
2 // Created by: Anastasia BORISOVA
3 // Copyright (c) 2015 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
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.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <OpenGl_BackgroundArray.hxx>
18 #include <Aspect_FillMethod.hxx>
19 #include <NCollection_AlignedAllocator.hxx>
20 #include <OpenGl_Texture.hxx>
22 // =======================================================================
23 // method : Constructor
25 // =======================================================================
26 OpenGl_BackgroundArray::OpenGl_BackgroundArray (const Graphic3d_TypeOfBackground theType)
27 : OpenGl_PrimitiveArray (NULL, Graphic3d_TOPA_TRIANGLESTRIPS, NULL, NULL, NULL),
28 myToUpdate (Standard_False),
32 myFillMethod (Aspect_FM_NONE)
34 Handle(NCollection_AlignedAllocator) anAlloc = new NCollection_AlignedAllocator (16);
35 myAttribs = new Graphic3d_Buffer (anAlloc);
37 myDrawMode = Graphic3d_TOPA_TRIANGLESTRIPS;
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;
44 // =======================================================================
45 // method : SetTextureParameters
47 // =======================================================================
48 void OpenGl_BackgroundArray::SetTextureParameters (const Aspect_FillMethod theFillMethod)
50 if (myType != Graphic3d_TOB_TEXTURE)
55 myFillMethod = theFillMethod;
59 // =======================================================================
60 // method : SetTextureFillMethod
62 // =======================================================================
63 void OpenGl_BackgroundArray::SetTextureFillMethod (const Aspect_FillMethod theFillMethod)
65 myFillMethod = theFillMethod;
69 // =======================================================================
70 // method : SetGradientParameters
72 // =======================================================================
73 void OpenGl_BackgroundArray::SetGradientParameters (const Quantity_Color& theColor1,
74 const Quantity_Color& theColor2,
75 const Aspect_GradientFillMethod theType)
77 if (myType != Graphic3d_TOB_GRADIENT)
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);
86 theColor2.Values (anR, aG, aB, Quantity_TOC_RGB);
87 myGradientParams.color2 = OpenGl_Vec4 ((float)anR, (float)aG, (float)aB, 0.0f);
89 myGradientParams.type = theType;
93 // =======================================================================
94 // method : SetGradientFillMethod
96 // =======================================================================
97 void OpenGl_BackgroundArray::SetGradientFillMethod (const Aspect_GradientFillMethod theType)
99 if (myType != Graphic3d_TOB_GRADIENT)
104 myGradientParams.type = theType;
108 // =======================================================================
109 // method : IsDefined
111 // =======================================================================
112 bool OpenGl_BackgroundArray::IsDefined() const
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;
120 return Standard_False;
123 // =======================================================================
124 // method : invalidateData
126 // =======================================================================
127 void OpenGl_BackgroundArray::invalidateData()
129 myToUpdate = Standard_True;
132 // =======================================================================
135 // =======================================================================
136 Standard_Boolean OpenGl_BackgroundArray::Init (const Handle(OpenGl_Workspace)& theWorkspace)
140 case Graphic3d_TOB_GRADIENT:
142 if (!createGradientArray())
144 return Standard_False;
148 case Graphic3d_TOB_TEXTURE:
150 myViewWidth = theWorkspace->Width();
151 myViewHeight = theWorkspace->Height();
152 if (!createTextureArray (theWorkspace))
154 return Standard_False;
158 case Graphic3d_TOB_NONE:
161 return Standard_False;
166 const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
169 clearMemoryGL (aCtx);
171 buildVBO (aCtx, Standard_True);
172 myIsVboInit = Standard_True;
174 // Data is up-to-date
175 myToUpdate = Standard_False;
176 return Standard_True;
179 // =======================================================================
180 // method : createGradientArray
182 // =======================================================================
183 Standard_Boolean OpenGl_BackgroundArray::createGradientArray()
185 // Initialize data for primitive array
186 Graphic3d_Attribute aGragientAttribInfo[] =
188 { Graphic3d_TOA_POS, Graphic3d_TOD_VEC2 },
189 { Graphic3d_TOA_COLOR, Graphic3d_TOD_VEC3 }
192 if (!myAttribs->Init (4, aGragientAttribInfo, 2))
194 return Standard_False;
197 OpenGl_Vec2 aVertices[4] =
199 OpenGl_Vec2(-1.0f, -1.0f),
200 OpenGl_Vec2( 1.0f, -1.0f),
201 OpenGl_Vec2( 1.0f, 1.0f),
202 OpenGl_Vec2(-1.0f, 1.0f)
205 Tfloat* aCorners[4] = {};
206 Tfloat aDiagCorner1[3] = {};
207 Tfloat aDiagCorner2[3] = {};
209 switch (myGradientParams.type)
213 aCorners[0] = myGradientParams.color1.xyz().ChangeData();
214 aCorners[1] = myGradientParams.color2.xyz().ChangeData();
215 aCorners[2] = myGradientParams.color2.xyz().ChangeData();
216 aCorners[3] = myGradientParams.color1.xyz().ChangeData();
221 aCorners[0] = myGradientParams.color2.xyz().ChangeData();
222 aCorners[1] = myGradientParams.color2.xyz().ChangeData();
223 aCorners[2] = myGradientParams.color1.xyz().ChangeData();
224 aCorners[3] = myGradientParams.color1.xyz().ChangeData();
227 case Aspect_GFM_DIAG1:
229 aCorners[1] = myGradientParams.color2.xyz().ChangeData();
230 aCorners[3] = myGradientParams.color1.xyz().ChangeData();
231 aDiagCorner1[0] = aDiagCorner2[0] = 0.5f * (aCorners[1][0] + aCorners[3][0]);
232 aDiagCorner1[1] = aDiagCorner2[1] = 0.5f * (aCorners[1][1] + aCorners[3][1]);
233 aDiagCorner1[2] = aDiagCorner2[2] = 0.5f * (aCorners[1][2] + aCorners[3][2]);
234 aCorners[0] = aDiagCorner1;
235 aCorners[2] = aDiagCorner2;
238 case Aspect_GFM_DIAG2:
240 aCorners[0] = myGradientParams.color2.xyz().ChangeData();
241 aCorners[2] = myGradientParams.color1.xyz().ChangeData();
242 aDiagCorner1[0] = aDiagCorner2[0] = 0.5f * (aCorners[0][0] + aCorners[2][0]);
243 aDiagCorner1[1] = aDiagCorner2[1] = 0.5f * (aCorners[0][1] + aCorners[2][1]);
244 aDiagCorner1[2] = aDiagCorner2[2] = 0.5f * (aCorners[0][2] + aCorners[2][2]);
245 aCorners[1] = aDiagCorner1;
246 aCorners[3] = aDiagCorner2;
249 case Aspect_GFM_CORNER1:
251 aCorners[0] = myGradientParams.color2.xyz().ChangeData();
252 aCorners[1] = myGradientParams.color2.xyz().ChangeData();
253 aCorners[2] = myGradientParams.color2.xyz().ChangeData();
254 aCorners[3] = myGradientParams.color1.xyz().ChangeData();
257 case Aspect_GFM_CORNER2:
259 aCorners[0] = myGradientParams.color2.xyz().ChangeData();
260 aCorners[1] = myGradientParams.color2.xyz().ChangeData();
261 aCorners[2] = myGradientParams.color1.xyz().ChangeData();
262 aCorners[3] = myGradientParams.color2.xyz().ChangeData();
265 case Aspect_GFM_CORNER3:
267 aCorners[0] = myGradientParams.color2.xyz().ChangeData();
268 aCorners[1] = myGradientParams.color1.xyz().ChangeData();
269 aCorners[2] = myGradientParams.color2.xyz().ChangeData();
270 aCorners[3] = myGradientParams.color2.xyz().ChangeData();
273 case Aspect_GFM_CORNER4:
275 aCorners[0] = myGradientParams.color1.xyz().ChangeData();
276 aCorners[1] = myGradientParams.color2.xyz().ChangeData();
277 aCorners[2] = myGradientParams.color2.xyz().ChangeData();
278 aCorners[3] = myGradientParams.color2.xyz().ChangeData();
281 case Aspect_GFM_NONE:
287 if (myGradientParams.type != Aspect_GFM_CORNER1
288 && myGradientParams.type != Aspect_GFM_CORNER3)
290 for (Standard_Integer anIt = 0; anIt < 4; ++anIt)
292 OpenGl_Vec2* aVertData = reinterpret_cast<OpenGl_Vec2* >(myAttribs->changeValue (anIt));
293 *aVertData = aVertices[anIt];
295 OpenGl_Vec3* aColorData = reinterpret_cast<OpenGl_Vec3* >(myAttribs->changeValue (anIt) + myAttribs->AttributeOffset (1));
296 *aColorData = OpenGl_Vec3(aCorners[anIt][0], aCorners[anIt][1], aCorners[anIt][2]);
299 else //if (myGradientParams.type == Aspect_GFM_CORNER1 || myGradientParams.type == Aspect_GFM_CORNER3)
301 for (Standard_Integer anIt = 0; anIt < 4; ++anIt)
303 // Indices should be in sequence 1, 2, 3, 0
304 Standard_Integer anIndex = (anIt + 1) % 4;
305 OpenGl_Vec2* aVertData = reinterpret_cast<OpenGl_Vec2* >(myAttribs->changeValue (anIt));
306 *aVertData = aVertices[anIndex];
308 OpenGl_Vec3* aColorData = reinterpret_cast<OpenGl_Vec3* >(myAttribs->changeValue (anIt) + myAttribs->AttributeOffset (1));
309 *aColorData = OpenGl_Vec3(aCorners[anIndex][0], aCorners[anIndex][1], aCorners[anIndex][2]);
313 return Standard_True;
316 // =======================================================================
317 // method : createTextureArray
319 // =======================================================================
320 Standard_Boolean OpenGl_BackgroundArray::createTextureArray (const Handle(OpenGl_Workspace)& theWorkspace)
322 Graphic3d_Attribute aTextureAttribInfo[] =
324 { Graphic3d_TOA_POS, Graphic3d_TOD_VEC2 },
325 { Graphic3d_TOA_UV, Graphic3d_TOD_VEC2 }
328 if (!myAttribs->Init (4, aTextureAttribInfo, 2))
330 return Standard_False;
333 GLfloat aTexRangeX = 1.0f; // texture <s> coordinate
334 GLfloat aTexRangeY = 1.0f; // texture <t> coordinate
336 // Set up for stretching or tiling
337 GLfloat anOffsetX = 1.0f;
338 GLfloat anOffsetY = 1.0f;
340 // Setting this coefficient to -1.0f allows to tile textures relatively to the top-left corner of the view
341 // (value 1.0f corresponds to the initial behavior - tiling from the bottom-left corner)
342 GLfloat aCoef = -1.0f;
344 // Get texture parameters
345 const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
346 const OpenGl_AspectFace* anAspectFace = theWorkspace->AspectFace (Standard_False);
347 GLfloat aTextureWidth = (GLfloat )anAspectFace->TextureRes (aCtx)->SizeX();
348 GLfloat aTextureHeight = (GLfloat )anAspectFace->TextureRes (aCtx)->SizeY();
350 if (myFillMethod == Aspect_FM_CENTERED)
352 anOffsetX = aTextureWidth / (GLfloat )myViewWidth;
353 anOffsetY = aTextureHeight / (GLfloat )myViewHeight;
355 else if (myFillMethod == Aspect_FM_TILED)
357 aTexRangeX = (GLfloat )myViewWidth / aTextureWidth;
358 aTexRangeY = (GLfloat )myViewHeight / aTextureHeight;
361 // NOTE: texture is mapped using GL_REPEAT wrapping mode so integer part
362 // is simply ignored, and negative multiplier is here for convenience only
363 // and does not result e.g. in texture mirroring
365 OpenGl_Vec2* aData = reinterpret_cast<OpenGl_Vec2* >(myAttribs->changeValue (0));
366 aData[0] = OpenGl_Vec2 (-anOffsetX, -aCoef * anOffsetY);
367 aData[1] = OpenGl_Vec2 (0.0f, 0.0f);
369 aData = reinterpret_cast<OpenGl_Vec2* >(myAttribs->changeValue (1));
370 aData[0] = OpenGl_Vec2 (anOffsetX, -aCoef * anOffsetY);
371 aData[1] = OpenGl_Vec2 (aTexRangeX, 0.0f);
373 aData = reinterpret_cast<OpenGl_Vec2* >(myAttribs->changeValue (2));
374 aData[0] = OpenGl_Vec2 (anOffsetX, aCoef * anOffsetY);
375 aData[1] = OpenGl_Vec2 (aTexRangeX, aCoef * aTexRangeY);
377 aData = reinterpret_cast<OpenGl_Vec2* >(myAttribs->changeValue (3));
378 aData[0] = OpenGl_Vec2 (-anOffsetX, aCoef * anOffsetY);
379 aData[1] = OpenGl_Vec2 (0.0f, aCoef * aTexRangeY);
381 return Standard_True;