All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
glMesh.h
Go to the documentation of this file.
1 //
2 // Copyright 2013 Pixar
3 //
4 // Licensed under the Apache License, Version 2.0 (the "Apache License")
5 // with the following modification; you may not use this file except in
6 // compliance with the Apache License and the following modification to it:
7 // Section 6. Trademarks. is deleted and replaced with:
8 //
9 // 6. Trademarks. This License does not grant permission to use the trade
10 // names, trademarks, service marks, or product names of the Licensor
11 // and its affiliates, except as required to comply with Section 4(c) of
12 // the License and to reproduce the content of the NOTICE file.
13 //
14 // You may obtain a copy of the Apache License at
15 //
16 // http://www.apache.org/licenses/LICENSE-2.0
17 //
18 // Unless required by applicable law or agreed to in writing, software
19 // distributed under the Apache License with the above modification is
20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21 // KIND, either express or implied. See the Apache License for the specific
22 // language governing permissions and limitations under the Apache License.
23 //
24 
25 #ifndef OSD_GL_MESH_H
26 #define OSD_GL_MESH_H
27 
28 #include "../version.h"
29 
30 #include "../osd/mesh.h"
31 #include "../osd/glDrawContext.h"
32 #include "../osd/vertexDescriptor.h"
33 
34 #ifdef OPENSUBDIV_HAS_OPENCL
35 # include "../osd/clComputeController.h"
36 # include "../osd/opencl.h"
37 #endif
38 
39 namespace OpenSubdiv {
40 namespace OPENSUBDIV_VERSION {
41 
42 namespace Osd {
43 
45 
46 template <class VERTEX_BUFFER, class COMPUTE_CONTROLLER>
47 class Mesh<VERTEX_BUFFER, COMPUTE_CONTROLLER, GLDrawContext> : public GLMeshInterface {
48 public:
49  typedef VERTEX_BUFFER VertexBuffer;
50  typedef COMPUTE_CONTROLLER ComputeController;
51  typedef typename ComputeController::ComputeContext ComputeContext;
54 
55  Mesh(ComputeController * computeController,
56  Far::TopologyRefiner * refiner,
57  int numVertexElements,
58  int numVaryingElements,
59  int level,
60  MeshBitset bits) :
61 
62  _refiner(refiner),
63  _patchTables(0),
64  _vertexBuffer(0),
65  _varyingBuffer(0),
66  _computeContext(0),
67  _computeController(computeController),
68  _drawContext(0)
69  {
70 
71  GLMeshInterface::refineMesh(*_refiner, level, bits.test(MeshAdaptive));
72 
73  int numElements =
74  initializeVertexBuffers(numVertexElements, numVaryingElements, bits);
75 
76  initializeComputeContext(numVertexElements, numVaryingElements);
77 
78  initializeDrawContext(numElements, bits);
79  }
80 
81  Mesh(ComputeController * computeController,
82  Far::TopologyRefiner * refiner,
83  VertexBuffer * vertexBuffer,
84  VertexBuffer * varyingBuffer,
85  ComputeContext * computeContext,
86  DrawContext * drawContext) :
87 
88  _refiner(refiner),
89  _vertexBuffer(vertexBuffer),
90  _varyingBuffer(varyingBuffer),
91  _computeContext(computeContext),
92  _computeController(computeController),
93  _drawContext(drawContext)
94  {
95  _drawContext->UpdateVertexTexture(_vertexBuffer);
96  }
97 
98  virtual ~Mesh() {
99  delete _refiner;
100  delete _patchTables;
101  delete _vertexBuffer;
102  delete _varyingBuffer;
103  delete _computeContext;
104  delete _drawContext;
105  }
106 
107  virtual int GetNumVertices() const {
108  assert(_refiner);
109  return GLMeshInterface::getNumVertices(*_refiner);
110  }
111 
112 
113  virtual void UpdateVertexBuffer(float const *vertexData, int startVertex, int numVerts) {
114  _vertexBuffer->UpdateData(vertexData, startVertex, numVerts);
115  }
116 
117  virtual void UpdateVaryingBuffer(float const *varyingData, int startVertex, int numVerts) {
118  _varyingBuffer->UpdateData(varyingData, startVertex, numVerts);
119  }
120 
121  virtual void Refine() {
122  _computeController->Compute(_computeContext, _kernelBatches, _vertexBuffer, _varyingBuffer);
123  }
124 
125  virtual void Refine(VertexBufferDescriptor const * vertexDesc,
126  VertexBufferDescriptor const * varyingDesc,
127  bool interleaved) {
128  _computeController->Compute(_computeContext, _kernelBatches,
129  _vertexBuffer, (interleaved ? _vertexBuffer : _varyingBuffer),
130  vertexDesc, varyingDesc);
131  }
132 
133  virtual void Synchronize() {
134  _computeController->Synchronize();
135  }
136 
138  return _vertexBuffer->BindVBO();
139  }
140 
142  return _varyingBuffer->BindVBO();
143  }
144 
146  return _drawContext;
147  }
148 
150  return _vertexBuffer;
151  }
152 
154  return _varyingBuffer;
155  }
156 
157  virtual Far::TopologyRefiner const * GetTopologyRefiner() const {
158  return _refiner;
159  }
160 
161  virtual void SetFVarDataChannel(int fvarWidth, std::vector<float> const & fvarData) {
162  if (_patchTables and _drawContext and fvarWidth and (not fvarData.empty())) {
163  _drawContext->SetFVarDataTexture(*_patchTables, fvarWidth, fvarData);
164  }
165  }
166 
167 private:
168 
169  void initializeComputeContext(int numVertexElements,
170  int numVaryingElements ) {
171 
172  assert(_refiner);
173 
175  options.generateOffsets=true;
176  options.generateAllLevels=_refiner->IsUniform() ? false : true;
177 
178  Far::StencilTables const * vertexStencils=0, * varyingStencils=0;
179 
180  if (numVertexElements>0) {
181 
182  vertexStencils = Far::StencilTablesFactory::Create(*_refiner, options);
183 
184  _kernelBatches.push_back(Far::StencilTablesFactory::Create(*vertexStencils));
185  }
186 
187  if (numVaryingElements>0) {
188 
190 
191  varyingStencils = Far::StencilTablesFactory::Create(*_refiner, options);
192  }
193 
194  _computeContext = ComputeContext::Create(vertexStencils, varyingStencils);
195 
196  delete vertexStencils;
197  delete varyingStencils;
198  }
199 
200  void initializeDrawContext(int numElements, MeshBitset bits) {
201 
202  assert(_refiner and _vertexBuffer);
203 
204  Far::PatchTablesFactory::Options options;
205  options.generateFVarTables = bits.test(MeshFVarData);
206 
207  _patchTables = Far::PatchTablesFactory::Create(*_refiner, options);
208 
209  _drawContext = DrawContext::Create(_patchTables, numElements);
210 
211  _drawContext->UpdateVertexTexture(_vertexBuffer);
212  }
213 
214  int initializeVertexBuffers(int numVertexElements,
215  int numVaryingElements, MeshBitset bits) {
216 
217  int numVertices = GLMeshInterface::getNumVertices(*_refiner);
218 
219  int numElements = numVertexElements +
220  (bits.test(MeshInterleaveVarying) ? numVaryingElements : 0);
221 
222  if (numVertexElements) {
223 
224  _vertexBuffer = VertexBuffer::Create(numElements, numVertices);
225  }
226 
227  if (numVaryingElements>0 and (not bits.test(MeshInterleaveVarying))) {
228  _varyingBuffer = VertexBuffer::Create(numVaryingElements, numVertices);
229  }
230  return numElements;
231  }
232 
233  Far::TopologyRefiner * _refiner;
234  Far::PatchTables * _patchTables;
235  Far::KernelBatchVector _kernelBatches;
236 
237  VertexBuffer *_vertexBuffer;
238  VertexBuffer *_varyingBuffer;
239 
240  ComputeContext *_computeContext;
241  ComputeController *_computeController;
242 
243  DrawContext *_drawContext;
244 };
245 
246 #ifdef OPENSUBDIV_HAS_OPENCL
247 
248 template <class VERTEX_BUFFER>
249 class Mesh<VERTEX_BUFFER, CLComputeController, GLDrawContext> : public GLMeshInterface {
250 public:
251  typedef VERTEX_BUFFER VertexBuffer;
252  typedef CLComputeController ComputeController;
253  typedef typename ComputeController::ComputeContext ComputeContext;
254  typedef GLDrawContext DrawContext;
255  typedef typename DrawContext::VertexBufferBinding VertexBufferBinding;
256 
257  Mesh(ComputeController * computeController,
258  Far::TopologyRefiner * refiner,
259  int numVertexElements,
260  int numVaryingElements,
261  int level,
262  MeshBitset bits,
263  cl_context clContext,
264  cl_command_queue clQueue) :
265 
266  _refiner(refiner),
267  _vertexBuffer(0),
268  _varyingBuffer(0),
269  _computeContext(0),
270  _computeController(computeController),
271  _drawContext(0),
272  _clContext(clContext),
273  _clQueue(clQueue)
274  {
275  assert(_refiner);
276 
277  GLMeshInterface::refineMesh(*_refiner, level, bits.test(MeshAdaptive));
278 
279  int numElements =
280  initializeVertexBuffers(numVertexElements, numVaryingElements, bits);
281 
282  initializeComputeContext(numVertexElements, numVaryingElements);
283 
284  initializeDrawContext(numElements, bits);
285  }
286 
287  Mesh(ComputeController * computeController,
288  Far::TopologyRefiner * refiner,
289  VertexBuffer * vertexBuffer,
290  VertexBuffer * varyingBuffer,
291  ComputeContext * computeContext,
292  DrawContext * drawContext,
293  cl_context clContext,
294  cl_command_queue clQueue) :
295 
296  _refiner(refiner),
297  _vertexBuffer(vertexBuffer),
298  _varyingBuffer(varyingBuffer),
299  _computeContext(computeContext),
300  _computeController(computeController),
301  _drawContext(drawContext),
302  _clContext(clContext),
303  _clQueue(clQueue)
304  {
305  _drawContext->UpdateVertexTexture(_vertexBuffer);
306  }
307 
308  virtual ~Mesh() {
309  delete _refiner;
310  delete _patchTables;
311  delete _vertexBuffer;
312  delete _varyingBuffer;
313  delete _computeContext;
314  delete _drawContext;
315  }
316 
317  virtual int GetNumVertices() const { return _refiner->GetNumVerticesTotal(); }
318 
319  virtual void UpdateVertexBuffer(float const *vertexData, int startVertex, int numVerts) {
320  _vertexBuffer->UpdateData(vertexData, startVertex, numVerts, _clQueue);
321  }
322 
323  virtual void UpdateVaryingBuffer(float const *varyingData, int startVertex, int numVerts) {
324  _varyingBuffer->UpdateData(varyingData, startVertex, numVerts, _clQueue);
325  }
326 
327  virtual void Refine() {
328  _computeController->Compute(_computeContext, _kernelBatches, _vertexBuffer, _varyingBuffer);
329  }
330 
331  virtual void Refine(VertexBufferDescriptor const *vertexDesc,
332  VertexBufferDescriptor const *varyingDesc,
333  bool interleaved) {
334  _computeController->Compute(_computeContext, _kernelBatches,
335  _vertexBuffer, (interleaved ? _vertexBuffer : _varyingBuffer),
336  vertexDesc, varyingDesc);
337  }
338 
339  virtual void Synchronize() {
340  _computeController->Synchronize();
341  }
342 
344  return _vertexBuffer->BindVBO();
345  }
346 
348  return _varyingBuffer->BindVBO();
349  }
350 
351  virtual DrawContext * GetDrawContext() {
352  return _drawContext;
353  }
354 
355  virtual VertexBuffer * GetVertexBuffer() {
356  return _vertexBuffer;
357  }
358 
359  virtual VertexBuffer * GetVaryingBuffer() {
360  return _varyingBuffer;
361  }
362 
363  virtual Far::TopologyRefiner const * GetTopologyRefiner() const {
364  return _refiner;
365  }
366 
367  virtual void SetFVarDataChannel(int fvarWidth, std::vector<float> const & fvarData) {
368  if (_patchTables and _drawContext and fvarWidth and (not fvarData.empty())) {
369  _drawContext->SetFVarDataTexture(*_patchTables, fvarWidth, fvarData);
370  }
371  }
372 
373 private:
374 
375  void initializeComputeContext(int numVertexElements,
376  int numVaryingElements ) {
377 
378  assert(_refiner);
379 
380  Far::StencilTablesFactory::Options options;
381  options.generateOffsets=true;
382  options.generateAllLevels=_refiner->IsUniform() ? false : true;
383 
384  Far::StencilTables const * vertexStencils=0, * varyingStencils=0;
385 
386  if (numVertexElements>0) {
387 
388  vertexStencils = Far::StencilTablesFactory::Create(*_refiner, options);
389 
390  _kernelBatches.push_back(Far::StencilTablesFactory::Create(*vertexStencils));
391  }
392 
393  if (numVaryingElements>0) {
394 
395  options.interpolationMode = Far::StencilTablesFactory::INTERPOLATE_VARYING;
396 
397  varyingStencils = Far::StencilTablesFactory::Create(*_refiner, options);
398  }
399 
400  _computeContext = ComputeContext::Create(_clContext, vertexStencils, varyingStencils);
401 
402  delete vertexStencils;
403  delete varyingStencils;
404  }
405 
406  void initializeDrawContext(int numElements, MeshBitset bits) {
407 
408  assert(_refiner and _vertexBuffer);
409 
410  Far::PatchTablesFactory::Options options;
411  options.generateFVarTables = bits.test(MeshFVarData);
412 
413  _patchTables = Far::PatchTablesFactory::Create(*_refiner);
414 
415  _drawContext = DrawContext::Create(_patchTables, numElements);
416 
417  _drawContext->UpdateVertexTexture(_vertexBuffer);
418  }
419 
420  int initializeVertexBuffers(int numVertexElements,
421  int numVaryingElements, MeshBitset bits) {
422 
423  int numVertices = GLMeshInterface::getNumVertices(*_refiner);
424 
425  int numElements = numVertexElements +
426  (bits.test(MeshInterleaveVarying) ? numVaryingElements : 0);
427 
428  if (numVertexElements) {
429 
430  _vertexBuffer = VertexBuffer::Create(numElements, numVertices, _clContext);
431  }
432 
433  if (numVaryingElements>0 and (not bits.test(MeshInterleaveVarying))) {
434  _varyingBuffer = VertexBuffer::Create(numVaryingElements, numVertices, _clContext);
435  }
436  return numElements;
437  }
438 
439  Far::TopologyRefiner * _refiner;
440  Far::PatchTables * _patchTables;
441  Far::KernelBatchVector _kernelBatches;
442 
443  VertexBuffer *_vertexBuffer;
444  VertexBuffer *_varyingBuffer;
445 
446  ComputeContext *_computeContext;
447  ComputeController *_computeController;
448 
449  DrawContext *_drawContext;
450 
451  cl_context _clContext;
452  cl_command_queue _clQueue;
453 };
454 #endif
455 
456 } // end namespace Osd
457 
458 } // end namespace OPENSUBDIV_VERSION
459 using namespace OPENSUBDIV_VERSION;
460 
461 } // end namespace OpenSubdiv
462 
463 #endif // OSD_GL_MESH_H
464 
virtual DrawContext * GetDrawContext()
Definition: mesh.h:203
COMPUTE_CONTROLLER ComputeController
Definition: mesh.h:117
int generateOffsets
populate optional &quot;_offsets&quot; field
static PatchTables * Create(TopologyRefiner const &refiner, Options options=Options())
Factory constructor for PatchTables.
static void refineMesh(Far::TopologyRefiner &refiner, int level, bool adaptive)
Definition: mesh.h:99
Mesh(ComputeController *computeController, Far::TopologyRefiner *refiner, VertexBuffer *vertexBuffer, VertexBuffer *varyingBuffer, ComputeContext *computeContext, DrawContext *drawContext)
Definition: glMesh.h:81
virtual void UpdateVaryingBuffer(float const *varyingData, int startVertex, int numVerts)
Definition: glMesh.h:117
virtual void UpdateVertexBuffer(float const *vertexData, int startVertex, int numVerts)
Definition: mesh.h:175
Describes vertex elements in interleaved data buffers.
virtual void SetFVarDataChannel(int fvarWidth, std::vector< float > const &fvarData)
Definition: mesh.h:207
virtual void UpdateVertexBuffer(float const *vertexData, int startVertex, int numVerts)
Definition: glMesh.h:113
MeshInterface< GLDrawContext > GLMeshInterface
Definition: glMesh.h:44
std::vector< KernelBatch > KernelBatchVector
Definition: kernelBatch.h:73
virtual void UpdateVaryingBuffer(float const *varyingData, int startVertex, int numVerts)
Definition: mesh.h:179
DrawContext::VertexBufferBinding VertexBufferBinding
Definition: mesh.h:120
int GetNumVerticesTotal() const
Returns the total number of vertices in all levels.
virtual void Refine(VertexBufferDescriptor const *vertexDesc, VertexBufferDescriptor const *varyingDesc, bool interleaved)
Definition: glMesh.h:125
virtual int GetNumVertices() const
Definition: mesh.h:170
std::bitset< NUM_MESH_BITS > MeshBitset
Definition: mesh.h:56
Mesh(ComputeController *computeController, Far::TopologyRefiner *refiner, int numVertexElements, int numVaryingElements, int level, MeshBitset bits)
Definition: glMesh.h:55
ComputeController::ComputeContext ComputeContext
Definition: mesh.h:118
Mesh(ComputeController *computeController, Far::TopologyRefiner *refiner, int numVertexElements, int numVaryingElements, int level, MeshBitset bits=MeshBitset())
Definition: mesh.h:122
virtual VertexBufferBinding BindVaryingBuffer()
Definition: mesh.h:199
static StencilTables const * Create(TopologyRefiner const &refiner, Options options=Options())
Instantiates StencilTables from TopologyRefiner that have been refined uniformly or adaptively...
OpenGL specialized DrawContext class.
Definition: glDrawContext.h:54
bool IsUniform() const
Returns true if uniform subdivision has been applied.
Stores topology data for a specified set of refinement options.
virtual VertexBufferBinding BindVertexBuffer()
Definition: mesh.h:195
virtual void SetFVarDataChannel(int fvarWidth, std::vector< float > const &fvarData)
Definition: glMesh.h:161
static int getNumVertices(Far::TopologyRefiner const &refiner)
Definition: mesh.h:93