|
@@ -1,8 +1,7 @@
|
|
|
-#ifdef IGL_OPENGL_4
|
|
|
|
|
-
|
|
|
|
|
#include "map_texture.h"
|
|
#include "map_texture.h"
|
|
|
#include "background_window.h"
|
|
#include "background_window.h"
|
|
|
#include "../create_shader_program.h"
|
|
#include "../create_shader_program.h"
|
|
|
|
|
+#include "../bind_vertex_attrib_array.h"
|
|
|
|
|
|
|
|
#include "../gl.h"
|
|
#include "../gl.h"
|
|
|
#include <GLFW/glfw3.h>
|
|
#include <GLFW/glfw3.h>
|
|
@@ -30,75 +29,45 @@ IGL_INLINE bool igl::opengl::glfw::map_texture(
|
|
|
|
|
|
|
|
template <typename DerivedV, typename DerivedF, typename DerivedU>
|
|
template <typename DerivedV, typename DerivedF, typename DerivedU>
|
|
|
IGL_INLINE bool igl::opengl::glfw::map_texture(
|
|
IGL_INLINE bool igl::opengl::glfw::map_texture(
|
|
|
- const Eigen::MatrixBase<DerivedV> & _V,
|
|
|
|
|
- const Eigen::MatrixBase<DerivedF> & _F,
|
|
|
|
|
- const Eigen::MatrixBase<DerivedU> & _U,
|
|
|
|
|
|
|
+ const Eigen::MatrixBase<DerivedV> & V,
|
|
|
|
|
+ const Eigen::MatrixBase<DerivedF> & F,
|
|
|
|
|
+ const Eigen::MatrixBase<DerivedU> & U,
|
|
|
const unsigned char * in_data,
|
|
const unsigned char * in_data,
|
|
|
- const int w,
|
|
|
|
|
- const int h,
|
|
|
|
|
- const int nc,
|
|
|
|
|
|
|
+ const int in_w,
|
|
|
|
|
+ const int in_h,
|
|
|
|
|
+ const int in_nc,
|
|
|
std::vector<unsigned char> & out_data,
|
|
std::vector<unsigned char> & out_data,
|
|
|
int & out_w,
|
|
int & out_w,
|
|
|
int & out_h,
|
|
int & out_h,
|
|
|
int & out_nc)
|
|
int & out_nc)
|
|
|
{
|
|
{
|
|
|
- const auto fail = [](const std::string msg)
|
|
|
|
|
|
|
+ GLenum format = -1;
|
|
|
|
|
+ switch(in_nc)
|
|
|
{
|
|
{
|
|
|
- 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>();
|
|
|
|
|
- const int dim = U.cols();
|
|
|
|
|
- GLFWwindow * window;
|
|
|
|
|
- if(!background_window(window))
|
|
|
|
|
- {
|
|
|
|
|
- fail("Could not initialize glfw window");
|
|
|
|
|
|
|
+ case 1: format = GL_RED; break;
|
|
|
|
|
+ case 2: format = GL_RG; break;
|
|
|
|
|
+ case 3: format = GL_RGB; break;
|
|
|
|
|
+ case 4: format = GL_RGBA; break;
|
|
|
|
|
+ default: assert(false && "Unsupported number of channels"); break;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ GLFWwindow * window = nullptr;
|
|
|
|
|
+ igl::opengl::glfw::background_window(window);
|
|
|
// Compile each shader
|
|
// Compile each shader
|
|
|
- std::string vertex_shader = dim == 2 ?
|
|
|
|
|
- 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.);
|
|
|
|
|
-}
|
|
|
|
|
-)"
|
|
|
|
|
- :
|
|
|
|
|
- R"(
|
|
|
|
|
-#version 330 core
|
|
|
|
|
|
|
+ std::string vertex_shader = R"(
|
|
|
|
|
+#version 400
|
|
|
layout(location = 0) in vec3 position;
|
|
layout(location = 0) in vec3 position;
|
|
|
layout(location = 1) in vec2 tex_coord_v;
|
|
layout(location = 1) in vec2 tex_coord_v;
|
|
|
out vec2 tex_coord_f;
|
|
out vec2 tex_coord_f;
|
|
|
void main()
|
|
void main()
|
|
|
{
|
|
{
|
|
|
tex_coord_f = vec2(tex_coord_v.x,1.-tex_coord_v.y);
|
|
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., position.z,1.);
|
|
|
|
|
|
|
+ gl_Position = vec4(2.*position.x-1.,2.*(1.-position.y)-1., position.z,1.);
|
|
|
}
|
|
}
|
|
|
)"
|
|
)"
|
|
|
;
|
|
;
|
|
|
std::string fragment_shader = R"(
|
|
std::string fragment_shader = R"(
|
|
|
-#version 330 core
|
|
|
|
|
|
|
+#version 400
|
|
|
layout(location = 0) out vec3 color;
|
|
layout(location = 0) out vec3 color;
|
|
|
uniform sampler2D tex;
|
|
uniform sampler2D tex;
|
|
|
in vec2 tex_coord_f;
|
|
in vec2 tex_coord_f;
|
|
@@ -109,53 +78,44 @@ void main()
|
|
|
)";
|
|
)";
|
|
|
GLuint prog_id =
|
|
GLuint prog_id =
|
|
|
igl::opengl::create_shader_program(vertex_shader,fragment_shader,{});
|
|
igl::opengl::create_shader_program(vertex_shader,fragment_shader,{});
|
|
|
- glUniform1i(glGetUniformLocation(prog_id, "tex"),0);
|
|
|
|
|
|
|
+
|
|
|
|
|
+ using Scalar = float;
|
|
|
|
|
+ using MatrixXS3 = Eigen::Matrix<Scalar,Eigen::Dynamic,3,Eigen::RowMajor>;
|
|
|
|
|
+ MatrixXS3 V_vbo = MatrixXS3::Zero(V.rows(),3);
|
|
|
|
|
+ V_vbo.leftCols(V.cols()) = V.template cast<Scalar>();
|
|
|
|
|
+ MatrixXS3 U_vbo = MatrixXS3::Zero(U.rows(),3);
|
|
|
|
|
+ U_vbo.leftCols(U.cols()) = U.template cast<Scalar>();
|
|
|
|
|
+ Eigen::Matrix<unsigned, Eigen::Dynamic, 3, Eigen::RowMajor> F_vbo =
|
|
|
|
|
+ F.template cast<unsigned>();
|
|
|
|
|
+
|
|
|
// Generate and attach buffers to vertex array
|
|
// Generate and attach buffers to vertex array
|
|
|
glDisable(GL_CULL_FACE);
|
|
glDisable(GL_CULL_FACE);
|
|
|
GLuint VAO = 0;
|
|
GLuint VAO = 0;
|
|
|
glGenVertexArrays(1,&VAO);
|
|
glGenVertexArrays(1,&VAO);
|
|
|
glBindVertexArray(VAO);
|
|
glBindVertexArray(VAO);
|
|
|
- GLuint ibo,vbo,tbo;
|
|
|
|
|
|
|
+ GLuint ibo,vbo,tbo,tex;
|
|
|
glGenBuffers(1,&ibo);
|
|
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);
|
|
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, U.cols() * sizeof(GLdouble), (GLvoid*)0);
|
|
|
|
|
glGenBuffers(1,&tbo);
|
|
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);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ glGenTextures(1,&tex);
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ out_w = in_w;
|
|
|
|
|
+ out_h = in_h;
|
|
|
|
|
+ glClearColor(0,0,1,1);
|
|
|
|
|
+ glClear(GL_COLOR_BUFFER_BIT);
|
|
|
|
|
+ glViewport(0,0,out_w,out_h);
|
|
|
|
|
+
|
|
|
// Prepare framebuffer
|
|
// Prepare framebuffer
|
|
|
GLuint fb = 0;
|
|
GLuint fb = 0;
|
|
|
|
|
+ GLuint out_tex;
|
|
|
|
|
+
|
|
|
glGenFramebuffers(1, &fb);
|
|
glGenFramebuffers(1, &fb);
|
|
|
glBindFramebuffer(GL_FRAMEBUFFER, fb);
|
|
glBindFramebuffer(GL_FRAMEBUFFER, fb);
|
|
|
- GLuint out_tex;
|
|
|
|
|
glGenTextures(1, &out_tex);
|
|
glGenTextures(1, &out_tex);
|
|
|
glBindTexture(GL_TEXTURE_2D, out_tex);
|
|
glBindTexture(GL_TEXTURE_2D, out_tex);
|
|
|
// always use float for internal storage
|
|
// always use float for internal storage
|
|
|
- assert(out_nc == 3);
|
|
|
|
|
- glTexImage2D(GL_TEXTURE_2D, 0,GL_RGB, out_w, out_h, 0,GL_RGB, GL_FLOAT, 0);
|
|
|
|
|
|
|
+ glTexImage2D(GL_TEXTURE_2D, 0,format, out_w, out_h, 0,format, GL_FLOAT, 0);
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
|
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, out_tex, 0);
|
|
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, out_tex, 0);
|
|
@@ -165,40 +125,39 @@ void main()
|
|
|
}
|
|
}
|
|
|
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
|
|
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
|
|
|
{
|
|
{
|
|
|
- fail("framebuffer setup failed.");
|
|
|
|
|
|
|
+ glfwTerminate();
|
|
|
|
|
+ return false;
|
|
|
}
|
|
}
|
|
|
glBindFramebuffer(GL_FRAMEBUFFER, fb);
|
|
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,out_w,out_h);
|
|
|
|
|
- // Attach shader program
|
|
|
|
|
|
|
+
|
|
|
glUseProgram(prog_id);
|
|
glUseProgram(prog_id);
|
|
|
- glActiveTexture(GL_TEXTURE0 + 0);
|
|
|
|
|
- glBindTexture(GL_TEXTURE_2D, in_tex);
|
|
|
|
|
- // Draw mesh as wireframe
|
|
|
|
|
|
|
+
|
|
|
|
|
+ glActiveTexture(GL_TEXTURE0);
|
|
|
|
|
+ glBindTexture(GL_TEXTURE_2D, 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_MIN_FILTER, GL_LINEAR);
|
|
|
|
|
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
|
|
|
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
|
|
|
|
+ glTexImage2D(GL_TEXTURE_2D, 0, format, in_w, in_h, 0, format, GL_UNSIGNED_BYTE, in_data);
|
|
|
|
|
+ glUniform1i(glGetUniformLocation(prog_id,"tex"), 0);
|
|
|
|
|
+
|
|
|
|
|
+ igl::opengl::bind_vertex_attrib_array(prog_id,"position", vbo, U_vbo, true);
|
|
|
|
|
+ igl::opengl::bind_vertex_attrib_array(prog_id,"tex_coord_v", tbo, V_vbo, true);
|
|
|
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
|
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
|
|
glBindVertexArray(VAO);
|
|
glBindVertexArray(VAO);
|
|
|
|
|
+
|
|
|
|
|
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
|
|
|
|
|
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned)*F_vbo.size(), F_vbo.data(), GL_DYNAMIC_DRAW);
|
|
|
glDrawElements(GL_TRIANGLES, F.size(), GL_UNSIGNED_INT, 0);
|
|
glDrawElements(GL_TRIANGLES, F.size(), GL_UNSIGNED_INT, 0);
|
|
|
- glBindVertexArray(0);
|
|
|
|
|
- // Write into memory
|
|
|
|
|
- assert(out_nc == 3);
|
|
|
|
|
|
|
+
|
|
|
|
|
+ out_nc = in_nc;
|
|
|
out_data.resize(out_nc*out_w*out_h);
|
|
out_data.resize(out_nc*out_w*out_h);
|
|
|
glBindTexture(GL_TEXTURE_2D, out_tex);
|
|
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
|
|
|
|
|
|
|
+ glGetTexImage(GL_TEXTURE_2D, 0, format, GL_UNSIGNED_BYTE, out_data.data());
|
|
|
glfwDestroyWindow(window);
|
|
glfwDestroyWindow(window);
|
|
|
glfwTerminate();
|
|
glfwTerminate();
|
|
|
|
|
+
|
|
|
return true;
|
|
return true;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -206,6 +165,5 @@ void main()
|
|
|
// Explicit template instantiation
|
|
// Explicit template instantiation
|
|
|
// generated by autoexplicit.sh
|
|
// 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> >&);
|
|
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> >&);
|
|
|
|
|
+template bool igl::opengl::glfw::map_texture<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, unsigned char const*, int, int, int, std::vector<unsigned char, std::allocator<unsigned char> >&, int&, int&, int&);
|
|
|
#endif
|
|
#endif
|
|
|
-
|
|
|
|
|
-#endif // IGL_OPENGL_4
|
|
|