Explorar o código

map texture in new opengl glfw nested dependency

Former-commit-id: 575be3e5844de1a31edaf2704bc994d5ff26d2c9
Alec Jacobson %!s(int64=8) %!d(string=hai) anos
pai
achega
a82c85910f
Modificáronse 2 ficheiros con 223 adicións e 0 borrados
  1. 177 0
      include/igl/opengl/glfw/map_texture.cpp
  2. 46 0
      include/igl/opengl/glfw/map_texture.h

+ 177 - 0
include/igl/opengl/glfw/map_texture.cpp

@@ -0,0 +1,177 @@
+#include "map_texture.h"
+#include "../create_shader_program.h"
+// Hopefully OpenGL/gl.h hasn't been included already
+#include <OpenGL/gl3.h>
+#define __gl_h_
+
+#define GLFW_INCLUDE_GLU
+#include <GLFW/glfw3.h>
+
+#include <iostream>
+#include <string>
+  
+template <typename DerivedV, typename DerivedF, typename DerivedU>
+IGL_INLINE bool igl::opengl::glfw::map_texture(
+  const Eigen::MatrixBase<DerivedV> & _V,
+  const Eigen::MatrixBase<DerivedF> & _F,
+  const Eigen::MatrixBase<DerivedU> & _U,
+  const unsigned char * in_data,
+  const int w,
+  const int h,
+  const int nc,
+  std::vector<unsigned char> & out_data)
+{
+  const auto fail = [](const std::string msg)
+  {
+    std::cerr<<msg<<std::endl;
+    glfwTerminate();
+    return false;
+  };
+  // Force inputs to be RowMajor at the cost of a copy 
+  Eigen::Matrix<
+    double,
+    DerivedV::RowsAtCompileTime,
+    DerivedV::ColsAtCompileTime,
+    Eigen::RowMajor> V = _V.template cast<double>();
+  Eigen::Matrix<
+    double,
+    DerivedU::RowsAtCompileTime,
+    DerivedU::ColsAtCompileTime,
+    Eigen::RowMajor> U = _U.template cast<double>();
+  Eigen::Matrix<
+    int,
+    DerivedF::RowsAtCompileTime,
+    DerivedF::ColsAtCompileTime,
+    Eigen::RowMajor> F = _F.template cast<int>();
+  // Set up glfw
+  if(!glfwInit()) fail("Could not initialize glfw");
+  glfwSetErrorCallback([](int id,const char* m){std::cerr<<m<<std::endl;});
+  glfwWindowHint(GLFW_SAMPLES, 4);
+  glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
+  glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
+  glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
+  glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
+  glfwWindowHint(GLFW_VISIBLE, GL_FALSE);
+  GLFWwindow* window = glfwCreateWindow(1, 1,"", NULL, NULL);
+  if(!window) fail("Could not create glfw window");
+  glfwMakeContextCurrent(window);
+  // Compile each shader
+  std::string vertex_shader = R"(
+#version 330 core
+layout(location = 0) in vec2 position;
+layout(location = 1) in vec2 tex_coord_v;
+out vec2 tex_coord_f;
+void main()
+{
+  tex_coord_f = vec2(tex_coord_v.x,1.-tex_coord_v.y);
+  gl_Position = vec4( 2.*position.x-1., 2.*(1.-position.y)-1., 0.,1.);
+}
+)";
+  std::string fragment_shader = R"(
+#version 330 core
+layout(location = 0) out vec3 color;
+uniform sampler2D tex;
+in vec2 tex_coord_f;
+void main()
+{
+  color = texture(tex,tex_coord_f).rgb;
+}
+)";
+  GLuint prog_id = 
+    igl::opengl::create_shader_program(vertex_shader,fragment_shader,{});
+  glUniform1i(glGetUniformLocation(prog_id, "tex"),0);
+  // Generate and attach buffers to vertex array
+  glDisable(GL_CULL_FACE);
+  GLuint VAO = 0;
+  glGenVertexArrays(1,&VAO);
+  glBindVertexArray(VAO);
+  GLuint ibo,vbo,tbo;
+  glGenBuffers(1,&ibo);
+  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
+  glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint)*F.size(), F.data(), GL_STATIC_DRAW);
+  glGenBuffers(1,&vbo);
+  glEnableVertexAttribArray(0);
+  glBindBuffer(GL_ARRAY_BUFFER,vbo);
+  glBufferData(GL_ARRAY_BUFFER, sizeof(double)*U.size(), U.data(), GL_STATIC_DRAW);
+  glVertexAttribLPointer(0, U.cols(), GL_DOUBLE, V.cols() * sizeof(GLdouble), (GLvoid*)0);
+  glGenBuffers(1,&tbo);
+  glEnableVertexAttribArray(1);
+  glBindBuffer(GL_ARRAY_BUFFER,tbo);
+  glBufferData(GL_ARRAY_BUFFER, sizeof(double)*V.size(), V.data(), GL_STATIC_DRAW);
+  glVertexAttribLPointer(1, V.cols(), GL_DOUBLE, V.cols() * sizeof(GLdouble), (GLvoid*)0);
+  glBindVertexArray(0);
+  glBindBuffer(GL_ARRAY_BUFFER, 0); 
+  glBindVertexArray(0);
+  // Prepare texture
+  GLuint in_tex;
+  GLenum format;
+  {
+    format = nc==1 ? GL_RED : (nc==3 ? GL_RGB : (nc == 4 ? GL_RGBA : GL_FALSE));
+    glGenTextures(1, &in_tex);
+    glBindTexture(GL_TEXTURE_2D, in_tex);
+    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_MAG_FILTER, GL_LINEAR);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+    glTexImage2D(GL_TEXTURE_2D, 0,GL_RGB, w, h, 0,format, GL_UNSIGNED_BYTE, in_data);
+  }
+  // Prepare framebuffer
+  GLuint fb = 0;
+  glGenFramebuffers(1, &fb);
+  glBindFramebuffer(GL_FRAMEBUFFER, fb);
+  GLuint out_tex;
+  glGenTextures(1, &out_tex);
+  glBindTexture(GL_TEXTURE_2D, out_tex);
+  // always use float for internal storage
+  glTexImage2D(GL_TEXTURE_2D, 0,GL_RGB, w, h, 0,GL_RGB, GL_FLOAT, 0);
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+  glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, out_tex, 0);
+  {
+    GLenum bufs[1] = {GL_COLOR_ATTACHMENT0};
+    glDrawBuffers(1, bufs);
+  }
+  if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) 
+  {
+    fail("framebuffer setup failed.");
+  }
+  glBindFramebuffer(GL_FRAMEBUFFER, fb);
+  // clear screen and set viewport
+  glClearColor(0.0,1.0,0.0,0.);
+  glClear(GL_COLOR_BUFFER_BIT);
+  glViewport(0,0,w,h);
+  // Attach shader program
+  glUseProgram(prog_id);
+  glActiveTexture(GL_TEXTURE0 + 0);
+  glBindTexture(GL_TEXTURE_2D, in_tex);
+  // Draw mesh as wireframe
+  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+  glBindVertexArray(VAO);
+  glDrawElements(GL_TRIANGLES, F.size(), GL_UNSIGNED_INT, 0);
+  glBindVertexArray(0);
+  // Write into memory
+  out_data.resize(nc*w*h);
+  glBindTexture(GL_TEXTURE_2D, out_tex);
+  glGetTexImage(GL_TEXTURE_2D, 0, format, GL_UNSIGNED_BYTE, &out_data[0]);
+  // OpenGL cleanup
+  glDeleteBuffers(1,&fb);
+  glDeleteBuffers(1,&ibo);
+  glDeleteBuffers(1,&vbo);
+  glDeleteBuffers(1,&tbo);
+  glDeleteTextures(1,&in_tex);
+  glDeleteTextures(1,&out_tex);
+  glDeleteVertexArrays(1,&VAO);
+  glUseProgram(0);
+  glDeleteProgram(prog_id);
+  // GLFW cleanup
+  glfwDestroyWindow(window);
+  glfwTerminate();
+  return true;
+}
+
+#ifdef IGL_STATIC_LIBRARY
+// Explicit template instantiation
+// generated by autoexplicit.sh
+template bool igl::opengl::glfw::map_texture<Eigen::Matrix<double, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<double, -1, -1, 1, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 1, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 1, -1, -1> > const&, unsigned char const*, int, int, int, std::vector<unsigned char, std::allocator<unsigned char> >&);
+#endif

