1 /*=========================================================================
2
3 Program: Visualization Toolkit
4
5 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
6 All rights reserved.
7 See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
8
9 This software is distributed WITHOUT ANY WARRANTY; without even
10 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11 PURPOSE. See the above copyright notice for more information.
12
13 =========================================================================*/
14 #include "vtkOpenGLGlyph3DHelper.h"
15
16 #include "vtkOpenGLHelper.h"
17
18 #include "vtkBitArray.h"
19 #include "vtkCamera.h"
20 #include "vtkDataObject.h"
21 #include "vtkHardwareSelector.h"
22 #include "vtkMath.h"
23 #include "vtkMatrix3x3.h"
24 #include "vtkMatrix4x4.h"
25 #include "vtkNew.h"
26 #include "vtkObjectFactory.h"
27 #include "vtkOpenGLActor.h"
28 #include "vtkOpenGLBufferObject.h"
29 #include "vtkOpenGLCamera.h"
30 #include "vtkOpenGLError.h"
31 #include "vtkOpenGLIndexBufferObject.h"
32 #include "vtkOpenGLInstanceCulling.h"
33 #include "vtkOpenGLRenderWindow.h"
34 #include "vtkOpenGLRenderer.h"
35 #include "vtkOpenGLResourceFreeCallback.h"
36 #include "vtkOpenGLShaderCache.h"
37 #include "vtkOpenGLVertexArrayObject.h"
38 #include "vtkOpenGLVertexBufferObject.h"
39 #include "vtkOpenGLVertexBufferObjectGroup.h"
40 #include "vtkPolyData.h"
41 #include "vtkProperty.h"
42 #include "vtkShader.h"
43 #include "vtkShaderProgram.h"
44 #include "vtkTransform.h"
45 #include "vtkTransformFeedback.h"
46
47 #include "vtkGlyph3DVS.h"
48
49 #include <algorithm>
50 #include <numeric>
51
52 //-----------------------------------------------------------------------------
vtkStandardNewMacro(vtkOpenGLGlyph3DHelper)53 vtkStandardNewMacro(vtkOpenGLGlyph3DHelper)
54
55 //-----------------------------------------------------------------------------
56 vtkOpenGLGlyph3DHelper::vtkOpenGLGlyph3DHelper()
57 {
58 this->UsingInstancing = false;
59 this->PopulateSelectionSettings = 0;
60 }
61
62 // ---------------------------------------------------------------------------
63 // Description:
64 // Release any graphics resources that are being consumed by this mapper.
ReleaseGraphicsResources(vtkWindow * window)65 void vtkOpenGLGlyph3DHelper::ReleaseGraphicsResources(vtkWindow *window)
66 {
67 this->NormalMatrixBuffer->ReleaseGraphicsResources();
68 this->MatrixBuffer->ReleaseGraphicsResources();
69 this->ColorBuffer->ReleaseGraphicsResources();
70 this->Superclass::ReleaseGraphicsResources(window);
71 }
72
73 //-----------------------------------------------------------------------------
GetShaderTemplate(std::map<vtkShader::Type,vtkShader * > shaders,vtkRenderer * ren,vtkActor * actor)74 void vtkOpenGLGlyph3DHelper::GetShaderTemplate(
75 std::map<vtkShader::Type, vtkShader *> shaders,
76 vtkRenderer *ren, vtkActor *actor)
77 {
78 this->Superclass::GetShaderTemplate(shaders,ren,actor);
79
80 shaders[vtkShader::Vertex]->SetSource(vtkGlyph3DVS);
81 }
82
ReplaceShaderPositionVC(std::map<vtkShader::Type,vtkShader * > shaders,vtkRenderer * ren,vtkActor * actor)83 void vtkOpenGLGlyph3DHelper::ReplaceShaderPositionVC(
84 std::map<vtkShader::Type, vtkShader *> shaders,
85 vtkRenderer *ren, vtkActor *actor)
86 {
87 std::string VSSource = shaders[vtkShader::Vertex]->GetSource();
88
89 if (this->LastLightComplexity[this->LastBoundBO] > 0)
90 {
91 // we use vertex instead of vertexMC
92 vtkShaderProgram::Substitute(VSSource,
93 "//VTK::PositionVC::Impl",
94 "vertexVCVSOutput = MCVCMatrix * vertex;\n"
95 " gl_Position = MCDCMatrix * vertex;\n");
96 }
97 else
98 {
99 vtkShaderProgram::Substitute(VSSource,
100 "//VTK::PositionVC::Impl",
101 "gl_Position = MCDCMatrix * vertex;\n");
102 }
103
104 shaders[vtkShader::Vertex]->SetSource(VSSource);
105
106 this->Superclass::ReplaceShaderPositionVC(shaders,ren,actor);
107 }
108
ReplaceShaderColor(std::map<vtkShader::Type,vtkShader * > shaders,vtkRenderer * ren,vtkActor * actor)109 void vtkOpenGLGlyph3DHelper::ReplaceShaderColor(
110 std::map<vtkShader::Type, vtkShader *> shaders,
111 vtkRenderer *ren, vtkActor *actor)
112 {
113 std::string VSSource = shaders[vtkShader::Vertex]->GetSource();
114 std::string FSSource = shaders[vtkShader::Fragment]->GetSource();
115 std::string GSSource = shaders[vtkShader::Geometry]->GetSource();
116
117 // deal with color
118 if (this->UsingInstancing)
119 {
120 vtkShaderProgram::Substitute(VSSource,
121 "//VTK::Color::Dec",
122 "in vec4 glyphColor;\n"
123 "out vec4 vertexColorVSOutput;");
124 vtkShaderProgram::Substitute(GSSource,
125 "//VTK::Color::Dec",
126 "in vec4 vertexColorVSOutput[];\n"
127 "out vec4 vertexColorGSOutput;");
128 vtkShaderProgram::Substitute(GSSource,
129 "//VTK::Color::Impl",
130 "vertexColorGSOutput = vertexColorVSOutput[i];");
131 vtkShaderProgram::Substitute(VSSource,"//VTK::Color::Impl",
132 "vertexColorVSOutput = glyphColor;");
133 vtkShaderProgram::Substitute(FSSource,"//VTK::Color::Dec",
134 "in vec4 vertexColorVSOutput;\n"
135 "//VTK::Color::Dec", false);
136 }
137 else
138 {
139 vtkShaderProgram::Substitute(VSSource,
140 "//VTK::Color::Dec", "");
141 vtkShaderProgram::Substitute(FSSource,
142 "//VTK::Color::Dec",
143 "uniform vec4 glyphColor;\n"
144 "//VTK::Color::Dec", false);
145 vtkShaderProgram::Substitute(FSSource,"//VTK::Color::Impl",
146 "vec4 vertexColorVSOutput = glyphColor;\n"
147 "//VTK::Color::Impl", false);
148 }
149
150 // now handle scalar coloring
151 if(!this->DrawingEdgesOrVertices)
152 {
153 vtkShaderProgram::Substitute(FSSource,"//VTK::Color::Impl",
154 "//VTK::Color::Impl\n"
155 " diffuseColor = diffuseIntensity * vertexColorVSOutput.rgb;\n"
156 " ambientColor = ambientIntensity * vertexColorVSOutput.rgb;\n"
157 " opacity = opacity * vertexColorVSOutput.a;");
158 }
159
160 if (this->UsingInstancing)
161 {
162 vtkShaderProgram::Substitute(VSSource,
163 "//VTK::Glyph::Dec",
164 "in mat4 GCMCMatrix;");
165 }
166 else
167 {
168 vtkShaderProgram::Substitute(VSSource,
169 "//VTK::Glyph::Dec",
170 "uniform mat4 GCMCMatrix;");
171 }
172 vtkShaderProgram::Substitute(VSSource,
173 "//VTK::Glyph::Impl",
174 "vec4 vertex = GCMCMatrix * vertexMC;\n");
175
176 shaders[vtkShader::Vertex]->SetSource(VSSource);
177 shaders[vtkShader::Fragment]->SetSource(FSSource);
178 shaders[vtkShader::Geometry]->SetSource(GSSource);
179
180 this->Superclass::ReplaceShaderColor(shaders,ren,actor);
181 }
182
ReplaceShaderNormal(std::map<vtkShader::Type,vtkShader * > shaders,vtkRenderer * ren,vtkActor * actor)183 void vtkOpenGLGlyph3DHelper::ReplaceShaderNormal(
184 std::map<vtkShader::Type, vtkShader *> shaders,
185 vtkRenderer *ren, vtkActor *actor)
186 {
187 std::string VSSource = shaders[vtkShader::Vertex]->GetSource();
188 std::string FSSource = shaders[vtkShader::Fragment]->GetSource();
189
190 // new code for normal matrix if we have normals
191 if (this->VBOs->GetNumberOfComponents("normalMC") == 3)
192 {
193 if (this->UsingInstancing)
194 {
195 vtkShaderProgram::Substitute(VSSource,
196 "//VTK::Normal::Dec",
197 "uniform mat3 normalMatrix;\n"
198 "in vec3 normalMC;\n"
199 "in mat3 glyphNormalMatrix;\n"
200 "out vec3 normalVCVSOutput;");
201 }
202 else
203 {
204 vtkShaderProgram::Substitute(VSSource,
205 "//VTK::Normal::Dec",
206 "uniform mat3 normalMatrix;\n"
207 "in vec3 normalMC;\n"
208 "uniform mat3 glyphNormalMatrix;\n"
209 "out vec3 normalVCVSOutput;");
210 }
211 vtkShaderProgram::Substitute(VSSource, "//VTK::Normal::Impl",
212 "normalVCVSOutput = normalMatrix * glyphNormalMatrix * normalMC;");
213 }
214
215 shaders[vtkShader::Vertex]->SetSource(VSSource);
216 shaders[vtkShader::Fragment]->SetSource(FSSource);
217
218 this->Superclass::ReplaceShaderNormal(shaders,ren,actor);
219 }
220
221
ReplaceShaderClip(std::map<vtkShader::Type,vtkShader * > shaders,vtkRenderer * ren,vtkActor * actor)222 void vtkOpenGLGlyph3DHelper::ReplaceShaderClip(
223 std::map<vtkShader::Type, vtkShader *> shaders,
224 vtkRenderer *ren, vtkActor *actor)
225 {
226 std::string VSSource = shaders[vtkShader::Vertex]->GetSource();
227
228 // override one part of the clipping code
229 if (this->GetNumberOfClippingPlanes())
230 {
231 // add all the clipping planes
232 int numClipPlanes = this->GetNumberOfClippingPlanes();
233 if (numClipPlanes > 6)
234 {
235 vtkErrorMacro("OpenGL has a limit of 6 clipping planes");
236 }
237
238 vtkShaderProgram::Substitute(VSSource,
239 "//VTK::Clip::Impl",
240 "for (int planeNum = 0; planeNum < numClipPlanes; planeNum++)\n"
241 " {\n"
242 " clipDistancesVSOutput[planeNum] = dot(clipPlanes[planeNum], vertex);\n"
243 " }\n");
244 }
245
246 shaders[vtkShader::Vertex]->SetSource(VSSource);
247
248 this->Superclass::ReplaceShaderClip(shaders,ren,actor);
249 }
250
ReplaceShaderPicking(std::map<vtkShader::Type,vtkShader * > shaders,vtkRenderer *,vtkActor *)251 void vtkOpenGLGlyph3DHelper::ReplaceShaderPicking(
252 std::map<vtkShader::Type, vtkShader *> shaders,
253 vtkRenderer *, vtkActor *)
254 {
255 std::string FSSource = shaders[vtkShader::Fragment]->GetSource();
256
257 if (this->LastSelectionState >= vtkHardwareSelector::MIN_KNOWN_PASS)
258 {
259 vtkShaderProgram::Substitute(FSSource, "//VTK::Picking::Dec",
260 "uniform vec3 mapperIndex;");
261 vtkShaderProgram::Substitute(FSSource,
262 "//VTK::Picking::Impl",
263 " gl_FragData[0] = vec4(mapperIndex,1.0);\n");
264 }
265 shaders[vtkShader::Fragment]->SetSource(FSSource);
266 }
267
GlyphRender(vtkRenderer * ren,vtkActor * actor,vtkIdType numPts,std::vector<unsigned char> & colors,std::vector<float> & matrices,std::vector<float> & normalMatrices,std::vector<vtkIdType> & pickIds,vtkMTimeType pointMTime,bool culling)268 void vtkOpenGLGlyph3DHelper::GlyphRender(
269 vtkRenderer* ren,
270 vtkActor* actor,
271 vtkIdType numPts,
272 std::vector<unsigned char> &colors,
273 std::vector<float> &matrices,
274 std::vector<float> &normalMatrices,
275 std::vector<vtkIdType> &pickIds,
276 vtkMTimeType pointMTime,
277 bool culling)
278 {
279 this->ResourceCallback->RegisterGraphicsResources(
280 static_cast<vtkOpenGLRenderWindow *>(ren->GetRenderWindow()));
281
282 this->UsingInstancing = false;
283
284 vtkHardwareSelector* selector = ren->GetSelector();
285
286 if (!selector && !ren->GetRenderWindow()->GetIsPicking()
287 && GLEW_ARB_instanced_arrays)
288 {
289 // if there is no triangle, culling is useless.
290 // GLEW_ARB_gpu_shader5 is needed by the culling shader.
291 #ifndef GL_ES_VERSION_3_0
292 if (this->CurrentInput->GetNumberOfPolys() <= 0 || !GLEW_ARB_gpu_shader5 || !GLEW_ARB_transform_feedback3)
293 {
294 culling = false;
295 }
296 #else
297 // disable culling on OpenGL ES
298 culling = false;
299 #endif
300
301 this->GlyphRenderInstances(ren, actor, numPts, colors,
302 matrices, normalMatrices, pointMTime, culling);
303 return;
304 }
305
306 bool selecting_points = selector && (selector->GetFieldAssociation() ==
307 vtkDataObject::FIELD_ASSOCIATION_POINTS);
308
309 int representation = actor->GetProperty()->GetRepresentation();
310
311 this->RenderPieceStart(ren,actor);
312
313 if (selecting_points)
314 {
315 #if GL_ES_VERSION_3_0 != 1
316 glPointSize(6.0);
317 #endif
318 representation = GL_POINTS;
319 }
320
321 bool draw_surface_with_edges =
322 (actor->GetProperty()->GetEdgeVisibility() && representation == VTK_SURFACE) && !selector;
323 int numVerts = this->VBOs->GetNumberOfTuples("vertexMC");
324 for (int i = PrimitiveStart;
325 i < (draw_surface_with_edges ? PrimitiveEnd : PrimitiveTriStrips + 1); i++)
326 {
327 this->DrawingEdgesOrVertices = (i > PrimitiveTriStrips ? true : false);
328 if (this->Primitives[i].IBO->IndexCount)
329 {
330 this->UpdateShaders(this->Primitives[i], ren, actor);
331 GLenum mode = this->GetOpenGLMode(representation, i);
332 this->Primitives[i].IBO->Bind();
333 for (vtkIdType inPtId = 0; inPtId < numPts; inPtId++)
334 {
335 // handle the middle
336 vtkShaderProgram *program = this->Primitives[i].Program;
337
338 if (!program)
339 {
340 return;
341 }
342
343 // Apply the extra transform
344 program->SetUniformMatrix4x4("GCMCMatrix", &(matrices[inPtId*16]));
345
346 // for lit shaders set normal matrix
347 if (this->LastLightComplexity[this->LastBoundBO] > 0 &&
348 this->VBOs->GetNumberOfComponents("normalMC") == 3 &&
349 !this->UsingInstancing)
350 {
351 program->SetUniformMatrix3x3("glyphNormalMatrix", &(normalMatrices[inPtId*9]));
352 }
353
354 program->SetUniform4uc("glyphColor", &(colors[inPtId*4]));
355
356 if (selector)
357 {
358 if (selector->GetCurrentPass() == vtkHardwareSelector::POINT_ID_LOW24 ||
359 selector->GetCurrentPass() == vtkHardwareSelector::POINT_ID_HIGH24 ||
360 selector->GetCurrentPass() == vtkHardwareSelector::CELL_ID_LOW24 ||
361 selector->GetCurrentPass() == vtkHardwareSelector::CELL_ID_HIGH24)
362 {
363 selector->SetPropColorValue(pickIds[inPtId]);
364 }
365 program->SetUniform3f("mapperIndex", selector->GetPropColorValue());
366 }
367
368 glDrawRangeElements(mode, 0,
369 static_cast<GLuint>(numVerts - 1),
370 static_cast<GLsizei>(this->Primitives[i].IBO->IndexCount),
371 GL_UNSIGNED_INT,
372 nullptr);
373 }
374 this->Primitives[i].IBO->Release();
375 }
376 }
377 this->RenderPieceFinish(ren,actor);
378 }
379
380 //-----------------------------------------------------------------------------
SetMapperShaderParameters(vtkOpenGLHelper & cellBO,vtkRenderer * ren,vtkActor * actor)381 void vtkOpenGLGlyph3DHelper::SetMapperShaderParameters(vtkOpenGLHelper &cellBO,
382 vtkRenderer *ren, vtkActor *actor)
383 {
384 this->Superclass::SetMapperShaderParameters(cellBO,ren,actor);
385
386 vtkHardwareSelector* selector = ren->GetSelector();
387 if (selector)
388 {
389 cellBO.Program->SetUniform3f("mapperIndex", selector->GetPropColorValue());
390 }
391 }
392
GlyphRenderInstances(vtkRenderer * ren,vtkActor * actor,vtkIdType numPts,std::vector<unsigned char> & colors,std::vector<float> & matrices,std::vector<float> & normalMatrices,vtkMTimeType pointMTime,bool culling)393 void vtkOpenGLGlyph3DHelper::GlyphRenderInstances(
394 vtkRenderer* ren, vtkActor* actor, vtkIdType numPts,
395 std::vector<unsigned char> &colors, std::vector<float> &matrices,
396 std::vector<float> &normalMatrices,
397 vtkMTimeType pointMTime, bool culling)
398 {
399 this->UsingInstancing = true;
400 this->RenderPieceStart(ren,actor);
401 int representation = actor->GetProperty()->GetRepresentation();
402
403 bool withNormals = (this->VBOs->GetNumberOfComponents("normalMC") == 3);
404
405 // update the VBOs if needed
406 if (pointMTime > this->InstanceBuffersBuildTime.GetMTime())
407 {
408 this->MatrixBuffer->Upload(matrices, vtkOpenGLBufferObject::ArrayBuffer);
409
410 if (withNormals)
411 {
412 this->NormalMatrixBuffer->Upload(
413 normalMatrices, vtkOpenGLBufferObject::ArrayBuffer);
414 }
415
416 this->ColorBuffer->Upload(colors, vtkOpenGLBufferObject::ArrayBuffer);
417 this->InstanceBuffersBuildTime.Modified();
418 }
419
420 bool draw_surface_with_edges =
421 (actor->GetProperty()->GetEdgeVisibility() && representation == VTK_SURFACE);
422 for (int i = PrimitiveStart;
423 i < (draw_surface_with_edges ? PrimitiveEnd : PrimitiveTriStrips + 1); i++)
424 {
425 this->DrawingEdgesOrVertices = (i > PrimitiveTriStrips ? true : false);
426 if (this->Primitives[i].IBO->IndexCount)
427 {
428 GLenum mode = this->GetOpenGLMode(representation, i);
429
430 // culling
431 if (culling)
432 {
433 this->BuildCullingShaders(ren, actor, numPts, withNormals);
434 if (!this->InstanceCulling->GetHelper().Program)
435 {
436 return;
437 }
438
439 this->InstanceCulling->RunCullingShaders(numPts, this->MatrixBuffer, this->ColorBuffer, this->NormalMatrixBuffer);
440
441 // draw each LOD
442
443 this->UpdateShaders(this->Primitives[i], ren, actor);
444 if (!this->Primitives[i].Program)
445 {
446 return;
447 }
448
449 size_t stride = (withNormals ? 29 : 20) * sizeof(float);
450
451 this->Primitives[i].VAO->Bind();
452
453 for (vtkIdType j=0; j<this->InstanceCulling->GetNumberOfLOD(); j++)
454 {
455 if (this->InstanceCulling->GetLOD(j).NumberOfInstances == 0) continue;
456
457 // add VBO of current instance in VAO
458 if (!this->Primitives[i].VAO->AddAttributeArray(
459 this->Primitives[i].Program, this->InstanceCulling->GetLOD(j).PositionVBO,
460 "vertexMC", 0, 4 * sizeof(float), VTK_FLOAT, 4, false))
461 {
462 vtkErrorMacro("Error setting 'vertexMC' in shader VAO.");
463 }
464
465 if (withNormals)
466 {
467 if (!this->Primitives[i].VAO->AddAttributeArray(
468 this->Primitives[i].Program, this->InstanceCulling->GetLOD(j).NormalVBO,
469 "normalMC", 0, 3 * sizeof(float), VTK_FLOAT, 3, false))
470 {
471 vtkErrorMacro("Error setting 'normalMC' in shader VAO.");
472 }
473 }
474
475 // add instances attributes based on transform feedback buffers
476 if (!this->Primitives[i].VAO->AddAttributeArrayWithDivisor(
477 this->Primitives[i].Program, this->InstanceCulling->GetLODBuffer(j),
478 "glyphColor", 16 * sizeof(float), stride, VTK_FLOAT, 4, false, 1, false))
479 {
480 vtkErrorMacro("Error setting 'diffuse color' in shader VAO.");
481 }
482
483 if (!this->Primitives[i].VAO->AddAttributeMatrixWithDivisor(
484 this->Primitives[i].Program, this->InstanceCulling->GetLODBuffer(j),
485 "GCMCMatrix", 0, stride, VTK_FLOAT, 4, false, 1, 4 * sizeof(float)))
486 {
487 vtkErrorMacro("Error setting 'GCMCMatrix' in shader VAO.");
488 }
489
490 if (withNormals)
491 {
492 if (!this->Primitives[i].VAO->AddAttributeMatrixWithDivisor(
493 this->Primitives[i].Program, this->InstanceCulling->GetLODBuffer(j),
494 "glyphNormalMatrix", 20 * sizeof(float), stride, VTK_FLOAT, 3, false, 1, 3 * sizeof(float)))
495 {
496 vtkErrorMacro("Error setting 'glyphNormalMatrix' in shader VAO.");
497 }
498 }
499
500 if (this->InstanceCulling->GetLOD(j).IBO->IndexCount > 0)
501 {
502 this->InstanceCulling->GetLOD(j).IBO->Bind();
503
504 #if GL_ES_VERSION_3_0 == 1
505 glDrawElementsInstanced(mode,
506 static_cast<GLsizei>(this->InstanceCulling->GetLOD(j).IBO->IndexCount),
507 GL_UNSIGNED_INT,
508 nullptr,
509 this->InstanceCulling->GetLOD(j).NumberOfInstances);
510 #else
511 glDrawElementsInstancedARB(mode,
512 static_cast<GLsizei>(this->InstanceCulling->GetLOD(j).IBO->IndexCount),
513 GL_UNSIGNED_INT,
514 nullptr,
515 this->InstanceCulling->GetLOD(j).NumberOfInstances);
516 #endif
517 this->InstanceCulling->GetLOD(j).IBO->Release();
518 }
519 else
520 {
521 #if GL_ES_VERSION_3_0 == 1
522 glDrawArraysInstanced(GL_POINTS, 0, 1,
523 this->InstanceCulling->GetLOD(j).NumberOfInstances);
524 #else
525 glDrawArraysInstancedARB(GL_POINTS, 0, 1,
526 this->InstanceCulling->GetLOD(j).NumberOfInstances);
527 #endif
528 }
529 }
530 }
531 else
532 {
533 this->UpdateShaders(this->Primitives[i], ren, actor);
534 if (!this->Primitives[i].Program)
535 {
536 return;
537 }
538
539 // do the superclass and then reset a couple values
540 if ((this->InstanceBuffersBuildTime > this->InstanceBuffersLoadTime ||
541 this->Primitives[i].ShaderSourceTime > this->InstanceBuffersLoadTime))
542 {
543 this->Primitives[i].VAO->Bind();
544
545 this->MatrixBuffer->Bind();
546 if (!this->Primitives[i].VAO->AddAttributeMatrixWithDivisor(
547 this->Primitives[i].Program, this->MatrixBuffer,
548 "GCMCMatrix", 0, 16 * sizeof(float), VTK_FLOAT, 4, false, 1, 4 * sizeof(float)))
549 {
550 vtkErrorMacro("Error setting 'GCMCMatrix' in shader VAO.");
551 }
552 this->MatrixBuffer->Release();
553
554 if (withNormals && this->Primitives[i].Program->IsAttributeUsed("glyphNormalMatrix"))
555 {
556 this->NormalMatrixBuffer->Bind();
557 if (!this->Primitives[i].VAO->AddAttributeMatrixWithDivisor(
558 this->Primitives[i].Program, this->NormalMatrixBuffer,
559 "glyphNormalMatrix", 0, 9 * sizeof(float), VTK_FLOAT, 3, false, 1, 3 * sizeof(float)))
560 {
561 vtkErrorMacro("Error setting 'glyphNormalMatrix' in shader VAO.");
562 }
563 this->NormalMatrixBuffer->Release();
564 }
565
566 if (this->Primitives[i].Program->IsAttributeUsed("glyphColor"))
567 {
568 this->ColorBuffer->Bind();
569 if (!this->Primitives[i].VAO->AddAttributeArrayWithDivisor(
570 this->Primitives[i].Program, this->ColorBuffer,
571 "glyphColor", 0, 4 * sizeof(unsigned char), VTK_UNSIGNED_CHAR, 4, true, 1, false))
572 {
573 vtkErrorMacro("Error setting 'diffuse color' in shader VAO.");
574 }
575 this->ColorBuffer->Release();
576 }
577 this->InstanceBuffersLoadTime.Modified();
578 }
579
580 this->Primitives[i].IBO->Bind();
581
582 #if GL_ES_VERSION_3_0 == 1
583 glDrawElementsInstanced(mode,
584 static_cast<GLsizei>(this->Primitives[i].IBO->IndexCount),
585 GL_UNSIGNED_INT,
586 nullptr,
587 numPts);
588 #else
589 glDrawElementsInstancedARB(mode,
590 static_cast<GLsizei>(this->Primitives[i].IBO->IndexCount),
591 GL_UNSIGNED_INT,
592 nullptr,
593 numPts);
594 #endif
595
596 this->Primitives[i].IBO->Release();
597 }
598 }
599 }
600
601 vtkOpenGLCheckErrorMacro("failed after Render");
602 this->RenderPieceFinish(ren, actor);
603 }
604
605 //-----------------------------------------------------------------------------
BuildCullingShaders(vtkRenderer * ren,vtkActor * actor,vtkIdType numPts,bool withNormals)606 void vtkOpenGLGlyph3DHelper::BuildCullingShaders(vtkRenderer* ren, vtkActor* actor, vtkIdType numPts, bool withNormals)
607 {
608 vtkOpenGLRenderWindow* renWin = vtkOpenGLRenderWindow::SafeDownCast(ren->GetRenderWindow());
609
610 if (!this->InstanceCulling->GetHelper().Program)
611 {
612 this->InstanceCulling->InitLOD(this->CurrentInput);
613
614 for (auto& lod : this->LODs)
615 {
616 this->InstanceCulling->AddLOD(lod.first, lod.second);
617 }
618 }
619
620 this->InstanceCulling->BuildCullingShaders(renWin->GetShaderCache(), numPts, withNormals);
621
622 if (this->InstanceCulling->GetHelper().Program)
623 {
624 this->SetCameraShaderParameters(this->InstanceCulling->GetHelper(), ren, actor);
625
626 double* bounds = this->CurrentInput->GetBounds();
627 float BBoxSize[4] = { static_cast<float>(bounds[1] - bounds[0]),
628 static_cast<float>(bounds[3] - bounds[2]),
629 static_cast<float>(bounds[5] - bounds[4]),
630 0.f };
631
632 this->InstanceCulling->GetHelper().Program->SetUniform4f("BBoxSize", BBoxSize);
633 }
634 }
635
636 //-----------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)637 void vtkOpenGLGlyph3DHelper::PrintSelf(ostream& os, vtkIndent indent)
638 {
639 this->Superclass::PrintSelf(os, indent);
640 }
641
642 //-----------------------------------------------------------------------------
SetLODs(std::vector<std::pair<float,float>> & lods)643 void vtkOpenGLGlyph3DHelper::SetLODs(std::vector<std::pair<float, float> >& lods)
644 {
645 this->LODs = lods;
646 }
647
648 //-----------------------------------------------------------------------------
SetLODColoring(bool val)649 void vtkOpenGLGlyph3DHelper::SetLODColoring(bool val)
650 {
651 this->InstanceCulling->SetColorLOD(val);
652 }
653