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>
21 #include <Graphic3d_TextureParams.hxx>
23 // =======================================================================
24 // method : Constructor
26 // =======================================================================
27 OpenGl_BackgroundArray::OpenGl_BackgroundArray (const Graphic3d_TypeOfBackground theType)
28 : OpenGl_PrimitiveArray (NULL, Graphic3d_TOPA_TRIANGLESTRIPS, NULL, NULL, NULL),
29 myToUpdate (Standard_False),
33 myFillMethod (Aspect_FM_NONE)
35 Handle(NCollection_AlignedAllocator) anAlloc = new NCollection_AlignedAllocator (16);
36 myAttribs = new Graphic3d_Buffer (anAlloc);
38 myDrawMode = GL_TRIANGLE_STRIP;
40 myGradientParams.color1 = OpenGl_Vec4 (0.0f, 0.0f, 0.0f, 1.0f);
41 myGradientParams.color2 = OpenGl_Vec4 (0.0f, 0.0f, 0.0f, 1.0f);
42 myGradientParams.type = Aspect_GFM_NONE;
45 // =======================================================================
46 // method : SetTextureParameters
48 // =======================================================================
49 void OpenGl_BackgroundArray::SetTextureParameters (const Aspect_FillMethod theFillMethod)
51 if (myType != Graphic3d_TOB_TEXTURE)
56 myFillMethod = theFillMethod;
60 // =======================================================================
61 // method : SetTextureFillMethod
63 // =======================================================================
64 void OpenGl_BackgroundArray::SetTextureFillMethod (const Aspect_FillMethod theFillMethod)
66 myFillMethod = theFillMethod;
70 // =======================================================================
71 // method : SetGradientParameters
73 // =======================================================================
74 void OpenGl_BackgroundArray::SetGradientParameters (const Quantity_Color& theColor1,
75 const Quantity_Color& theColor2,
76 const Aspect_GradientFillMethod theType)
78 if (myType != Graphic3d_TOB_GRADIENT)
83 Standard_Real anR, aG, aB;
84 theColor1.Values (anR, aG, aB, Quantity_TOC_RGB);
85 myGradientParams.color1 = OpenGl_Vec4 ((float)anR, (float)aG, (float)aB, 0.0f);
87 theColor2.Values (anR, aG, aB, Quantity_TOC_RGB);
88 myGradientParams.color2 = OpenGl_Vec4 ((float)anR, (float)aG, (float)aB, 0.0f);
90 myGradientParams.type = theType;
94 // =======================================================================
95 // method : SetGradientFillMethod
97 // =======================================================================
98 void OpenGl_BackgroundArray::SetGradientFillMethod (const Aspect_GradientFillMethod theType)
100 if (myType != Graphic3d_TOB_GRADIENT)
105 myGradientParams.type = theType;
109 // =======================================================================
110 // method : IsDefined
112 // =======================================================================
113 bool OpenGl_BackgroundArray::IsDefined() const
117 case Graphic3d_TOB_GRADIENT: return myGradientParams.type != Aspect_GFM_NONE;
118 case Graphic3d_TOB_TEXTURE: return myFillMethod != Aspect_FM_NONE;
119 case Graphic3d_TOB_NONE: return Standard_False;
121 return Standard_False;
124 // =======================================================================
125 // method : invalidateData
127 // =======================================================================
128 void OpenGl_BackgroundArray::invalidateData()
130 myToUpdate = Standard_True;
133 // =======================================================================
136 // =======================================================================
137 Standard_Boolean OpenGl_BackgroundArray::Init (const Handle(OpenGl_Workspace)& theWorkspace)
141 case Graphic3d_TOB_GRADIENT:
143 if (!createGradientArray())
145 return Standard_False;
149 case Graphic3d_TOB_TEXTURE:
151 myViewWidth = theWorkspace->Width();
152 myViewHeight = theWorkspace->Height();
153 if (!createTextureArray (theWorkspace))
155 return Standard_False;
159 case Graphic3d_TOB_NONE:
162 return Standard_False;
167 const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
170 clearMemoryGL (aCtx);
172 buildVBO (aCtx, Standard_True);
173 myIsVboInit = Standard_True;
175 // Data is up-to-date
176 myToUpdate = Standard_False;
177 return Standard_True;
180 // =======================================================================
181 // method : createGradientArray
183 // =======================================================================
184 Standard_Boolean OpenGl_BackgroundArray::createGradientArray()
186 // Initialize data for primitive array
187 Graphic3d_Attribute aGragientAttribInfo[] =
189 { Graphic3d_TOA_POS, Graphic3d_TOD_VEC2 },
190 { Graphic3d_TOA_COLOR, Graphic3d_TOD_VEC3 }
193 if (!myAttribs->Init (4, aGragientAttribInfo, 2))
195 return Standard_False;
198 OpenGl_Vec2 aVertices[4] =
200 OpenGl_Vec2( 1.0f, -1.0f),
201 OpenGl_Vec2( 1.0f, 1.0f),
202 OpenGl_Vec2(-1.0f, -1.0f),
203 OpenGl_Vec2(-1.0f, 1.0f)
206 Tfloat* aCorners[4] = {};
207 Tfloat aDiagCorner1[3] = {};
208 Tfloat aDiagCorner2[3] = {};
210 switch (myGradientParams.type)
214 aCorners[0] = myGradientParams.color2.xyz().ChangeData();
215 aCorners[1] = myGradientParams.color2.xyz().ChangeData();
216 aCorners[2] = myGradientParams.color1.xyz().ChangeData();
217 aCorners[3] = myGradientParams.color1.xyz().ChangeData();
222 aCorners[0] = myGradientParams.color2.xyz().ChangeData();
223 aCorners[1] = myGradientParams.color1.xyz().ChangeData();
224 aCorners[2] = myGradientParams.color2.xyz().ChangeData();
225 aCorners[3] = myGradientParams.color1.xyz().ChangeData();
228 case Aspect_GFM_DIAG1:
230 aCorners[0] = myGradientParams.color2.xyz().ChangeData();
231 aCorners[3] = myGradientParams.color1.xyz().ChangeData();
232 aDiagCorner1[0] = aDiagCorner2[0] = 0.5f * (aCorners[0][0] + aCorners[3][0]);
233 aDiagCorner1[1] = aDiagCorner2[1] = 0.5f * (aCorners[0][1] + aCorners[3][1]);
234 aDiagCorner1[2] = aDiagCorner2[2] = 0.5f * (aCorners[0][2] + aCorners[3][2]);
235 aCorners[1] = aDiagCorner1;
236 aCorners[2] = aDiagCorner2;
239 case Aspect_GFM_DIAG2:
241 aCorners[1] = myGradientParams.color1.xyz().ChangeData();
242 aCorners[2] = myGradientParams.color2.xyz().ChangeData();
243 aDiagCorner1[0] = aDiagCorner2[0] = 0.5f * (aCorners[1][0] + aCorners[2][0]);
244 aDiagCorner1[1] = aDiagCorner2[1] = 0.5f * (aCorners[1][1] + aCorners[2][1]);
245 aDiagCorner1[2] = aDiagCorner2[2] = 0.5f * (aCorners[1][2] + aCorners[2][2]);
246 aCorners[0] = aDiagCorner1;
247 aCorners[3] = aDiagCorner2;
250 case Aspect_GFM_CORNER1:
252 aVertices[0] = OpenGl_Vec2( 1.0f, 1.0f);
253 aVertices[1] = OpenGl_Vec2(-1.0f, 1.0f);
254 aVertices[2] = OpenGl_Vec2( 1.0f, -1.0f);
255 aVertices[3] = OpenGl_Vec2(-1.0f, -1.0f);
257 aCorners[0] = myGradientParams.color2.xyz().ChangeData();
258 aCorners[1] = myGradientParams.color1.xyz().ChangeData();
259 aCorners[2] = myGradientParams.color2.xyz().ChangeData();
260 aCorners[3] = myGradientParams.color2.xyz().ChangeData();
263 case Aspect_GFM_CORNER2:
265 aCorners[0] = myGradientParams.color2.xyz().ChangeData();
266 aCorners[1] = myGradientParams.color1.xyz().ChangeData();
267 aCorners[2] = myGradientParams.color2.xyz().ChangeData();
268 aCorners[3] = myGradientParams.color2.xyz().ChangeData();
271 case Aspect_GFM_CORNER3:
273 aVertices[0] = OpenGl_Vec2( 1.0f, 1.0f);
274 aVertices[1] = OpenGl_Vec2(-1.0f, 1.0f);
275 aVertices[2] = OpenGl_Vec2( 1.0f, -1.0f);
276 aVertices[3] = OpenGl_Vec2(-1.0f, -1.0f);
278 aCorners[0] = myGradientParams.color2.xyz().ChangeData();
279 aCorners[1] = myGradientParams.color2.xyz().ChangeData();
280 aCorners[2] = myGradientParams.color1.xyz().ChangeData();
281 aCorners[3] = myGradientParams.color2.xyz().ChangeData();
284 case Aspect_GFM_CORNER4:
286 aCorners[0] = myGradientParams.color2.xyz().ChangeData();
287 aCorners[1] = myGradientParams.color2.xyz().ChangeData();
288 aCorners[2] = myGradientParams.color1.xyz().ChangeData();
289 aCorners[3] = myGradientParams.color2.xyz().ChangeData();
292 case Aspect_GFM_NONE:
298 for (Standard_Integer anIt = 0; anIt < 4; ++anIt)
300 OpenGl_Vec2* aVertData = reinterpret_cast<OpenGl_Vec2* >(myAttribs->changeValue (anIt));
301 *aVertData = aVertices[anIt];
303 OpenGl_Vec3* aColorData = reinterpret_cast<OpenGl_Vec3* >(myAttribs->changeValue (anIt) + myAttribs->AttributeOffset (1));
304 *aColorData = OpenGl_Vec3(aCorners[anIt][0], aCorners[anIt][1], aCorners[anIt][2]);
307 return Standard_True;
310 // =======================================================================
311 // method : createTextureArray
313 // =======================================================================
314 Standard_Boolean OpenGl_BackgroundArray::createTextureArray (const Handle(OpenGl_Workspace)& theWorkspace)
316 Graphic3d_Attribute aTextureAttribInfo[] =
318 { Graphic3d_TOA_POS, Graphic3d_TOD_VEC2 },
319 { Graphic3d_TOA_UV, Graphic3d_TOD_VEC2 }
322 if (!myAttribs->Init (4, aTextureAttribInfo, 2))
324 return Standard_False;
327 GLfloat aTexRangeX = 1.0f; // texture <s> coordinate
328 GLfloat aTexRangeY = 1.0f; // texture <t> coordinate
330 // Set up for stretching or tiling
331 GLfloat anOffsetX = 1.0f;
332 GLfloat anOffsetY = 1.0f;
334 // Setting this coefficient to -1.0f allows to tile textures relatively to the top-left corner of the view
335 // (value 1.0f corresponds to the initial behavior - tiling from the bottom-left corner)
336 GLfloat aCoef = -1.0f;
338 // Get texture parameters
339 const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
340 const OpenGl_AspectFace* anAspectFace = theWorkspace->AspectFace (Standard_False);
341 GLfloat aTextureWidth = (GLfloat )anAspectFace->TextureRes (aCtx)->SizeX();
342 GLfloat aTextureHeight = (GLfloat )anAspectFace->TextureRes (aCtx)->SizeY();
344 if (myFillMethod == Aspect_FM_CENTERED)
346 anOffsetX = aTextureWidth / (GLfloat )myViewWidth;
347 anOffsetY = aTextureHeight / (GLfloat )myViewHeight;
349 else if (myFillMethod == Aspect_FM_TILED)
351 aTexRangeX = (GLfloat )myViewWidth / aTextureWidth;
352 aTexRangeY = (GLfloat )myViewHeight / aTextureHeight;
355 // NOTE: texture is mapped using GL_REPEAT wrapping mode so integer part
356 // is simply ignored, and negative multiplier is here for convenience only
357 // and does not result e.g. in texture mirroring
360 OpenGl_Vec2* aData = reinterpret_cast<OpenGl_Vec2* >(myAttribs->changeValue (0));
361 aData[0] = OpenGl_Vec2 (anOffsetX, -aCoef * anOffsetY);
362 aData[1] = OpenGl_Vec2 (aTexRangeX, 0.0f);
364 aData = reinterpret_cast<OpenGl_Vec2* >(myAttribs->changeValue (1));
365 aData[0] = OpenGl_Vec2 (anOffsetX, aCoef * anOffsetY);
366 aData[1] = OpenGl_Vec2 (aTexRangeX, aCoef * aTexRangeY);
368 aData = reinterpret_cast<OpenGl_Vec2* >(myAttribs->changeValue (2));
369 aData[0] = OpenGl_Vec2 (-anOffsetX, -aCoef * anOffsetY);
370 aData[1] = OpenGl_Vec2 (0.0f, 0.0f);
372 aData = reinterpret_cast<OpenGl_Vec2* >(myAttribs->changeValue (3));
373 aData[0] = OpenGl_Vec2 (-anOffsetX, aCoef * anOffsetY);
374 aData[1] = OpenGl_Vec2 (0.0f, aCoef * aTexRangeY);
376 return Standard_True;