+ 46 - 0
include/igl/opengl/glfw/map_texture.h

@@ -0,0 +1,46 @@
+#ifndef IGL_OPENGL_GLFW_MAP_TEXTURE_H
+#define IGL_OPENGL_GLFW_MAP_TEXTURE_H
+
+#include "../../igl_inline.h"
+#include <Eigen/Core>
+#include <vector>
+
+namespace igl
+{
+  namespace opengl
+  {
+    namespace glfw
+    {
+      // Given a mesh (V,F) in [0,1]² and new positions (U) and a texture image
+      // (in_data), _render_ a new image (out_data) of the same size.
+      // Inputs:
+      //   V  #V by 2 list of undeformed mesh vertex positions (matching texture)
+      //   F  #F by 3 list of mesh triangle indices into V
+      //   U  #U by 2 list of deformed vertex positions
+      //   in_data  w*h*nc array of color values, channels, then columns, then
+      //     rows (e.g., what stbi_image returns and expects)
+      //   w  width
+      //   h  height
+      //   nc  number of channels
+      // Outputs:
+      //   out_data  h*w*nc list of output colors in same order as input
+      //
+      template <typename DerivedV, typename DerivedF, typename DerivedU>
+      IGL_INLINE bool map_texture(
+        const Eigen::MatrixBase<DerivedV> & V,
+        const Eigen::MatrixBase<DerivedF> & F,
+        const Eigen::MatrixBase<DerivedU> & U,
+        const unsigned char * in_data,
+        const int w,
+        const int h,
+        const int nc,
+        std::vector<unsigned char> & out_data);
+    }
+  }
+}
+
+#ifndef IGL_STATIC_LIBRARY
+#  include "map_texture.cpp"
+#endif
+
+#endif