Browse Source

set data rather than custom shader

Alec Jacobson 6 years ago
parent
commit
37b087a275

+ 7 - 2
include/igl/opengl/MeshGL.cpp

@@ -12,6 +12,11 @@
 #include "destroy_shader_program.h"
 #include <iostream>
 
+IGL_INLINE igl::opengl::MeshGL::MeshGL():
+  tex_filter(GL_LINEAR)
+{
+}
+
 IGL_INLINE void igl::opengl::MeshGL::init_buffers()
 {
   // Mesh: Vertex Array Object & Buffer objects
@@ -90,8 +95,8 @@ IGL_INLINE void igl::opengl::MeshGL::bind_mesh()
   {
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, tex_filter);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, tex_filter);
     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex_u, tex_v, 0, GL_RGBA, GL_UNSIGNED_BYTE, tex.data());
   }

+ 4 - 0
include/igl/opengl/MeshGL.h

@@ -24,6 +24,7 @@ class MeshGL
 {
 public:
   typedef unsigned int GLuint;
+  typedef unsigned int GLint;
 
   enum DirtyFlags
   {
@@ -82,6 +83,7 @@ public:
 
   int tex_u;
   int tex_v;
+  GLint tex_filter;
   Eigen::Matrix<char,Eigen::Dynamic,1> tex;
 
   Eigen::Matrix<unsigned, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> F_vbo;
@@ -91,6 +93,8 @@ public:
   // Marks dirty buffers that need to be uploaded to OpenGL
   uint32_t dirty;
 
+  IGL_INLINE MeshGL();
+
   // Initialize shaders and buffers
   IGL_INLINE void init();
 

+ 24 - 0
include/igl/opengl/ViewerData.cpp

@@ -14,6 +14,9 @@
 #include "../parula.h"
 #include "../per_vertex_normals.h"
 
+// Really? Just for GL_NEAREST?
+#include "gl.h"
+
 #include <iostream>
 
 
@@ -260,6 +263,27 @@ IGL_INLINE void igl::opengl::ViewerData::set_texture(
   dirty |= MeshGL::DIRTY_TEXTURE;
 }
 
+IGL_INLINE void igl::opengl::ViewerData::set_data(const Eigen::VectorXd & D)
+{
+  set_uv((D/D.maxCoeff()).replicate(1,2));
+}
+
+IGL_INLINE void igl::opengl::ViewerData::set_colormap(const Eigen::MatrixXd & CM)
+{
+  assert(CM.cols() == 3 && "colormap CM should have 3 columns");
+  // Convert to R,G,B textures
+  const Eigen::Matrix<unsigned char,Eigen::Dynamic, Eigen::Dynamic> R =
+    (CM.col(0)*255.0).cast<unsigned char>();
+  const Eigen::Matrix<unsigned char,Eigen::Dynamic, Eigen::Dynamic> G =
+    (CM.col(1)*255.0).cast<unsigned char>();
+  const Eigen::Matrix<unsigned char,Eigen::Dynamic, Eigen::Dynamic> B = 
+    (CM.col(2)*255.0).cast<unsigned char>();
+  set_colors(Eigen::RowVector3d(1,1,1));
+  set_texture(R,G,B);
+  show_texture = true;
+  meshgl.tex_filter = GL_NEAREST;
+}
+
 IGL_INLINE void igl::opengl::ViewerData::set_points(
   const Eigen::MatrixXd& P,
   const Eigen::MatrixXd& C)

+ 12 - 1
include/igl/opengl/ViewerData.h

@@ -82,7 +82,6 @@ public:
     const Eigen::Matrix<unsigned char,Eigen::Dynamic,Eigen::Dynamic>& R,
     const Eigen::Matrix<unsigned char,Eigen::Dynamic,Eigen::Dynamic>& G,
     const Eigen::Matrix<unsigned char,Eigen::Dynamic,Eigen::Dynamic>& B);
-
   // Set the texture associated with the mesh.
   //
   // Inputs:
@@ -96,6 +95,18 @@ public:
     const Eigen::Matrix<unsigned char,Eigen::Dynamic,Eigen::Dynamic>& G,
     const Eigen::Matrix<unsigned char,Eigen::Dynamic,Eigen::Dynamic>& B,
     const Eigen::Matrix<unsigned char,Eigen::Dynamic,Eigen::Dynamic>& A);
+  // Set pseudo-colorable scalar data associated with the mesh.
+  //
+  // Inputs:
+  //   D  #V by 3 list of colors
+  // To-do: support #F by 1 per-face data
+  IGL_INLINE void set_data(const Eigen::VectorXd & D);
+  // Not to be confused with set_colors, this creates a _texture_ that will be
+  // referenced to pseudocolor accordint to the scalar field passed to set_data.
+  //
+  // Inputs:
+  //   CM  #CM by 3 list of colors
+  IGL_INLINE void set_colormap(const Eigen::MatrixXd & CM);
 
   // Sets points given a list of point vertices. In constrast to `add_points`
   // this will (purposefully) clober existing points.

+ 19 - 103
tutorial/716_HeatGeodesics/main.cpp

@@ -9,6 +9,21 @@
 #include <igl/opengl/destroy_shader_program.h>
 #include <iostream>
 
+void set_colormap(igl::opengl::glfw::Viewer & viewer)
+{
+  const int num_intervals = 30;
+  Eigen::MatrixXd CM(num_intervals,3);
+  // Colormap texture
+  for(int i = 0;i<num_intervals;i++)
+  {
+    double t = double(num_intervals - i - 1)/double(num_intervals-1);
+    CM(i,0) = std::max(std::min(2.0*t-0.0,1.0),0.0);
+    CM(i,1) = std::max(std::min(2.0*t-1.0,1.0),0.0);
+    CM(i,2) = std::max(std::min(6.0*t-5.0,1.0),0.0);
+  }
+  viewer.data().set_colormap(CM);
+}
+
 int main(int argc, char *argv[])
 {
   // Create the peak height field
@@ -29,8 +44,6 @@ int main(int argc, char *argv[])
   };
   precompute();
 
