0026122: Visualization, TKOpenGl - clipping and capping is broken when ffp is disable...
[occt.git] / src / OpenGl / OpenGl_CappingPlaneResource.cxx
CommitLineData
4269bd1b 1// Created on: 2013-08-15
2// Created by: Anton POLETAEV
d5f74e42 3// Copyright (c) 2013-2014 OPEN CASCADE SAS
4269bd1b 4//
973c2be1 5// This file is part of Open CASCADE Technology software library.
4269bd1b 6//
d5f74e42 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
973c2be1 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.
4269bd1b 12//
973c2be1 13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
4269bd1b 15
e1c659da 16#include <NCollection_AlignedAllocator.hxx>
4269bd1b 17#include <OpenGl_CappingPlaneResource.hxx>
18#include <OpenGl_Context.hxx>
19#include <OpenGl_Vec.hxx>
20#include <Precision.hxx>
21
e1c659da 22namespace
23{
24 //! 12 plane vertices, interleaved:
25 //! - 4 floats, position
26 //! - 4 floats, normal
27 //! - 4 floats, UV texture coordinates
28 static const GLfloat THE_CAPPING_PLN_VERTS[12 * (4 + 4 + 4)] =
29 {
30 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
31 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
44ef962b 32 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,-1.0f, 0.0f, 0.0f,
e1c659da 33
34 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
44ef962b 35 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,-1.0f, 0.0f, 0.0f,
e1c659da 36 -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f,
37
38 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
39 -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f,
44ef962b 40 0.0f, 0.0f,-1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
e1c659da 41
42 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
44ef962b 43 0.0f, 0.0f,-1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
e1c659da 44 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f
45 };
f8ae3605 46
47 static const OpenGl_Matrix OpenGl_IdentityMatrix =
48 {
49 // mat[4][4]
50 { { 1.0f, 0.0f, 0.0f, 0.0f },
51 { 0.0f, 1.0f, 0.0f, 0.0f },
52 { 0.0f, 0.0f, 1.0f, 0.0f },
53 { 0.0f, 0.0f, 0.0f, 1.0f } }
54 };
55
e1c659da 56}
57
4269bd1b 58
59// =======================================================================
60// function : OpenGl_CappingPlaneResource
61// purpose :
62// =======================================================================
63OpenGl_CappingPlaneResource::OpenGl_CappingPlaneResource (const Handle(Graphic3d_ClipPlane)& thePlane)
e1c659da 64: myPrimitives (NULL),
65 myOrientation (OpenGl_IdentityMatrix),
8d3865d8 66 myAspect (NULL),
67 myPlaneRoot (thePlane),
68 myEquationMod ((unsigned int )-1),
69 myAspectMod ((unsigned int )-1)
e1c659da 70{
71 // Fill primitive array
72 Handle(NCollection_AlignedAllocator) anAlloc = new NCollection_AlignedAllocator (16);
73 Handle(Graphic3d_Buffer) anAttribs = new Graphic3d_Buffer (anAlloc);
74 Graphic3d_Attribute anAttribInfo[] =
75 {
76 { Graphic3d_TOA_POS, Graphic3d_TOD_VEC4 },
77 { Graphic3d_TOA_NORM, Graphic3d_TOD_VEC4 },
78 { Graphic3d_TOA_UV, Graphic3d_TOD_VEC4 }
79 };
80 if (anAttribs->Init (12, anAttribInfo, 3))
81 {
82 memcpy (anAttribs->ChangeData(), THE_CAPPING_PLN_VERTS, sizeof(THE_CAPPING_PLN_VERTS));
83 myPrimitives.InitBuffers (NULL, Graphic3d_TOPA_TRIANGLES, NULL, anAttribs, NULL);
84 }
85}
4269bd1b 86
87// =======================================================================
88// function : OpenGl_CappingPlaneResource
89// purpose :
90// =======================================================================
91OpenGl_CappingPlaneResource::~OpenGl_CappingPlaneResource()
92{
93 Release (NULL);
94}
95
96// =======================================================================
97// function : Update
98// purpose :
99// =======================================================================
100void OpenGl_CappingPlaneResource::Update (const Handle(OpenGl_Context)& theContext)
101{
102 UpdateTransform();
103 UpdateAspect (theContext);
104}
105
106// =======================================================================
107// function : Release
108// purpose :
109// =======================================================================
10b9c7df 110void OpenGl_CappingPlaneResource::Release (OpenGl_Context* theContext)
4269bd1b 111{
112 OpenGl_Element::Destroy (theContext, myAspect);
e1c659da 113 myPrimitives.Release (theContext);
8d3865d8 114 myEquationMod = (unsigned int )-1;
115 myAspectMod = (unsigned int )-1;
4269bd1b 116}
117
118// =======================================================================
119// function : UpdateAspect
120// purpose :
121// =======================================================================
122void OpenGl_CappingPlaneResource::UpdateAspect (const Handle(OpenGl_Context)& theContext)
123{
124 Handle(Graphic3d_AspectFillArea3d) aCappingAsp = myPlaneRoot->CappingAspect();
125 if (myAspect != NULL && !aCappingAsp.IsNull())
126 {
127 if (myAspectMod == myPlaneRoot->MCountAspect())
128 return; // noting to update
129
fd4a6963 130 myAspect->SetAspect (aCappingAsp);
4269bd1b 131 myAspectMod = myPlaneRoot->MCountAspect();
132 return;
133 }
134
135 // no more used
136 if (myAspect != NULL && aCappingAsp.IsNull())
137 {
10b9c7df 138 OpenGl_Element::Destroy (theContext.operator->(), myAspect);
4269bd1b 139 myAspectMod = myPlaneRoot->MCountAspect();
140 return;
141 }
142
143 // first created
144 if (myAspect == NULL && !aCappingAsp.IsNull())
145 {
146 myAspect = new OpenGl_AspectFace();
fd4a6963 147 myAspect->SetAspect (aCappingAsp);
4269bd1b 148 myAspectMod = myPlaneRoot->MCountAspect();
149 }
150}
151
152// =======================================================================
153// function : UpdateTransform
154// purpose :
155// =======================================================================
156void OpenGl_CappingPlaneResource::UpdateTransform()
157{
158 const Graphic3d_ClipPlane::Equation& anEquation = myPlaneRoot->GetEquation();
159 if (myEquationMod == myPlaneRoot->MCountEquation())
160 {
161 return; // nothing to update
162 }
163
164 // re-evaluate infinite plane transformation matrix
165 Standard_ShortReal N[3] =
166 { (Standard_ShortReal)anEquation[0],
167 (Standard_ShortReal)anEquation[1],
168 (Standard_ShortReal)anEquation[2] };
169
170 Standard_ShortReal T[3] =
171 { (Standard_ShortReal)(anEquation[0] * -anEquation[3]),
172 (Standard_ShortReal)(anEquation[1] * -anEquation[3]),
173 (Standard_ShortReal)(anEquation[2] * -anEquation[3]) };
174
175 Standard_ShortReal L[3] = { 0.0f, 0.0f, 0.0f };
176 Standard_ShortReal F[3] = { 0.0f, 0.0f, 0.0f };
177
178 // project plane normal onto OX to find left vector
4269bd1b 179 Standard_ShortReal aProjLen =
180 sqrt ( (Standard_ShortReal)(anEquation[0] * anEquation[0])
181 + (Standard_ShortReal)(anEquation[2] * anEquation[2]));
79f4f036 182 if (aProjLen < ShortRealSmall())
4269bd1b 183 {
184 L[0] = 1.0f;
185 }
186 else
187 {
188 L[0] = N[2] / aProjLen;
189 L[2] = -N[0] / aProjLen;
190 }
191
192 // (-aLeft) x aNorm
193 F[0] = (-L[1])*N[2] - (-L[2])*N[1];
194 F[1] = (-L[2])*N[0] - (-L[0])*N[2];
195 F[2] = (-L[0])*N[1] - (-L[1])*N[0];
196
197 myOrientation.mat[0][0] = L[0];
198 myOrientation.mat[0][1] = L[1];
199 myOrientation.mat[0][2] = L[2];
200 myOrientation.mat[0][3] = 0.0f;
201
202 myOrientation.mat[1][0] = N[0];
203 myOrientation.mat[1][1] = N[1];
204 myOrientation.mat[1][2] = N[2];
205 myOrientation.mat[1][3] = 0.0f;
206
207 myOrientation.mat[2][0] = F[0];
208 myOrientation.mat[2][1] = F[1];
209 myOrientation.mat[2][2] = F[2];
210 myOrientation.mat[2][3] = 0.0f;
211
212 myOrientation.mat[3][0] = T[0];
213 myOrientation.mat[3][1] = T[1];
214 myOrientation.mat[3][2] = T[2];
215 myOrientation.mat[3][3] = 1.0f;
216
217 myEquationMod = myPlaneRoot->MCountEquation();
218}