Thanks to visit codestin.com
Credit goes to glvis.github.io

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