-  // Initialize white
-  Eigen::MatrixXd C = Eigen::MatrixXd::Constant(V.rows(),3,1);
   igl::opengl::glfw::Viewer viewer;
   bool down_on_mesh = false;
   const auto update = [&]()->bool
@@ -56,7 +69,7 @@ int main(int argc, char *argv[])
       Eigen::VectorXd D = Eigen::VectorXd::Zero(data.Grad.cols());
 	  D(vid) = 1;
       igl::heat_geodesics_solve(data,(Eigen::VectorXi(1,1)<<vid).finished(),D);
-      viewer.data().set_colors((D/D.maxCoeff()).replicate(1,3));
+      viewer.data().set_data(D);
       return true;
     }
     return false;
@@ -122,106 +135,9 @@ int main(int argc, char *argv[])
 
   // Show mesh
   viewer.data().set_mesh(V, F);
-  viewer.data().set_colors(C);
+  viewer.data().set_data(Eigen::VectorXd::Zero(V.rows()));
+  set_colormap(viewer);
   viewer.data().show_lines = false;
-  viewer.launch_init(true,false);
-
-  viewer.data().meshgl.init();
-  igl::opengl::destroy_shader_program(viewer.data().meshgl.shader_mesh);
-
-  {
-    std::string mesh_vertex_shader_string =
-R"(#version 150
-uniform mat4 view;
-uniform mat4 proj;
-uniform mat4 normal_matrix;
-in vec3 position;
-in vec3 normal;
-out vec3 position_eye;
-out vec3 normal_eye;
-in vec4 Ka;
-in vec4 Kd;
-in vec4 Ks;
-in vec2 texcoord;
-out vec2 texcoordi;
-out vec4 Kai;
-out vec4 Kdi;
-out vec4 Ksi;
-
-void main()
-{
-  position_eye = vec3 (view * vec4 (position, 1.0));
-  normal_eye = vec3 (normal_matrix * vec4 (normal, 0.0));
-  normal_eye = normalize(normal_eye);
-  gl_Position = proj * vec4 (position_eye, 1.0); //proj * view * vec4(position, 1.0);
-  Kai = Ka;
-  Kdi = Kd;
-  Ksi = Ks;
-  texcoordi = texcoord;
-})";
-
-    std::string mesh_fragment_shader_string =
-R"(#version 150
-uniform mat4 view;
-uniform mat4 proj;
-uniform vec4 fixed_color;
-in vec3 position_eye;
-in vec3 normal_eye;
-uniform vec3 light_position_eye;
-vec3 Ls = vec3 (1, 1, 1);
-vec3 Ld = vec3 (1, 1, 1);
-vec3 La = vec3 (1, 1, 1);
-in vec4 Ksi;
-in vec4 Kdi;
-in vec4 Kai;
-in vec2 texcoordi;
-uniform sampler2D tex;
-uniform float specular_exponent;
-uniform float lighting_factor;
-uniform float texture_factor;
-out vec4 outColor;
-void main()
-{
-vec3 Ia = La * vec3(Kai);    // ambient intensity
-float ni = 30.0; // number of intervals
-float t = 1.0-round(ni*Kdi.r)/ni; // quantize and reverse
-vec3 Kdiq = clamp(vec3(2.*t,2.*t-1.,6.*t-5.),0,1); // heat map
-
-vec3 vector_to_light_eye = light_position_eye - position_eye;
-vec3 direction_to_light_eye = normalize (vector_to_light_eye);
-float dot_prod = dot (direction_to_light_eye, normalize(normal_eye));
-float clamped_dot_prod = max (dot_prod, 0.0);
-vec3 Id = Ld * Kdiq * clamped_dot_prod;    // Diffuse intensity
-
-vec3 reflection_eye = reflect (-direction_to_light_eye, normalize(normal_eye));
-vec3 surface_to_viewer_eye = normalize (-position_eye);
-float dot_prod_specular = dot (reflection_eye, surface_to_viewer_eye);
-dot_prod_specular = float(abs(dot_prod)==dot_prod) * max (dot_prod_specular, 0.0);
-float specular_factor = pow (dot_prod_specular, specular_exponent);
-vec3 Kfi = 0.5*vec3(Ksi);
-vec3 Lf = Ls;
-float fresnel_exponent = 2*specular_exponent;
-float fresnel_factor = 0;
-{
-  float NE = max( 0., dot( normalize(normal_eye), surface_to_viewer_eye));
-  fresnel_factor = pow (max(sqrt(1. - NE*NE),0.0), fresnel_exponent);
-}
-vec3 Is = Ls * vec3(Ksi) * specular_factor;    // specular intensity
-vec3 If = Lf * vec3(Kfi) * fresnel_factor;     // fresnel intensity
-vec4 color = vec4(lighting_factor * (If + Is + Id) + Ia +
-  (1.0-lighting_factor) * Kdiq,(Kai.a+Ksi.a+Kdi.a)/3);
-outColor = mix(vec4(1,1,1,1), texture(tex, texcoordi), texture_factor) * color;
-if (fixed_color != vec4(0.0)) outColor = fixed_color;
-})";
-
-    igl::opengl::create_shader_program(
-      mesh_vertex_shader_string,
-      mesh_fragment_shader_string,
-      {},
-      viewer.data().meshgl.shader_mesh);
-  }
-
-  viewer.launch_rendering(true);
-  viewer.launch_shut();
+  viewer.launch();
 
 }