0030700: Visualization, TKOpenGl - support PBR Metallic-Roughness shading model
[occt.git] / src / Graphic3d / Graphic3d_AttribBuffer.cxx
1 // Copyright (c) 2018 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13
14 #include <Graphic3d_AttribBuffer.hxx>
15
16 IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_AttribBuffer, Graphic3d_Buffer)
17
18 // =======================================================================
19 // function : Graphic3d_AttribBuffer
20 // purpose  :
21 // =======================================================================
22 Graphic3d_AttribBuffer::Graphic3d_AttribBuffer(const Handle(NCollection_BaseAllocator)& theAlloc)
23 : Graphic3d_Buffer (theAlloc),
24   myIsInterleaved (Standard_True),
25   myIsMutable (Standard_False)
26 {
27 }
28
29 // =======================================================================
30 // function : Init
31 // purpose  :
32 // =======================================================================
33 bool Graphic3d_AttribBuffer::Init (const Standard_Integer     theNbElems,
34                                    const Graphic3d_Attribute* theAttribs,
35                                    const Standard_Integer     theNbAttribs)
36 {
37   if (!Graphic3d_Buffer::Init (theNbElems, theAttribs, theNbAttribs))
38   {
39     return false;
40   }
41
42   if (mySize > (Standard_Size )IntegerLast()
43    && myIsMutable)
44   {
45     throw Standard_OutOfRange ("Graphic3d_AttribBuffer::Init(), Mutable flag cannot be used for buffer exceeding 32-bit address space");
46   }
47   return true;
48 }
49
50 // =======================================================================
51 // function : SetMutable
52 // purpose  :
53 // =======================================================================
54 void Graphic3d_AttribBuffer::SetMutable (Standard_Boolean theMutable)
55 {
56   if (mySize > (Standard_Size )IntegerLast()
57    && theMutable)
58   {
59     throw Standard_OutOfRange ("Graphic3d_AttribBuffer::SetMutable(), Mutable flag cannot be used for buffer exceeding 32-bit address space");
60   }
61   myIsMutable = theMutable;
62 }
63
64 // =======================================================================
65 // function : Invalidate
66 // purpose  :
67 // =======================================================================
68 void Graphic3d_AttribBuffer::SetInterleaved (Standard_Boolean theIsInterleaved)
69 {
70   if (NbMaxElements() != 0)
71   {
72     throw Standard_ProgramError ("Graphic3d_AttribBuffer::SetInterleaved() should not be called for allocated buffer");
73   }
74   myIsInterleaved = theIsInterleaved;
75 }
76
77 // =======================================================================
78 // function : invalidate
79 // purpose  :
80 // =======================================================================
81 void Graphic3d_AttribBuffer::invalidate (const Graphic3d_BufferRange& theRange)
82 {
83   if (mySize > (Standard_Size )IntegerLast())
84   {
85     throw Standard_OutOfRange ("Graphic3d_Buffer::Invalidate() cannot be used for buffer exceeding 32-bit address space");
86   }
87
88   myInvalidatedRange.Unite (theRange);
89 }
90
91 // =======================================================================
92 // function : Invalidate
93 // purpose  :
94 // =======================================================================
95 void Graphic3d_AttribBuffer::Invalidate()
96 {
97   if (mySize > (Standard_Size )IntegerLast())
98   {
99     throw Standard_OutOfRange ("Graphic3d_AttribBuffer::Invalidate() cannot be used for buffer exceeding 32-bit address space");
100   }
101
102   invalidate (Graphic3d_BufferRange (0, (Standard_Integer )mySize));
103 }
104
105 // =======================================================================
106 // function : Invalidate
107 // purpose  :
108 // =======================================================================
109 void Graphic3d_AttribBuffer::Invalidate (Standard_Integer theAttributeIndex)
110 {
111   Standard_OutOfRange_Raise_if (theAttributeIndex < 0
112                              || theAttributeIndex >= NbAttributes, "Graphic3d_AttribBuffer::Invalidate()");
113   if (myIsInterleaved)
114   {
115     Invalidate();
116     return;
117   }
118
119   Graphic3d_BufferRange aRange;
120   const Standard_Integer aNbMaxVerts = NbMaxElements();
121   for (Standard_Integer anAttribIter = 0; anAttribIter < NbAttributes; ++anAttribIter)
122   {
123     const Graphic3d_Attribute& anAttrib = Attribute (anAttribIter);
124     const Standard_Integer anAttribStride = Graphic3d_Attribute::Stride (anAttrib.DataType);
125     if (anAttribIter == theAttributeIndex)
126     {
127       aRange.Length = anAttribStride * aNbMaxVerts;
128       invalidate (aRange);
129       return;
130     }
131
132     aRange.Start += anAttribStride * aNbMaxVerts;
133   }
134 }
135
136 // =======================================================================
137 // function : Invalidate
138 // purpose  :
139 // =======================================================================
140 void Graphic3d_AttribBuffer::Invalidate (Standard_Integer theAttributeIndex,
141                                          Standard_Integer theVertexLower,
142                                          Standard_Integer theVertexUpper)
143 {
144   Standard_OutOfRange_Raise_if (theAttributeIndex < 0
145                              || theAttributeIndex >= NbAttributes
146                              || theVertexLower < 0
147                              || theVertexLower > theVertexUpper
148                              || theVertexUpper >= NbMaxElements(), "Graphic3d_AttribBuffer::Invalidate()");
149   if (myIsInterleaved)
150   {
151     Invalidate (theVertexLower, theVertexUpper);
152     return;
153   }
154
155   Graphic3d_BufferRange aRange;
156   const Standard_Integer aNbMaxVerts = NbMaxElements();
157   for (Standard_Integer anAttribIter = 0; anAttribIter < NbAttributes; ++anAttribIter)
158   {
159     const Graphic3d_Attribute& anAttrib = Attribute (anAttribIter);
160     const Standard_Integer anAttribStride = Graphic3d_Attribute::Stride (anAttrib.DataType);
161     if (anAttribIter == theAttributeIndex)
162     {
163       aRange.Start += anAttribStride * theVertexLower;
164       aRange.Length = anAttribStride * (theVertexUpper - theVertexLower + 1);
165       invalidate (aRange);
166       return;
167     }
168
169     aRange.Start += anAttribStride * aNbMaxVerts;
170   }
171 }
172
173 // =======================================================================
174 // function : Invalidate
175 // purpose  :
176 // =======================================================================
177 void Graphic3d_AttribBuffer::Invalidate (Standard_Integer theVertexLower,
178                                          Standard_Integer theVertexUpper)
179 {
180   Standard_OutOfRange_Raise_if (theVertexLower < 0
181                              || theVertexLower > theVertexUpper
182                              || theVertexUpper >= NbMaxElements(), "Graphic3d_AttribBuffer::Invalidate()");
183   if (myIsInterleaved)
184   {
185     invalidate (Graphic3d_BufferRange (Stride * theVertexLower,
186                                        Stride * (theVertexUpper - theVertexLower + 1)));
187     return;
188   }
189
190   for (Standard_Integer anAttribIter = 0; anAttribIter < NbAttributes; ++anAttribIter)
191   {
192     Invalidate (anAttribIter, theVertexLower, theVertexUpper);
193   }
194 }