GLVis  v4.2
Accurate and flexible finite element visualization
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
openglvis.cpp
Go to the documentation of this file.
1 // Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
2 // at the Lawrence Livermore National Laboratory. All Rights reserved. See files
3 // LICENSE and NOTICE for details. LLNL-CODE-443271.
4 //
5 // This file is part of the GLVis visualization tool and library. For more
6 // information and source code availability see https://glvis.org.
7 //
8 // GLVis is free software; you can redistribute it and/or modify it under the
9 // terms of the BSD-3 license. We welcome feedback and contributions, see file
10 // CONTRIBUTING.md for details.
11 
12 #include <iostream>
13 #include "openglvis.hpp"
14 #include "material.hpp"
15 #include "aux_vis.hpp"
16 
17 using namespace mfem;
18 
19 const int NUM_MATERIALS = 5;
20 extern Material materials[5];
21 extern Light lights[];
22 extern std::array<float, 4> amb_setting[];
23 extern Light lights_4[];
24 
26 {
27  static const double cam[9] =
28  {
29  0.0, 0.0, 2.5, // eye
30  0.0, 0.0, -1.0, // dir
31  0.0, 1.0, 0.0
32  }; // up
33 
34  Set(cam);
35 }
36 
37 void Camera::Set(const double cam[])
38 {
39  eye[0] = cam[0]; eye[1] = cam[1]; eye[2] = cam[2];
40  dir[0] = cam[3]; dir[1] = cam[4]; dir[2] = cam[5];
41  up [0] = cam[6]; up [1] = cam[7]; up [2] = cam[8];
42  Normalize(dir);
43  ProjectVector(up, dir);
44 }
45 
46 void Camera::TiltLeftRight(double angle)
47 {
48  LinearCombination(cos(angle), up, sin(angle), GetLeft(), up);
49  ProjectVector(up, dir);
50 }
51 
52 void Camera::TurnLeftRight(double angle)
53 {
54  LinearCombination(cos(angle), dir, sin(angle), GetLeft(), dir);
55  Normalize(dir);
56  ProjectVector(up, dir);
57 }
58 
59 void Camera::TurnUpDown(double angle)
60 {
61  double old_dir[3] = { dir[0], dir[1], dir[2] };
62  double c = cos(angle), s = sin(angle);
63  LinearCombination( c, old_dir, s, up, dir);
64  LinearCombination(-s, old_dir, c, up, up);
65  Normalize(dir);
66  ProjectVector(up, dir);
67 }
68 
69 glm::mat4 Camera::RotMatrix()
70 {
71  GetLeft();
72 
73  // *INDENT-OFF*
74  double mat[16] =
75  {
76  -left[0], up[0], -dir[0], 0.0,
77  -left[1], up[1], -dir[1], 0.0,
78  -left[2], up[2], -dir[2], 0.0,
79  0.0, 0.0, 0.0, 1.0
80  };
81  // *INDENT-ON*
82  return glm::make_mat4(mat);
83 }
84 
86 {
87  GetLeft();
88  // *INDENT-OFF*
89  double mat_t[16] =
90  {
91  -left[0], -left[1], -left[2], 0.0,
92  up[0], up[1], up[2], 0.0,
93  -dir[0], -dir[1], -dir[2], 0.0,
94  0.0, 0.0, 0.0, 1.0
95  };
96  // *INDENT-ON*
97  return glm::make_mat4(mat_t);
98 }
99 
101 {
102  glm::mat4 rotmtx = RotMatrix();
103  return glm::translate(rotmtx, glm::vec3(-eye[0], -eye[1], -eye[2]));
104 }
105 
107 {
108  std::cout <<
109  "camera " << eye[0] << ' ' << eye[1] << ' ' << eye[2] << "\n"
110  " " << dir[0] << ' ' << dir[1] << ' ' << dir[2] << "\n"
111  " " << up[0] << ' ' << up[1] << ' ' << up[2] << '\n'
112  << std::endl;
113 }
114 
116 {
117  translmat = glm::mat4(1.0);
118  rotmat = glm::mat4(1.0);
119  rotmat = glm::rotate(rotmat, glm::radians(-60.f), glm::vec3(1.f, 0.f, 0.f));
120  rotmat = glm::rotate(rotmat, glm::radians(-40.f), glm::vec3(0.f, 0.f, 1.f));
121  xscale = yscale = zscale = 1;
122  spinning = print = movie = 0;
123  OrthogonalProjection = 0;
124  ViewAngle = 45;
125  ViewScale = 1;
126  ViewCenterX = 0.0;
127  ViewCenterY = 0.0;
128 
129  cut_lambda = 0.0;
130  cut_updated = false;
131 
132  background = BG_WHITE;
133  GetAppWindow()->getRenderer().setClearColor(1.f, 1.f, 1.f, 1.f);
134  _use_cust_l0_pos = false;
135  light_mat_idx = 3;
136  use_light = true;
137 
138  palette.Init();
139 }
140 
142 
143 
146  const double (&p)[4][3], const double (&cv)[4],
147  const double minv, const double maxv)
148 {
149  // element center
150  double c[3];
151  c[0] = c[1] = c[2] = 0.0;
152  for (int j = 0; j < 3; j++)
153  {
154  c[0] += p[j][0]; c[1] += p[j][1]; c[2] += p[j][2];
155  }
156  c[0] /= 3.0; c[1] /= 3.0; c[2] /= 3.0;
157 
158  double l = cut_lambda;
159  double q[3][3];
160 
161  // corners of the cut frame
162  for (int j = 0; j < 3; j++)
163  {
164  q[j][0] = l*p[j][0] + (1.0-l)*c[0];
165  q[j][1] = l*p[j][1] + (1.0-l)*c[1];
166  q[j][2] = l*p[j][2] + (1.0-l)*c[2];
167  }
168 
169  double d[4][3];
170  double cvv[4];
171 
172  // bottom trapezoid
173  for (int k = 0; k < 3; k++)
174  {
175  d[0][k] = p[0][k]; d[1][k] = p[1][k]; d[2][k] = q[1][k]; d[3][k] = q[0][k];
176  }
177  DrawQuad(buff, d, cvv, minv, maxv);
178 
179  // diagonal trapezoid
180  for (int k = 0; k < 3; k++)
181  {
182  d[0][k] = p[1][k]; d[1][k] = p[2][k]; d[2][k] = q[2][k]; d[3][k] = q[1][k];
183  }
184  DrawQuad(buff, d, cvv, minv, maxv);
185 
186  // left trapezoid
187  for (int k = 0; k < 3; k++)
188  {
189  d[0][k] = p[2][k]; d[1][k] = p[0][k]; d[2][k] = q[0][k]; d[3][k] = q[2][k];
190  }
191  DrawQuad(buff, d, cvv, minv, maxv);
192 }
193 
194 
197  const double (&p)[4][3], const double (&cv)[4],
198  const double minv, const double maxv)
199 {
200  // element center
201  double c[3];
202  c[0] = c[1] = c[2] = 0.0;
203  for (int j = 0; j < 4; j++)
204  {
205  c[0] += p[j][0]; c[1] += p[j][1]; c[2] += p[j][2];
206  }
207  c[0] /= 4.0; c[1] /= 4.0; c[2] /= 4.0;
208 
209  double l = cut_lambda;
210  double q[4][3];
211 
212  // corners of the cut frame
213  for (int j = 0; j < 4; j++)
214  {
215  q[j][0] = l*p[j][0] + (1.0-l)*c[0];
216  q[j][1] = l*p[j][1] + (1.0-l)*c[1];
217  q[j][2] = l*p[j][2] + (1.0-l)*c[2];
218  }
219 
220  double d[4][3];
221  double cvv[4];
222 
223  // bottom trapezoid
224  for (int k = 0; k < 3; k++)
225  {
226  d[0][k] = p[0][k]; d[1][k] = p[1][k]; d[2][k] = q[1][k]; d[3][k] = q[0][k];
227  }
228  DrawQuad(buff, d, cvv, minv, maxv);
229 
230  // right trapezoid
231  for (int k = 0; k < 3; k++)
232  {
233  d[0][k] = p[1][k]; d[1][k] = p[2][k]; d[2][k] = q[2][k]; d[3][k] = q[1][k];
234  }
235  DrawQuad(buff, d, cvv, minv, maxv);
236 
237  // top trapezoid
238  for (int k = 0; k < 3; k++)
239  {
240  d[0][k] = p[2][k]; d[1][k] = p[3][k]; d[2][k] = q[3][k]; d[3][k] = q[2][k];
241  }
242  DrawQuad(buff, d, cvv, minv, maxv);
243 
244  // left trapezoid
245  for (int k = 0; k < 3; k++)
246  {
247  d[0][k] = p[3][k]; d[1][k] = p[0][k]; d[2][k] = q[0][k]; d[3][k] = q[3][k];
248  }
249  DrawQuad(buff, d, cvv, minv, maxv);
250 }
251 
252 
255  const double (&pts)[4][3], const double (&cv)[4],
256  const double minv, const double maxv)
257 {
258  double nor[3];
259  if (Compute3DUnitNormal(pts[0], pts[1], pts[2], nor))
260  {
261  return;
262  }
263 
264  std::array<float, 2> texcoord[3];
265  std::array<float, 3> fpts[3];
266  std::array<float, 3> fnorm = {(float) nor[0], (float) nor[1], (float) nor[2]};
267 
268  for (int i = 0; i < 3; i++)
269  {
270  float pal_coord = palette.GetColorCoord(cv[i], minv, maxv);
271  texcoord[i] = { pal_coord, 1.0 };
272  fpts[i] = {(float) pts[i][0], (float) pts[i][1], (float) pts[i][2]};
273  }
275  {fpts[0], fnorm, texcoord[0]},
276  {fpts[1], fnorm, texcoord[1]},
277  {fpts[2], fnorm, texcoord[2]});
278 }
279 
282  const double (&pts)[4][3], const double (&cv)[4],
283  const double minv, const double maxv)
284 {
285  double nor[3];
286  if (Compute3DUnitNormal(pts[0], pts[1], pts[2], nor))
287  {
288  return;
289  }
290 
291  std::array<float, 2> texcoord[4];
292  std::array<float, 3> fpts[4];
293  std::array<float, 3> fnorm = {(float) nor[0], (float) nor[1], (float) nor[2]};
294 
295  for (int i = 0; i < 4; i++)
296  {
297  float pal_coord = palette.GetColorCoord(cv[i], minv, maxv);
298  texcoord[i] = { pal_coord, 1.0 };
299  fpts[i] = {(float) pts[i][0], (float) pts[i][1], (float) pts[i][2]};
300  }
302  {fpts[0], fnorm, texcoord[0]},
303  {fpts[1], fnorm, texcoord[1]},
304  {fpts[2], fnorm, texcoord[2]},
305  {fpts[3], fnorm, texcoord[3]});
306 }
307 
309 ::DrawPatch(gl3::GlDrawable& drawable, const DenseMatrix &pts, Vector &vals,
310  DenseMatrix &normals,
311  const int n, const Array<int> &ind, const double minv,
312  const double maxv, const int normals_opt)
313 {
314  gl3::GlBuilder poly = drawable.createBuilder();
315  double na[3];
316 
317  if (normals_opt == 1 || normals_opt == -2)
318  {
319  normals.SetSize(3, pts.Width());
320  normals = 0.;
321  for (int i = 0; i < ind.Size(); i += n)
322  {
323  int j;
324  if (n == 3)
325  j = Compute3DUnitNormal(&pts(0, ind[i]), &pts(0, ind[i+1]),
326  &pts(0, ind[i+2]), na);
327  else
328  j = Compute3DUnitNormal(&pts(0, ind[i]), &pts(0, ind[i+1]),
329  &pts(0, ind[i+2]), &pts(0, ind[i+3]), na);
330  if (j == 0)
331  for ( ; j < n; j++)
332  for (int k = 0; k < 3; k++)
333  {
334  normals(k, ind[i+j]) += na[k];
335  }
336  }
337  }
338 
339  if (normals_opt != 0 && normals_opt != -1)
340  {
341  Normalize(normals);
342  std::vector<gl3::VertexNormTex> vertices;
343  std::vector<int> indices;
344  vertices.reserve(pts.Size());
345  indices.reserve(ind.Size());
346  for (int i = 0; i < pts.Width(); i++)
347  {
348  vertices.emplace_back(
350  {
351  {(float) pts(0, i), (float) pts(1, i), (float) pts(2, i)},
352  {(float) normals(0, i), (float) normals(1, i), (float) normals(2, i)},
353  {(float) palette.GetColorCoord(vals(i), minv, maxv), 1.0 }
354  });
355  }
356  if (normals_opt > 0)
357  {
358  for (int i = 0; i < ind.Size(); i++)
359  {
360  indices.emplace_back(ind[i]);
361  }
362  }
363  else
364  {
365  for (int i = ind.Size()-1; i >= 0; i--)
366  {
367  indices.emplace_back(ind[i]);
368  }
369  }
370  if (n == 3)
371  {
372  drawable.addTriangleIndexed(vertices, indices);
373  }
374  else
375  {
376  drawable.addQuadIndexed(vertices, indices);
377  }
378  }
379  else
380  {
381  if (n == 3)
382  {
383  poly.glBegin(GL_TRIANGLES);
384  }
385  else
386  {
387  poly.glBegin(GL_QUADS);
388  }
389  for (int i = 0; i < ind.Size(); i += n)
390  {
391  int j;
392  if (n == 3)
393  j = Compute3DUnitNormal(&pts(0, ind[i]), &pts(0, ind[i+1]),
394  &pts(0, ind[i+2]), na);
395  else
396  j = Compute3DUnitNormal(&pts(0, ind[i]), &pts(0, ind[i+1]),
397  &pts(0, ind[i+2]), &pts(0, ind[i+3]), na);
398  if (j == 0)
399  {
400  if (normals_opt == 0)
401  {
402  poly.glNormal3dv(na);
403  for ( ; j < n; j++)
404  {
405  MySetColor(poly, vals(ind[i+j]), minv, maxv);
406  poly.glVertex3dv(&pts(0, ind[i+j]));
407  }
408  }
409  else
410  {
411  poly.glNormal3d(-na[0], -na[1], -na[2]);
412  for (j = n-1; j >= 0; j--)
413  {
414  MySetColor(poly, vals(ind[i+j]), minv, maxv);
415  poly.glVertex3dv(&pts(0, ind[i+j]));
416  }
417  }
418  }
419  }
420  poly.glEnd();
421  }
422 }
423 
426 {
427 #ifdef GLVIS_USE_LIBPNG
428  const bool palette_smooth = palette.GetSmoothSetting();
429  auto sampler =
430  bld.addSampler(
431  /* magFilter: */
432  palette_smooth ? glTF_Builder::mag_filter::LINEAR :
434  /* minFilter: */
435  palette_smooth ? glTF_Builder::min_filter::LINEAR :
439  // create palette image
440  const int palette_size = palette.GetNumColors();
441  vector<array<float,4>> palette_data(palette_size);
442 #if 0
443  glGetTextureImage(
444  palette.GetColorTexture(), 0,
445  gl3::GLDevice::useLegacyTextureFmts() ? GL_RGBA : GL_RGBA32F,
446  GL_FLOAT,
447  palette_size,
448  palette_data.data());
449 #elif 0
450  glGetTexImage(GL_TEXTURE_2D, 0,
451  gl3::GLDevice::useLegacyTextureFmts() ? GL_RGBA : GL_RGBA32F,
452  GL_FLOAT, palette_data.data());
453 #else
454  const double *palette_data_raw = palette.GetData();
455  for (int i = 0; i < palette_size; ++i)
456  {
457  for (int j = 0; j < 3; ++j)
458  {
459  palette_data[i][j] = (float) palette_data_raw[j + 3*i];
460  }
461  palette_data[i][3] = 1.0f;
462  }
463 #endif
464  auto palette_img =
465  bld.addImage(
466  /* imageName: */ "palette",
467  /* width: */ palette_size,
468  /* height: */ 1,
469  /* color4f *pixels: */ palette_data.data());
470  auto palette_tex = bld.addTexture(sampler, palette_img);
471  glTF_Builder::pbr_matallic_roughness palette_pbr_mr =
472  {
473  /* haveTexture: */ true,
474  /* baseColorFactor: */ { 1.f, 1.f, 1.f, 1.f },
475  /* baseColorTexture: */ palette_tex,
476  /* metallicFactor: */ 1.f,
477  /* roughnessFactor: */ .3f
478  };
479 #else // GLVIS_USE_LIBPNG
480  glTF_Builder::pbr_matallic_roughness palette_pbr_mr =
481  {
482  /* haveTexture: */ false,
483  /* baseColorFactor: */ { 0.f, 1.f, .5f, 1.f },
484  /* baseColorTexture: */ {0},
485  /* metallicFactor: */ 1.f,
486  /* roughnessFactor: */ .3f
487  };
488 #endif // GLVIS_USE_LIBPNG
489  auto palette_mat =
490  bld.addMaterial(
491  /* materialName: */ "Palette Material",
492  /* pbrMetallicRoughness: */ palette_pbr_mr,
493  /* doubleSided: */ true);
494 
495  return palette_mat;
496 }
497 
500 {
502  {
503  /* haveTexture: */ false,
504  /* baseColorFactor: */ GetLineColor(),
505  /* baseColorTexture: */ {0},
506  /* metallicFactor: */ 1.f,
507  /* roughnessFactor: */ 1.f
508  };
509  auto black_mat =
510  bld.addMaterial(
511  /* materialName: */ "Black Material",
512  /* pbrMetallicRoughness: */ black_pbr_mr,
513  /* doubleSided: */ true);
514 
515  return black_mat;
516 }
517 
520  glTF_Builder &bld, glTF_Builder::material_id palette_mat)
521 {
522  glTF_Builder::pbr_matallic_roughness palette_pbr_mr_copy;
523  bld.getMaterialPBRMR(palette_mat, palette_pbr_mr_copy);
524  palette_pbr_mr_copy.metallicFactor = 1.f;
525  palette_pbr_mr_copy.roughnessFactor = 1.f;
526  auto palette_lines_mat =
527  bld.addMaterial(
528  /* materialName: */ "PaletteLines Material",
529  /* pbrMetallicRoughness: */ palette_pbr_mr_copy,
530  /* doubleSided: */ true);
531  return palette_lines_mat;
532 }
533 
535 VisualizationScene::AddModelNode(glTF_Builder &bld, const string &nodeName)
536 {
537  auto new_node = bld.addNode(nodeName);
538  // Coordinate system switch: (x,y,z) -> (x,z,-y).
539  // In glTF, the translation (T), rotation (R), and scale (S) properties are
540  // applied in the order: T * R * S.
541  // In GLVis, we apply them in the order: R * S * T.
542  bld.addNodeScale(
543  new_node, { (float)xscale, (float)zscale, (float)yscale });
544  bld.addNodeTranslation(
545  new_node, { float(-xscale*(bb.x[0]+bb.x[1])/2),
546  float(-zscale*bb.z[0]),
547  float(yscale*(bb.y[0]+bb.y[1])/2)
548  });
549  return new_node;
550 }
551 
552 // Used in VisualizationScene::AddTriangles() below.
553 void minmax(const float *data, size_t components, size_t stride, size_t count,
554  vector<float> &mins, vector<float> &maxs)
555 {
556  if (count == 0)
557  {
558  mins.assign(components, +numeric_limits<float>::infinity());
559  maxs.assign(components, -numeric_limits<float>::infinity());
560  return;
561  }
562  mins.resize(components);
563  maxs.resize(components);
564  for (size_t c = 0; c != components; ++c)
565  {
566  const auto entry = data[c];
567  mins[c] = entry;
568  maxs[c] = entry;
569  }
570  if (count == 1) { return; }
571  for (size_t i = 1; i != count; ++i)
572  {
573  data += stride;
574  for (size_t c = 0; c != components; ++c)
575  {
576  const auto entry = data[c];
577  if (entry < mins[c]) { mins[c] = entry; }
578  else if (entry > maxs[c]) { maxs[c] = entry; }
579  }
580  }
581 }
582 
586  glTF_Builder::material_id material,
587  const gl3::GlDrawable &gl_drawable)
588 {
589  int num_buf = 0, buf_layout = -1;
590  for (int layout = 0; layout < gl3::NUM_LAYOUTS; ++layout)
591  {
592  const gl3::IVertexBuffer *buf = gl_drawable.buffers[layout][1].get();
593  if (buf && buf->count() != 0)
594  {
595  num_buf++;
596  buf_layout = layout;
597  cout << "triangles: layout = " << layout << ", # vertices = "
598  << buf->count() << '\n';
599  }
600  }
601  int num_ibuf = 0, ibuf_layout = -1;
602  for (int layout = 0; layout < gl3::NUM_LAYOUTS; ++layout)
603  {
604  const gl3::IIndexedBuffer *ibuf =
605  gl_drawable.indexed_buffers[layout][1].get();
606  if (ibuf && ibuf->getIndices().size() != 0)
607  {
608  num_ibuf++;
609  ibuf_layout = layout;
610  cout << "indexed triangles: layout = " << layout << ", # vertices = "
611  << ibuf->count() << ", # indices = " << ibuf->getIndices().size()
612  << '\n';
613  }
614  }
615  if (num_buf + num_ibuf == 0) { return 0; }
616 
617  if (num_buf + num_ibuf > 1)
618  {
619  cout << "glTF export: skipping" << num_buf + num_ibuf - 1
620  << " triangle buffer(s).\n";
621  }
622  const gl3::IVertexBuffer *surf_buf = nullptr;
623  const gl3::IIndexedBuffer *surf_ibuf = nullptr;
624  const vector<int> *surf_indices = nullptr;
625  if (num_ibuf)
626  {
627  surf_buf = surf_ibuf = gl_drawable.indexed_buffers[ibuf_layout][1].get();
628  surf_indices = &surf_ibuf->getIndices();
629  buf_layout = ibuf_layout;
630  }
631  else
632  {
633  surf_buf = gl_drawable.buffers[buf_layout][1].get();
634  }
635  const size_t surf_vertices_count = surf_buf->count();
636  const size_t surf_vertices_stride = surf_buf->getStride(); // in bytes
637  const float *surf_vertices_data =
638  reinterpret_cast<const float *>(surf_buf->getData());
639  vector<float> vmins, vmaxs;
640  int components = surf_vertices_stride/sizeof(float);
641  switch (buf_layout)
642  {
643  case gl3::LAYOUT_VTX:
644  case gl3::LAYOUT_VTX_COLOR: components = 3; break;
645  case gl3::LAYOUT_VTX_TEXTURE0: components = 5; break;
647  case gl3::LAYOUT_VTX_NORMAL_COLOR: components = 6; break;
648  case gl3::LAYOUT_VTX_NORMAL_TEXTURE0: components = 8; break;
649  }
650  minmax(surf_vertices_data, components, surf_vertices_stride/sizeof(float),
651  surf_vertices_count, vmins, vmaxs);
652 
653  glTF_Builder::buffer_view_id surf_indices_buf_view;
654  if (surf_indices)
655  {
656  surf_indices_buf_view =
657  bld.addBufferView(
658  /* buffer: */ buffer,
659  /* data: */ surf_indices->data(),
660  /* byteLength: */ surf_indices->size()*sizeof(int),
661  /* byteStride: */ sizeof(int),
662  /* byteAlign: */ sizeof(int),
664  }
665 #if 0
666  auto surf_vertices_buf_view =
667  bld.addBufferView(
668  /* buffer: */ buffer,
669  /* data: */ surf_vertices_data,
670  /* byteLength: */ surf_vertices_count*surf_vertices_stride,
671  /* byteStride: */ surf_vertices_stride,
672  /* byteAlign: */ sizeof(float),
674 #else
675  auto surf_vertices_buf_view =
676  bld.addBufferView(
677  /* buffer: */ buffer,
678  /* data: */ surf_vertices_data,
679  /* byteLength: */ 0,
680  /* byteStride: */ surf_vertices_stride,
681  /* byteAlign: */ sizeof(float),
683  // Coordinate system switch: (x,y,z) -> (x,z,-y), see:
684  // https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#coordinate-system-and-units
685  switch (buf_layout)
686  {
687  case gl3::Vertex::layout:
688  {
689  auto surf_vert_data =
690  reinterpret_cast<const gl3::Vertex *>(surf_vertices_data);
691  for (size_t i = 0; i != surf_vertices_count; ++i)
692  {
693  auto &v = surf_vert_data[i];
694  gl3::Vertex vtx = { { v.coord[0], v.coord[2], -v.coord[1] } };
695  bld.appendToBufferView(surf_vertices_buf_view, &vtx, sizeof(vtx));
696  }
697  break;
698  }
700  {
701  auto surf_vert_data =
702  reinterpret_cast<const gl3::VertexNorm *>(surf_vertices_data);
703  for (size_t i = 0; i != surf_vertices_count; ++i)
704  {
705  auto &v = surf_vert_data[i];
706  gl3::VertexNorm vn =
707  {
708  { v.coord[0], v.coord[2], -v.coord[1] },
709  { v.norm[0], v.norm[2], -v.norm[1] }
710  };
711  bld.appendToBufferView(surf_vertices_buf_view, &vn, sizeof(vn));
712  }
713  break;
714  }
716  {
717  auto surf_vert_data =
718  reinterpret_cast<const gl3::VertexNormTex *>(surf_vertices_data);
719  for (size_t i = 0; i != surf_vertices_count; ++i)
720  {
721  auto &v = surf_vert_data[i];
722  gl3::VertexNormTex tv =
723  {
724  { v.coord[0], v.coord[2], -v.coord[1] },
725  { v.norm[0], v.norm[2], -v.norm[1] },
726  v.texCoord
727  };
728  bld.appendToBufferView(surf_vertices_buf_view, &tv, sizeof(tv));
729  }
730  break;
731  }
732  default:
733  {
734  cout << "glTF export: coorditate switch for layout " << buf_layout
735  << " is not implemented here:" << MFEM_LOCATION;
736  bld.appendToBufferView(surf_vertices_buf_view,
737  surf_vertices_data,
738  surf_vertices_count*surf_vertices_stride);
739  break;
740  }
741  }
742 #endif
744  if (surf_indices)
745  {
746  surf_indices_acc =
747  bld.addAccessor(
748  /* bufferView: */ surf_indices_buf_view,
749  /* byteOffset: */ 0,
750  /* componentType: */ glTF_Builder::component_type::UNSIGNED_INT,
751  /* count: */ surf_indices->size(),
752  /* tensorType: */ glTF_Builder::tensor_type::SCALAR);
753  }
754  auto surf_vertices_pos_acc =
755  bld.addAccessorVec3f(
756  /* bufferView: */ surf_vertices_buf_view,
757  /* byteOffset: */ 0,
758  /* count: */ surf_vertices_count,
759  // Coordinate system switch: (x,y,z) -> (x,z,-y), see above
760  /* vec3f min: */ { vmins[0], vmins[2], -vmaxs[1] },
761  /* vec3f max: */ { vmaxs[0], vmaxs[2], -vmins[1] });
762  unsigned floatOffset = 3;
764  const bool have_normals =
765  (buf_layout == gl3::LAYOUT_VTX_NORMAL ||
766  buf_layout == gl3::LAYOUT_VTX_NORMAL_COLOR ||
767  buf_layout == gl3::LAYOUT_VTX_NORMAL_TEXTURE0);
768  if (have_normals)
769  {
770  surf_vertices_nor_acc =
771  bld.addAccessor(
772  /* bufferView: */ surf_vertices_buf_view,
773  /* byteOffset: */ floatOffset*sizeof(float),
774  /* componentType: */ glTF_Builder::component_type::FLOAT,
775  /* count: */ surf_vertices_count,
776  /* tensorType: */ glTF_Builder::tensor_type::VEC3);
777  floatOffset += 3;
778  }
780  const bool have_texcoords =
781  (buf_layout == gl3::LAYOUT_VTX_TEXTURE0 ||
782  buf_layout == gl3::LAYOUT_VTX_NORMAL_TEXTURE0);
783  if (have_texcoords)
784  {
785  surf_vertices_tex_acc =
786  bld.addAccessorVec2f(
787  /* bufferView: */ surf_vertices_buf_view,
788  /* byteOffset: */ floatOffset*sizeof(float),
789  /* count: */ surf_vertices_count,
790  /* vec2f min: */ { vmins[floatOffset], vmins[floatOffset+1] },
791  /* vec2f max: */ { vmaxs[floatOffset], vmaxs[floatOffset+1] });
792  // floatOffset += 2;
793  }
794  bld.addMeshTriangles(
795  /* mesh: */ mesh,
796  /* vertexPositions: */ surf_vertices_pos_acc,
797  /* vertexNormals: */ surf_vertices_nor_acc,
798  /* vertexTexCoords0: */ surf_vertices_tex_acc,
799  /* vertexIndices: */ surf_indices_acc,
800  /* material: */ material);
801 
802  return surf_indices ? surf_indices->size()/3 : surf_vertices_count/3;
803 }
804 
808  glTF_Builder::material_id material,
809  const gl3::GlDrawable &gl_drawable)
810 {
811  int num_buf = 0, buf_layout = -1;
812  for (int layout = 0; layout < gl3::NUM_LAYOUTS; ++layout)
813  {
814  const gl3::IVertexBuffer *buf = gl_drawable.buffers[layout][0].get();
815  if (buf && buf->count() != 0)
816  {
817  num_buf++;
818  buf_layout = layout;
819  cout << "lines: layout = " << layout << ", # vertices = "
820  << buf->count() << '\n';
821  }
822  }
823  int num_ibuf = 0 /* , ibuf_layout = -1 */;
824  for (int layout = 0; layout < gl3::NUM_LAYOUTS; ++layout)
825  {
826  const gl3::IIndexedBuffer *ibuf =
827  gl_drawable.indexed_buffers[layout][0].get();
828  if (ibuf && ibuf->getIndices().size() != 0)
829  {
830  num_ibuf++;
831  /* ibuf_layout = layout; */
832  cout << "indexed lines: layout = " << layout << ", # vertices = "
833  << ibuf->count() << ", # indices = " << ibuf->getIndices().size()
834  << '\n';
835  }
836  }
837  if (num_buf + num_ibuf == 0) { return 0; }
838  if (num_buf == 0)
839  {
840  cout << "glTF export: indexed lines are not implemented.\n";
841  return 0;
842  }
843  if (num_buf + num_ibuf > 1)
844  {
845  cout << "glTF export: skipping" << num_buf + num_ibuf - 1
846  << " line buffer(s).\n";
847  }
848  const gl3::IVertexBuffer *lines_buf =
849  gl_drawable.buffers[buf_layout][0].get();
850  const size_t lines_vertices_count = lines_buf->count();
851  const size_t lines_vertices_stride = lines_buf->getStride(); // in bytes
852  const float *lines_vertices_data =
853  reinterpret_cast<const float *>(lines_buf->getData());
854  vector<float> vmins, vmaxs;
855  int components = lines_vertices_stride/sizeof(float);
856  switch (buf_layout)
857  {
858  case gl3::LAYOUT_VTX:
859  case gl3::LAYOUT_VTX_COLOR: components = 3; break;
860  case gl3::LAYOUT_VTX_TEXTURE0: components = 5; break;
862  case gl3::LAYOUT_VTX_NORMAL_COLOR: components = 6; break;
863  case gl3::LAYOUT_VTX_NORMAL_TEXTURE0: components = 8; break;
864  }
865  minmax(lines_vertices_data, components, lines_vertices_stride/sizeof(float),
866  lines_vertices_count, vmins, vmaxs);
867 
868 #if 0
869  auto lines_vertices_buf_view =
870  bld.addBufferView(
871  /* buffer: */ buffer,
872  /* data: */ lines_vertices_data,
873  /* byteLength: */ lines_vertices_count*lines_vertices_stride,
874  /* byteStride: */ lines_vertices_stride,
875  /* byteAlign: */ sizeof(float),
877 #else
878  auto lines_vertices_buf_view =
879  bld.addBufferView(
880  /* buffer: */ buffer,
881  /* data: */ lines_vertices_data,
882  /* byteLength: */ 0,
883  /* byteStride: */ lines_vertices_stride,
884  /* byteAlign: */ sizeof(float),
886  // Coordinate system switch: (x,y,z) -> (x,z,-y), see:
887  // https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#coordinate-system-and-units
888  switch (buf_layout)
889  {
890  case gl3::Vertex::layout:
891  {
892  auto lines_vert_data =
893  reinterpret_cast<const gl3::Vertex *>(lines_vertices_data);
894  for (size_t i = 0; i != lines_vertices_count; ++i)
895  {
896  auto &v = lines_vert_data[i];
897  gl3::Vertex vtx = { { v.coord[0], v.coord[2], -v.coord[1] } };
898  bld.appendToBufferView(lines_vertices_buf_view, &vtx, sizeof(vtx));
899  }
900  break;
901  }
903  {
904  auto lines_vert_data =
905  reinterpret_cast<const gl3::VertexColor *>(lines_vertices_data);
906  for (size_t i = 0; i != lines_vertices_count; ++i)
907  {
908  auto &v = lines_vert_data[i];
909  gl3::VertexColor vc =
910  {
911  { v.coord[0], v.coord[2], -v.coord[1] }, v.color
912  };
913  bld.appendToBufferView(lines_vertices_buf_view, &vc, sizeof(vc));
914  }
915  break;
916  }
918  {
919  auto lines_vert_data =
920  reinterpret_cast<const gl3::VertexTex *>(lines_vertices_data);
921  for (size_t i = 0; i != lines_vertices_count; ++i)
922  {
923  auto &v = lines_vert_data[i];
924  gl3::VertexTex vt =
925  {
926  { v.coord[0], v.coord[2], -v.coord[1] }, v.texCoord
927  };
928  bld.appendToBufferView(lines_vertices_buf_view, &vt, sizeof(vt));
929  }
930  break;
931  }
932  default:
933  {
934  cout << "glTF export: coorditate switch for layout " << buf_layout
935  << " is not implemented here:" << MFEM_LOCATION;
936  bld.appendToBufferView(lines_vertices_buf_view,
937  lines_vertices_data,
938  lines_vertices_count*lines_vertices_stride);
939  break;
940  }
941  }
942 #endif
943  auto lines_vertices_pos_acc =
944  bld.addAccessorVec3f(
945  /* bufferView: */ lines_vertices_buf_view,
946  /* byteOffset: */ 0,
947  /* count: */ lines_vertices_count,
948  // Coordinate system switch: (x,y,z) -> (x,z,-y), see above
949  /* vec3f min: */ { vmins[0], vmins[2], -vmaxs[1] },
950  /* vec3f max: */ { vmaxs[0], vmaxs[2], -vmins[1] });
951  unsigned floatOffset = 3;
952  glTF_Builder::accessor_id lines_vertices_col_acc{glTF_Builder::INVALID_ID};
953  const bool have_colors = (buf_layout == gl3::LAYOUT_VTX_COLOR);
954  if (have_colors)
955  {
956  lines_vertices_col_acc =
957  bld.addAccessor(
958  /* bufferView: */ lines_vertices_buf_view,
959  /* byteOffset: */ floatOffset*sizeof(float),
960  /* componentType: */ glTF_Builder::component_type::UNSIGNED_BYTE,
961  /* count: */ lines_vertices_count,
962  /* tensorType: */ glTF_Builder::tensor_type::VEC4);
963  // floatOffset += 2;
964  }
965  glTF_Builder::accessor_id lines_vertices_tex_acc{glTF_Builder::INVALID_ID};
966  const bool have_texcoords = (buf_layout == gl3::LAYOUT_VTX_TEXTURE0);
967  if (have_texcoords)
968  {
969  lines_vertices_tex_acc =
970  bld.addAccessorVec2f(
971  /* bufferView: */ lines_vertices_buf_view,
972  /* byteOffset: */ floatOffset*sizeof(float),
973  /* count: */ lines_vertices_count,
974  /* vec2f min: */ { vmins[floatOffset], vmins[floatOffset+1] },
975  /* vec2f max: */ { vmaxs[floatOffset], vmaxs[floatOffset+1] });
976  // floatOffset += 2;
977  }
978  bld.addMeshLines(
979  /* mesh: */ mesh,
980  /* vertexPositions: */ lines_vertices_pos_acc,
981  /* vertexTexcoords0: */ lines_vertices_tex_acc,
982  /* vertexColors0: */ lines_vertices_col_acc,
983  /* material: */ material);
984 
985  return lines_vertices_count/2;
986 }
987 
989 {
990  gl3::RenderParams params = {};
991  params.model_view.mtx = GetModelViewMtx();
992  params.projection.mtx = proj_mtx;
993  params.mesh_material = materials[light_mat_idx];
994  params.num_pt_lights = 0;
995  if (use_light)
996  {
997  if (light_mat_idx == 4)
998  {
999  for (int i = 0; i < 3; i++)
1000  {
1001  params.lights[i] = lights_4[i];
1002  }
1003  params.num_pt_lights = 3;
1004  }
1005  else
1006  {
1007  params.lights[0] = lights[light_mat_idx];
1008  params.num_pt_lights = 1;
1009  }
1010  }
1011  if (_use_cust_l0_pos)
1012  {
1013  params.lights[0].position = _l0_pos;
1014  }
1015  params.light_amb_scene = amb_setting[light_mat_idx];
1016  params.static_color = GetLineColor();
1017  return params;
1018 }
1019 
1021 {
1022  if (i < NUM_MATERIALS)
1023  {
1024  light_mat_idx = i;
1025  _use_cust_l0_pos = false;
1026  }
1027 }
1028 
1029 void VisualizationScene::SetLight0CustomPos(std::array<float, 4> pos)
1030 {
1031  _l0_pos = pos;
1032  _use_cust_l0_pos = true;
1033 }
1034 
1036 {
1037  if (background == BG_BLK)
1038  {
1039  background = BG_WHITE;
1040  GetAppWindow()->getRenderer().setClearColor(1.f, 1.f, 1.f, 1.f);
1041  }
1042  else
1043  {
1044  background = BG_BLK;
1045  GetAppWindow()->getRenderer().setClearColor(0.f, 0.f, 0.f, 1.f);
1046  }
1047 }
1048 
1049 void VisualizationScene::Rotate(double angle, double x, double y, double z)
1050 {
1051  gl3::GlMatrix rot_tmp;
1052  rot_tmp.identity();
1053  rot_tmp.mult(cam.TransposeRotMatrix());
1054  rot_tmp.rotate(angle, x, y, z);
1055  rot_tmp.mult(cam.RotMatrix());
1056  rot_tmp.mult(rotmat);
1057  rotmat = rot_tmp.mtx;
1058 }
1059 
1060 void VisualizationScene::PreRotate(double angle, double x, double y, double z)
1061 {
1062  rotmat = glm::rotate<float>(rotmat, glm::radians(angle), glm::vec3(x,y,z));
1063 }
1064 
1065 void VisualizationScene::Rotate(double angley, double anglex)
1066 {
1067  gl3::GlMatrix rot_tmp;
1068  rot_tmp.identity();
1069  rot_tmp.mult(cam.TransposeRotMatrix());
1070  rot_tmp.rotate(angley, 0.0, 1.0, 0.0);
1071  rot_tmp.rotate(anglex, 1.0, 0.0, 0.0);
1072  rot_tmp.mult(cam.RotMatrix());
1073  rot_tmp.mult(rotmat);
1074  rotmat = rot_tmp.mtx;
1075 
1076 }
1077 
1078 void VisualizationScene::Translate(double _x, double _y, double _z)
1079 {
1080  gl3::GlMatrix trans_tmp;
1081  trans_tmp.identity();
1082  trans_tmp.translate(_x, -_y, _z);
1083  trans_tmp.mult(translmat);
1084  translmat = trans_tmp.mtx;
1085 }
1086 
1088 {
1089  Scale (s, s, s);
1090 }
1091 
1092 void VisualizationScene::Scale(double s1, double s2, double s3)
1093 {
1094  xscale *= s1;
1095  yscale *= s2;
1096  zscale *= s3;
1097 }
1098 
1100 {
1101  gl3::GlMatrix tmp_mtx;
1102  tmp_mtx.identity();
1103  translmat = tmp_mtx.mtx;
1104  tmp_mtx.rotate(-60.f, 1.f, 0.f, 0.f);
1105  tmp_mtx.rotate(-40.f, 0.f, 0.f, 1.f);
1106  rotmat = tmp_mtx.mtx;
1107 }
1108 
1110 {
1111  translmat = glm::mat4(1.0);
1112  rotmat = glm::mat4(1.0);
1113 }
1114 
1115 void VisualizationScene::SetView(double theta, double phi)
1116 {
1117  gl3::GlMatrix tmp_mtx;
1118  tmp_mtx.identity();
1119  translmat = tmp_mtx.mtx;
1120  tmp_mtx.rotate(-theta, 1.f, 0.f, 0.f);
1121  tmp_mtx.rotate(-phi, 0.f, 0.f, 1.f);
1122  rotmat = tmp_mtx.mtx;
1123 }
1124 
1125 void VisualizationScene::Zoom(double factor)
1126 {
1127  if (OrthogonalProjection)
1128  {
1129  ViewScale *= factor;
1130  }
1131  else
1132  {
1133  double va = ViewAngle * ( M_PI / 360.0 );
1134  ViewAngle = atan( tan( va ) / factor ) * (360.0 / M_PI);
1135  }
1136 }
1137 
1139 {
1140  gl3::GlMatrix modelView;
1141  modelView.identity();
1142  modelView.mult(cam.TranslateMatrix());
1143  modelView.mult(translmat);
1144  modelView.mult(rotmat);
1145  modelView.scale(xscale, yscale, zscale);
1146  modelView.translate(-(bb.x[0]+bb.x[1])/2, -(bb.y[0]+bb.y[1])/2,
1147  -(bb.z[0]+bb.z[1])/2);
1148  return modelView.mtx;
1149 }
gl3::RenderParams GetMeshDrawParams()
Definition: openglvis.cpp:988
std::array< float, 3 > coord
Definition: types.hpp:205
int ProjectVector(double v[], const double n[])
Definition: geom_utils.hpp:141
void identity()
Sets the matrix to the identity matrix.
Definition: types.hpp:164
int AddTriangles(glTF_Builder &bld, glTF_Builder::mesh_id mesh, glTF_Builder::buffer_id buffer, glTF_Builder::material_id material, const gl3::GlDrawable &gl_drawable)
Definition: openglvis.cpp:583
void setClearColor(float r, float g, float b, float a)
Definition: renderer.hpp:260
void translate(double x, double y, double z)
Applies a translation transform to the matrix.
Definition: types.hpp:135
material_id addMaterial(const std::string &materialName, const pbr_matallic_roughness &pbrMetallicRoughness, bool doubleSided=false)
Definition: gltf.cpp:276
GlMatrix projection
Definition: renderer.hpp:41
void addNodeScale(node_id node, vec3f scale)
Definition: gltf.cpp:441
int Normalize(double v[])
Definition: geom_utils.hpp:38
accessor_id addAccessorVec3f(buffer_view_id bufferView, size_t byteOffset, size_t count, vec3f min, vec3f max)
Definition: gltf.cpp:165
buffer_view_id addBufferView(buffer_id buffer, const void *data, size_t byteLength, size_t byteStride, size_t byteAlign, target_type target)
Definition: gltf.cpp:38
virtual size_t count() const =0
Gets the number of vertices contained in the buffer.
static const int layout
Definition: types.hpp:227
void Set(const double cam[])
Definition: openglvis.cpp:37
sampler_id addSampler(mag_filter magFilter=mag_filter::NEAREST, min_filter minFilter=min_filter::NEAREST, wrap_type wrapS=wrap_type::CLAMP_TO_EDGE, wrap_type wrapT=wrap_type::CLAMP_TO_EDGE)
Definition: gltf.cpp:232
static const int layout
Definition: types.hpp:211
gl3::MeshRenderer & getRenderer()
Definition: sdl.hpp:226
int AddLines(glTF_Builder &bld, glTF_Builder::mesh_id mesh, glTF_Builder::buffer_id buffer, glTF_Builder::material_id material, const gl3::GlDrawable &gl_drawable)
Definition: openglvis.cpp:805
void glEnd()
Definition: types.hpp:309
void Translate(double x, double y, double z=0.0)
Definition: openglvis.cpp:1078
void Zoom(double factor)
Definition: openglvis.cpp:1125
void TiltLeftRight(double angle)
Definition: openglvis.cpp:46
static const int layout
Definition: types.hpp:235
void appendToBufferView(buffer_view_id bufferView, const void *data, size_t byteLength)
Definition: gltf.cpp:81
void addMeshLines(mesh_id mesh, accessor_id vertexPositions, accessor_id vertexTexcoords0, accessor_id vertexColors0, material_id material)
Definition: gltf.cpp:379
static const int layout
Definition: types.hpp:219
void glNormal3dv(const double *d)
Definition: types.hpp:407
void TurnUpDown(double angle)
Definition: openglvis.cpp:59
void addNodeTranslation(node_id node, vec3f translation)
Definition: gltf.cpp:449
void DrawPatch(gl3::GlDrawable &buff, const mfem::DenseMatrix &pts, mfem::Vector &vals, mfem::DenseMatrix &normals, const int n, const mfem::Array< int > &ind, const double minv, const double maxv, const int normals_opt=0)
Definition: openglvis.cpp:309
void addMeshTriangles(mesh_id mesh, accessor_id vertexPositions, accessor_id vertexNormals, accessor_id vertexTexCoords0, accessor_id vertexIndices, material_id material)
Definition: gltf.cpp:333
glTF_Builder::node_id AddModelNode(glTF_Builder &bld, const std::string &nodeName)
Definition: openglvis.cpp:535
std::array< float, 4 > light_amb_scene
Definition: renderer.hpp:47
std::array< float, 3 > coord
Definition: types.hpp:216
glm::mat4 TranslateMatrix()
Definition: openglvis.cpp:100
void glBegin(GLenum e)
Definition: types.hpp:295
int Compute3DUnitNormal(const double p1[], const double p2[], const double p3[], double nor[])
Definition: geom_utils.hpp:101
glTF_Builder::material_id AddBlackMaterial(glTF_Builder &bld)
Definition: openglvis.cpp:499
std::array< Light, LIGHTS_MAX > lights
Definition: renderer.hpp:46
texture_id addTexture(sampler_id sampler, image_id source)
Definition: gltf.cpp:256
void PreRotate(double angle, double x, double y, double z)
Definition: openglvis.cpp:1060
static bool useLegacyTextureFmts()
Definition: renderer.cpp:27
std::array< float, 3 > coord
Definition: types.hpp:232
glTF_Builder::material_id AddPaletteLinesMaterial(glTF_Builder &bld, glTF_Builder::material_id palette_mat)
Definition: openglvis.cpp:519
void glNormal3d(double nx, double ny, double nz)
Definition: types.hpp:401
std::array< float, 3 > coord
Definition: types.hpp:249
void DrawTriangle(gl3::GlDrawable &buff, const double(&pts)[4][3], const double(&cv)[4], const double minv, const double maxv)
Definition: openglvis.cpp:254
void SetLight0CustomPos(std::array< float, 4 > pos)
Definition: openglvis.cpp:1029
virtual ~VisualizationScene()
Definition: openglvis.cpp:141
void addTriangleIndexed(const std::vector< Vert > &verts, const std::vector< int > &inds)
Definition: types.hpp:704
std::array< float, 4 > amb_setting[]
Definition: material.cpp:56
GlBuilder createBuilder()
Definition: types.hpp:731
const int NUM_MATERIALS
Definition: openglvis.cpp:19
glm::mat4 mtx
Definition: types.hpp:121
void Print()
Definition: openglvis.cpp:106
virtual const void * getData() const =0
void SetView(double theta, double phi)
Definition: openglvis.cpp:1115
void scale(double x, double y, double z)
Applies a scale transform to the matrix.
Definition: types.hpp:141
virtual size_t getStride() const =0
Gets the stride between vertices.
void rotate(float angle, double x, double y, double z)
Applies a rotation transform to the matrix.
Definition: types.hpp:124
void Scale(double s)
Definition: openglvis.cpp:1087
node_id addNode(const std::string &nodeName)
Definition: gltf.cpp:422
image_id addImage(const std::string &imageName, int width, int height, const color4f *pixels)
Definition: gltf.cpp:190
std::array< float, 3 > coord
Definition: types.hpp:224
void SetLightMatIdx(unsigned i)
Definition: openglvis.cpp:1020
accessor_id addAccessor(buffer_view_id bufferView, size_t byteOffset, component_type componentType, size_t count, tensor_type tensorType)
Definition: gltf.cpp:97
SdlWindow * GetAppWindow()
Definition: aux_vis.cpp:58
Crude fixed-function OpenGL emulation helper.
Definition: types.hpp:261
glm::mat4 GetModelViewMtx()
Definition: openglvis.cpp:1138
void DrawQuad(gl3::GlDrawable &buff, const double(&pts)[4][3], const double(&cv)[4], const double minv, const double maxv)
Definition: openglvis.cpp:281
virtual const std::vector< int > & getIndices() const =0
void addQuadIndexed(const std::vector< Vert > &verts, const std::vector< int > &inds)
Definition: types.hpp:711
Light lights[]
Definition: material.cpp:48
glTF_Builder::material_id AddPaletteMaterial(glTF_Builder &bld)
Definition: openglvis.cpp:425
glm::mat4 TransposeRotMatrix()
Definition: openglvis.cpp:85
void getMaterialPBRMR(material_id material, pbr_matallic_roughness &pbr_mr_copy)
Definition: gltf.cpp:457
static constexpr unsigned INVALID_ID
Definition: gltf.hpp:218
Material materials[5]
Definition: material.cpp:14
void mult(glm::mat4 rhs)
Definition: types.hpp:129
static const int layout
Definition: types.hpp:253
Light lights_4[]
Definition: material.cpp:65
void addTriangle(const Vert &v1, const Vert &v2, const Vert &v3)
Definition: types.hpp:685
void DrawCutTriangle(gl3::GlDrawable &buff, const double(&pts)[4][3], const double(&cv)[4], const double minv, const double maxv)
Definition: openglvis.cpp:145
void glVertex3dv(const double *d)
Definition: types.hpp:396
void TurnLeftRight(double angle)
Definition: openglvis.cpp:52
void addQuad(const Vert &v1, const Vert &v2, const Vert &v3, const Vert &v4)
Definition: types.hpp:693
void LinearCombination(const double a, const double x[], const double b, const double y[], double z[])
Definition: geom_utils.hpp:18
std::array< float, 4 > static_color
Definition: renderer.hpp:48
GlMatrix model_view
Definition: renderer.hpp:40
Material mesh_material
Definition: renderer.hpp:44
accessor_id addAccessorVec2f(buffer_view_id bufferView, size_t byteOffset, size_t count, vec2f min, vec2f max)
Definition: gltf.cpp:140
void DrawCutQuad(gl3::GlDrawable &buff, const double(&pts)[4][3], const double(&cv)[4], const double minv, const double maxv)
Definition: openglvis.cpp:196
void minmax(const float *data, size_t components, size_t stride, size_t count, vector< float > &mins, vector< float > &maxs)
Definition: openglvis.cpp:553
glm::mat4 RotMatrix()
Definition: openglvis.cpp:69
void Rotate(double angle, double x, double y, double z)
Definition: openglvis.cpp:1049
void Reset()
Definition: openglvis.cpp:25