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 | // ======================================================================= |
28 | OpenGl_BackgroundArray::OpenGl_BackgroundArray (const Graphic3d_TypeOfBackground theType) |
29 | : OpenGl_PrimitiveArray (NULL, Graphic3d_TOPA_TRIANGLESTRIPS, NULL, NULL, NULL), |
0b0320e7 |
30 | myType (theType), |
3bffef55 |
31 | myFillMethod (Aspect_FM_NONE), |
0b0320e7 |
32 | myViewWidth (0), |
33 | myViewHeight (0), |
3bffef55 |
34 | myToUpdate (Standard_False) |
0b0320e7 |
35 | { |
d5846489 |
36 | myDrawMode = GL_TRIANGLE_STRIP; |
6ef0d6f1 |
37 | myIsFillType = true; |
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 | // ======================================================================= |
48 | void 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 | // ======================================================================= |
63 | void OpenGl_BackgroundArray::SetTextureFillMethod (const Aspect_FillMethod theFillMethod) |
64 | { |
65 | myFillMethod = theFillMethod; |
66 | invalidateData(); |
67 | } |
68 | |
69 | // ======================================================================= |
70 | // method : SetGradientParameters |
71 | // purpose : |
72 | // ======================================================================= |
73 | void 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 | // ======================================================================= |
97 | void 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 | // ======================================================================= |
112 | bool 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; |
077a220c |
118 | case Graphic3d_TOB_CUBEMAP: return Standard_True; |
0b0320e7 |
119 | case Graphic3d_TOB_NONE: return Standard_False; |
120 | } |
121 | return Standard_False; |
122 | } |
123 | |
124 | // ======================================================================= |
125 | // method : invalidateData |
126 | // purpose : |
127 | // ======================================================================= |
128 | void OpenGl_BackgroundArray::invalidateData() |
129 | { |
130 | myToUpdate = Standard_True; |
131 | } |
132 | |
133 | // ======================================================================= |
3bffef55 |
134 | // method : init |
0b0320e7 |
135 | // purpose : |
136 | // ======================================================================= |
3bffef55 |
137 | Standard_Boolean OpenGl_BackgroundArray::init (const Handle(OpenGl_Workspace)& theWorkspace) const |
0b0320e7 |
138 | { |
ba00aab7 |
139 | const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext(); |
0b0320e7 |
140 | switch (myType) |
141 | { |
142 | case Graphic3d_TOB_GRADIENT: |
143 | { |
ba00aab7 |
144 | if (!createGradientArray (aCtx)) |
0b0320e7 |
145 | { |
146 | return Standard_False; |
147 | } |
148 | break; |
149 | } |
150 | case Graphic3d_TOB_TEXTURE: |
151 | { |
0b0320e7 |
152 | if (!createTextureArray (theWorkspace)) |
153 | { |
154 | return Standard_False; |
155 | } |
156 | break; |
157 | } |
077a220c |
158 | case Graphic3d_TOB_CUBEMAP: |
159 | { |
160 | if (!createCubeMapArray()) |
161 | { |
162 | return Standard_False; |
163 | } |
164 | break; |
165 | } |
0b0320e7 |
166 | case Graphic3d_TOB_NONE: |
167 | default: |
168 | { |
169 | return Standard_False; |
170 | } |
171 | } |
172 | |
173 | // Init VBO |
0b0320e7 |
174 | if (myIsVboInit) |
175 | { |
176 | clearMemoryGL (aCtx); |
177 | } |
178 | buildVBO (aCtx, Standard_True); |
179 | myIsVboInit = Standard_True; |
180 | |
181 | // Data is up-to-date |
182 | myToUpdate = Standard_False; |
183 | return Standard_True; |
184 | } |
185 | |
186 | // ======================================================================= |
187 | // method : createGradientArray |
188 | // purpose : |
189 | // ======================================================================= |
ba00aab7 |
190 | Standard_Boolean OpenGl_BackgroundArray::createGradientArray (const Handle(OpenGl_Context)& theCtx) const |
0b0320e7 |
191 | { |
192 | // Initialize data for primitive array |
193 | Graphic3d_Attribute aGragientAttribInfo[] = |
194 | { |
195 | { Graphic3d_TOA_POS, Graphic3d_TOD_VEC2 }, |
196 | { Graphic3d_TOA_COLOR, Graphic3d_TOD_VEC3 } |
197 | }; |
198 | |
ba00aab7 |
199 | if (myAttribs.IsNull()) |
200 | { |
201 | Handle(NCollection_AlignedAllocator) anAlloc = new NCollection_AlignedAllocator (16); |
202 | myAttribs = new Graphic3d_Buffer (anAlloc); |
203 | } |
0b0320e7 |
204 | if (!myAttribs->Init (4, aGragientAttribInfo, 2)) |
205 | { |
206 | return Standard_False; |
207 | } |
208 | |
209 | OpenGl_Vec2 aVertices[4] = |
210 | { |
3bffef55 |
211 | OpenGl_Vec2(float(myViewWidth), 0.0f), |
212 | OpenGl_Vec2(float(myViewWidth), float(myViewHeight)), |
213 | OpenGl_Vec2(0.0f, 0.0f), |
214 | OpenGl_Vec2(0.0f, float(myViewHeight)) |
0b0320e7 |
215 | }; |
216 | |
b6472664 |
217 | float* aCorners[4] = {}; |
218 | float aDiagCorner1[3] = {}; |
219 | float aDiagCorner2[3] = {}; |
0b0320e7 |
220 | |
221 | switch (myGradientParams.type) |
222 | { |
223 | case Aspect_GFM_HOR: |
224 | { |
bc379358 |
225 | aCorners[0] = myGradientParams.color2.ChangeData(); |
226 | aCorners[1] = myGradientParams.color2.ChangeData(); |
227 | aCorners[2] = myGradientParams.color1.ChangeData(); |
228 | aCorners[3] = myGradientParams.color1.ChangeData(); |
0b0320e7 |
229 | break; |
230 | } |
231 | case Aspect_GFM_VER: |
232 | { |
bc379358 |
233 | aCorners[0] = myGradientParams.color2.ChangeData(); |
234 | aCorners[1] = myGradientParams.color1.ChangeData(); |
235 | aCorners[2] = myGradientParams.color2.ChangeData(); |
236 | aCorners[3] = myGradientParams.color1.ChangeData(); |
0b0320e7 |
237 | break; |
238 | } |
239 | case Aspect_GFM_DIAG1: |
240 | { |
bc379358 |
241 | aCorners[0] = myGradientParams.color2.ChangeData(); |
242 | aCorners[3] = myGradientParams.color1.ChangeData(); |
d5846489 |
243 | aDiagCorner1[0] = aDiagCorner2[0] = 0.5f * (aCorners[0][0] + aCorners[3][0]); |
244 | aDiagCorner1[1] = aDiagCorner2[1] = 0.5f * (aCorners[0][1] + aCorners[3][1]); |
245 | aDiagCorner1[2] = aDiagCorner2[2] = 0.5f * (aCorners[0][2] + aCorners[3][2]); |
246 | aCorners[1] = aDiagCorner1; |
0b0320e7 |
247 | aCorners[2] = aDiagCorner2; |
248 | break; |
249 | } |
250 | case Aspect_GFM_DIAG2: |
251 | { |
bc379358 |
252 | aCorners[1] = myGradientParams.color1.ChangeData(); |
253 | aCorners[2] = myGradientParams.color2.ChangeData(); |
d5846489 |
254 | aDiagCorner1[0] = aDiagCorner2[0] = 0.5f * (aCorners[1][0] + aCorners[2][0]); |
255 | aDiagCorner1[1] = aDiagCorner2[1] = 0.5f * (aCorners[1][1] + aCorners[2][1]); |
256 | aDiagCorner1[2] = aDiagCorner2[2] = 0.5f * (aCorners[1][2] + aCorners[2][2]); |
257 | aCorners[0] = aDiagCorner1; |
0b0320e7 |
258 | aCorners[3] = aDiagCorner2; |
259 | break; |
260 | } |
261 | case Aspect_GFM_CORNER1: |
262 | { |
3bffef55 |
263 | aVertices[0] = OpenGl_Vec2(float(myViewWidth), float(myViewHeight)); |
264 | aVertices[1] = OpenGl_Vec2(0.0f, float(myViewHeight)); |
265 | aVertices[2] = OpenGl_Vec2(float(myViewWidth), 0.0f); |
266 | aVertices[3] = OpenGl_Vec2(0.0f, 0.0f); |
d5846489 |
267 | |
bc379358 |
268 | aCorners[0] = myGradientParams.color2.ChangeData(); |
269 | aCorners[1] = myGradientParams.color1.ChangeData(); |
270 | aCorners[2] = myGradientParams.color2.ChangeData(); |
271 | aCorners[3] = myGradientParams.color2.ChangeData(); |
0b0320e7 |
272 | break; |
273 | } |
274 | case Aspect_GFM_CORNER2: |
275 | { |
bc379358 |
276 | aCorners[0] = myGradientParams.color2.ChangeData(); |
277 | aCorners[1] = myGradientParams.color1.ChangeData(); |
278 | aCorners[2] = myGradientParams.color2.ChangeData(); |
279 | aCorners[3] = myGradientParams.color2.ChangeData(); |
0b0320e7 |
280 | break; |
281 | } |
282 | case Aspect_GFM_CORNER3: |
283 | { |
3bffef55 |
284 | aVertices[0] = OpenGl_Vec2(float(myViewWidth), float(myViewHeight)); |
285 | aVertices[1] = OpenGl_Vec2(0.0f, float(myViewHeight)); |
286 | aVertices[2] = OpenGl_Vec2(float(myViewWidth), 0.0f); |
287 | aVertices[3] = OpenGl_Vec2(0.0f, 0.0f); |
d5846489 |
288 | |
bc379358 |
289 | aCorners[0] = myGradientParams.color2.ChangeData(); |
290 | aCorners[1] = myGradientParams.color2.ChangeData(); |
291 | aCorners[2] = myGradientParams.color1.ChangeData(); |
292 | aCorners[3] = myGradientParams.color2.ChangeData(); |
0b0320e7 |
293 | break; |
294 | } |
295 | case Aspect_GFM_CORNER4: |
296 | { |
bc379358 |
297 | aCorners[0] = myGradientParams.color2.ChangeData(); |
298 | aCorners[1] = myGradientParams.color2.ChangeData(); |
299 | aCorners[2] = myGradientParams.color1.ChangeData(); |
300 | aCorners[3] = myGradientParams.color2.ChangeData(); |
0b0320e7 |
301 | break; |
302 | } |
303 | case Aspect_GFM_NONE: |
304 | { |
305 | break; |
306 | } |
307 | } |
308 | |
d5846489 |
309 | for (Standard_Integer anIt = 0; anIt < 4; ++anIt) |
0b0320e7 |
310 | { |
d5846489 |
311 | OpenGl_Vec2* aVertData = reinterpret_cast<OpenGl_Vec2* >(myAttribs->changeValue (anIt)); |
312 | *aVertData = aVertices[anIt]; |
0b0320e7 |
313 | |
d5846489 |
314 | OpenGl_Vec3* aColorData = reinterpret_cast<OpenGl_Vec3* >(myAttribs->changeValue (anIt) + myAttribs->AttributeOffset (1)); |
ba00aab7 |
315 | *aColorData = theCtx->Vec4FromQuantityColor (OpenGl_Vec4(aCorners[anIt][0], aCorners[anIt][1], aCorners[anIt][2], 1.0f)).rgb(); |
0b0320e7 |
316 | } |
317 | |
318 | return Standard_True; |
319 | } |
320 | |
321 | // ======================================================================= |
322 | // method : createTextureArray |
323 | // purpose : |
324 | // ======================================================================= |
3bffef55 |
325 | Standard_Boolean OpenGl_BackgroundArray::createTextureArray (const Handle(OpenGl_Workspace)& theWorkspace) const |
0b0320e7 |
326 | { |
327 | Graphic3d_Attribute aTextureAttribInfo[] = |
328 | { |
329 | { Graphic3d_TOA_POS, Graphic3d_TOD_VEC2 }, |
330 | { Graphic3d_TOA_UV, Graphic3d_TOD_VEC2 } |
331 | }; |
332 | |
ba00aab7 |
333 | if (myAttribs.IsNull()) |
334 | { |
335 | Handle(NCollection_AlignedAllocator) anAlloc = new NCollection_AlignedAllocator (16); |
336 | myAttribs = new Graphic3d_Buffer (anAlloc); |
337 | } |
0b0320e7 |
338 | if (!myAttribs->Init (4, aTextureAttribInfo, 2)) |
339 | { |
340 | return Standard_False; |
341 | } |
342 | |
343 | GLfloat aTexRangeX = 1.0f; // texture <s> coordinate |
344 | GLfloat aTexRangeY = 1.0f; // texture <t> coordinate |
345 | |
346 | // Set up for stretching or tiling |
3bffef55 |
347 | GLfloat anOffsetX = 0.5f * (float )myViewWidth; |
348 | GLfloat anOffsetY = 0.5f * (float )myViewHeight; |
0b0320e7 |
349 | |
350 | // Setting this coefficient to -1.0f allows to tile textures relatively to the top-left corner of the view |
351 | // (value 1.0f corresponds to the initial behavior - tiling from the bottom-left corner) |
352 | GLfloat aCoef = -1.0f; |
353 | |
354 | // Get texture parameters |
355 | const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext(); |
bf5f0ca2 |
356 | const OpenGl_Aspects* anAspectFace = theWorkspace->Aspects(); |
cc8cbabe |
357 | GLfloat aTextureWidth = (GLfloat )anAspectFace->TextureSet (aCtx)->First()->SizeX(); |
358 | GLfloat aTextureHeight = (GLfloat )anAspectFace->TextureSet (aCtx)->First()->SizeY(); |
0b0320e7 |
359 | |
360 | if (myFillMethod == Aspect_FM_CENTERED) |
361 | { |
3bffef55 |
362 | anOffsetX = 0.5f * aTextureWidth; |
363 | anOffsetY = 0.5f * aTextureHeight; |
0b0320e7 |
364 | } |
365 | else if (myFillMethod == Aspect_FM_TILED) |
366 | { |
367 | aTexRangeX = (GLfloat )myViewWidth / aTextureWidth; |
368 | aTexRangeY = (GLfloat )myViewHeight / aTextureHeight; |
369 | } |
370 | |
371 | // NOTE: texture is mapped using GL_REPEAT wrapping mode so integer part |
372 | // is simply ignored, and negative multiplier is here for convenience only |
373 | // and does not result e.g. in texture mirroring |
374 | |
0b0320e7 |
375 | |
d5846489 |
376 | OpenGl_Vec2* aData = reinterpret_cast<OpenGl_Vec2* >(myAttribs->changeValue (0)); |
0b0320e7 |
377 | aData[0] = OpenGl_Vec2 (anOffsetX, -aCoef * anOffsetY); |
378 | aData[1] = OpenGl_Vec2 (aTexRangeX, 0.0f); |
379 | |
d5846489 |
380 | aData = reinterpret_cast<OpenGl_Vec2* >(myAttribs->changeValue (1)); |
0b0320e7 |
381 | aData[0] = OpenGl_Vec2 (anOffsetX, aCoef * anOffsetY); |
382 | aData[1] = OpenGl_Vec2 (aTexRangeX, aCoef * aTexRangeY); |
383 | |
d5846489 |
384 | aData = reinterpret_cast<OpenGl_Vec2* >(myAttribs->changeValue (2)); |
385 | aData[0] = OpenGl_Vec2 (-anOffsetX, -aCoef * anOffsetY); |
386 | aData[1] = OpenGl_Vec2 (0.0f, 0.0f); |
387 | |
0b0320e7 |
388 | aData = reinterpret_cast<OpenGl_Vec2* >(myAttribs->changeValue (3)); |
389 | aData[0] = OpenGl_Vec2 (-anOffsetX, aCoef * anOffsetY); |
390 | aData[1] = OpenGl_Vec2 (0.0f, aCoef * aTexRangeY); |
391 | |
392 | return Standard_True; |
393 | } |
3bffef55 |
394 | |
395 | // ======================================================================= |
077a220c |
396 | // method : createCubeMapArray |
397 | // purpose : |
398 | // ======================================================================= |
399 | Standard_Boolean OpenGl_BackgroundArray::createCubeMapArray() const |
400 | { |
cdc54fb0 |
401 | const Graphic3d_Attribute aCubeMapAttribInfo[] = |
077a220c |
402 | { |
cdc54fb0 |
403 | { Graphic3d_TOA_POS, Graphic3d_TOD_VEC3 } |
077a220c |
404 | }; |
405 | |
ba00aab7 |
406 | if (myAttribs.IsNull()) |
407 | { |
408 | Handle(NCollection_AlignedAllocator) anAlloc = new NCollection_AlignedAllocator (16); |
409 | myAttribs = new Graphic3d_Buffer (anAlloc); |
cdc54fb0 |
410 | myIndices = new Graphic3d_IndexBuffer (anAlloc); |
ba00aab7 |
411 | } |
cdc54fb0 |
412 | if (!myAttribs->Init (8, aCubeMapAttribInfo, 1) |
413 | || !myIndices->Init<unsigned short> (14)) |
077a220c |
414 | { |
415 | return Standard_False; |
416 | } |
417 | |
077a220c |
418 | { |
cdc54fb0 |
419 | OpenGl_Vec3* aData = reinterpret_cast<OpenGl_Vec3*>(myAttribs->changeValue(0)); |
420 | aData[0].SetValues (-1.0, -1.0, 1.0); |
421 | aData[1].SetValues ( 1.0, -1.0, 1.0); |
422 | aData[2].SetValues (-1.0, 1.0, 1.0); |
423 | aData[3].SetValues ( 1.0, 1.0, 1.0); |
424 | aData[4].SetValues (-1.0, -1.0, -1.0); |
425 | aData[5].SetValues ( 1.0, -1.0, -1.0); |
426 | aData[6].SetValues (-1.0, 1.0, -1.0); |
427 | aData[7].SetValues ( 1.0, 1.0, -1.0); |
428 | } |
429 | { |
430 | const unsigned short THE_BOX_TRISTRIP[14] = { 0, 1, 2, 3, 7, 1, 5, 4, 7, 6, 2, 4, 0, 1 }; |
431 | for (unsigned int aVertIter = 0; aVertIter < 14; ++aVertIter) |
432 | { |
433 | myIndices->SetIndex (aVertIter, THE_BOX_TRISTRIP[aVertIter]); |
434 | } |
077a220c |
435 | } |
436 | |
437 | return Standard_True; |
438 | } |
439 | |
440 | // ======================================================================= |
441 | // method : Render |
3bffef55 |
442 | // purpose : |
443 | // ======================================================================= |
cdc54fb0 |
444 | void OpenGl_BackgroundArray::Render (const Handle(OpenGl_Workspace)& theWorkspace, |
445 | Graphic3d_Camera::Projection theProjection) const |
3bffef55 |
446 | { |
447 | const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext(); |
448 | Standard_Integer aViewSizeX = aCtx->Viewport()[2]; |
449 | Standard_Integer aViewSizeY = aCtx->Viewport()[3]; |
f051908e |
450 | Graphic3d_Vec2i aTileOffset, aTileSize; |
451 | |
3bffef55 |
452 | if (theWorkspace->View()->Camera()->Tile().IsValid()) |
453 | { |
454 | aViewSizeX = theWorkspace->View()->Camera()->Tile().TotalSize.x(); |
455 | aViewSizeY = theWorkspace->View()->Camera()->Tile().TotalSize.y(); |
f051908e |
456 | |
457 | aTileOffset = theWorkspace->View()->Camera()->Tile().OffsetLowerLeft(); |
458 | aTileSize = theWorkspace->View()->Camera()->Tile().TileSize; |
3bffef55 |
459 | } |
460 | if (myToUpdate |
461 | || myViewWidth != aViewSizeX |
ba00aab7 |
462 | || myViewHeight != aViewSizeY |
463 | || myAttribs.IsNull() |
464 | || myVboAttribs.IsNull()) |
3bffef55 |
465 | { |
466 | myViewWidth = aViewSizeX; |
467 | myViewHeight = aViewSizeY; |
468 | init (theWorkspace); |
469 | } |
470 | |
471 | OpenGl_Mat4 aProjection = aCtx->ProjectionState.Current(); |
472 | OpenGl_Mat4 aWorldView = aCtx->WorldViewState.Current(); |
077a220c |
473 | |
cdc54fb0 |
474 | if (myType == Graphic3d_TOB_CUBEMAP) |
475 | { |
476 | Graphic3d_Camera aCamera (theWorkspace->View()->Camera()); |
477 | aCamera.SetZRange (0.01, 1.0); // is needed to avoid perspective camera exception |
478 | |
479 | // cancel translation |
480 | aCamera.MoveEyeTo (gp_Pnt (0.0, 0.0, 0.0)); |
481 | |
482 | // Handle projection matrix: |
483 | // - Cancel any head-to-eye translation for HMD display; |
484 | // - Ignore stereoscopic projection in case of non-HMD 3D display |
485 | // (ideally, we would need a stereoscopic cubemap image; adding a parallax makes no sense); |
486 | // - Force perspective projection when orthographic camera is active |
487 | // (orthographic projection makes no sense for cubemap). |
488 | const bool isCustomProj = aCamera.IsCustomStereoFrustum() |
489 | || aCamera.IsCustomStereoProjection(); |
490 | aCamera.SetProjectionType (theProjection == Graphic3d_Camera::Projection_Orthographic || !isCustomProj |
491 | ? Graphic3d_Camera::Projection_Perspective |
492 | : theProjection); |
493 | |
494 | aProjection = aCamera.ProjectionMatrixF(); |
495 | aWorldView = aCamera.OrientationMatrixF(); |
496 | if (isCustomProj) |
497 | { |
498 | // get projection matrix without pre-multiplied stereoscopic head-to-eye translation |
499 | if (theProjection == Graphic3d_Camera::Projection_MonoLeftEye) |
500 | { |
501 | Graphic3d_Mat4 aMatProjL, aMatHeadToEyeL, aMatProjR, aMatHeadToEyeR; |
502 | aCamera.StereoProjectionF (aMatProjL, aMatHeadToEyeL, aMatProjR, aMatHeadToEyeR); |
503 | aProjection = aMatProjL; |
504 | } |
505 | else if (theProjection == Graphic3d_Camera::Projection_MonoRightEye) |
506 | { |
507 | Graphic3d_Mat4 aMatProjL, aMatHeadToEyeL, aMatProjR, aMatHeadToEyeR; |
508 | aCamera.StereoProjectionF (aMatProjL, aMatHeadToEyeL, aMatProjR, aMatHeadToEyeR); |
509 | aProjection = aMatProjR; |
510 | } |
511 | } |
512 | } |
513 | else |
077a220c |
514 | { |
f051908e |
515 | aProjection.InitIdentity(); |
516 | aWorldView.InitIdentity(); |
517 | if (theWorkspace->View()->Camera()->Tile().IsValid()) |
518 | { |
519 | aWorldView.SetDiagonal (OpenGl_Vec4 (2.0f / aTileSize.x(), 2.0f / aTileSize.y(), 1.0f, 1.0f)); |
520 | if (myType == Graphic3d_TOB_GRADIENT) |
521 | { |
522 | aWorldView.SetColumn (3, OpenGl_Vec4 (-1.0f - 2.0f * aTileOffset.x() / aTileSize.x(), |
523 | -1.0f - 2.0f * aTileOffset.y() / aTileSize.y(), 0.0f, 1.0f)); |
524 | } |
525 | else |
526 | { |
527 | aWorldView.SetColumn (3, OpenGl_Vec4 (-1.0f + (float) aViewSizeX / aTileSize.x() - 2.0f * aTileOffset.x() / aTileSize.x(), |
528 | -1.0f + (float) aViewSizeY / aTileSize.y() - 2.0f * aTileOffset.y() / aTileSize.y(), 0.0f, 1.0f)); |
529 | } |
530 | } |
531 | else |
532 | { |
533 | aWorldView.SetDiagonal (OpenGl_Vec4 (2.0f / myViewWidth, 2.0f / myViewHeight, 1.0f, 1.0f)); |
534 | if (myType == Graphic3d_TOB_GRADIENT) |
535 | { |
536 | aWorldView.SetColumn (3, OpenGl_Vec4 (-1.0f, -1.0f, 0.0f, 1.0f)); |
537 | } |
538 | } |
077a220c |
539 | } |
3bffef55 |
540 | |
541 | aCtx->ProjectionState.Push(); |
542 | aCtx->WorldViewState.Push(); |
543 | aCtx->ProjectionState.SetCurrent (aProjection); |
544 | aCtx->WorldViewState.SetCurrent (aWorldView); |
545 | aCtx->ApplyProjectionMatrix(); |
546 | aCtx->ApplyModelViewMatrix(); |
547 | |
548 | OpenGl_PrimitiveArray::Render (theWorkspace); |
549 | |
550 | aCtx->ProjectionState.Pop(); |
551 | aCtx->WorldViewState.Pop(); |
552 | aCtx->ApplyProjectionMatrix(); |
553 | } |