OpenGL_shader.cpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2014 Wenzel Jacob <wenzel@inf.ethz.ch>
  4. //
  5. // This Source Code Form is subject to the terms of the Mozilla Public License
  6. // v. 2.0. If a copy of the MPL was not distributed with this file, You can
  7. // obtain one at http://mozilla.org/MPL/2.0/.
  8. #include "OpenGL_shader.h"
  9. #ifdef __APPLE__
  10. # include <OpenGL/gl3.h>
  11. # define __gl_h_ /* Prevent inclusion of the old gl.h */
  12. #else
  13. # ifdef _WIN32
  14. # include <windows.h>
  15. # endif
  16. # include <GL/gl.h>
  17. #endif
  18. #include <iostream>
  19. #include <fstream>
  20. IGL_INLINE bool igl::OpenGL_shader::init_from_files(
  21. const std::string &vertex_shader_filename,
  22. const std::string &fragment_shader_filename,
  23. const std::string &fragment_data_name,
  24. const std::string &geometry_shader_filename,
  25. int geometry_shader_max_vertices)
  26. {
  27. auto file_to_string = [](const std::string &filename)
  28. {
  29. std::ifstream t(filename);
  30. return std::string((std::istreambuf_iterator<char>(t)),
  31. std::istreambuf_iterator<char>());
  32. };
  33. return init(
  34. file_to_string(vertex_shader_filename),
  35. file_to_string(fragment_shader_filename),
  36. fragment_data_name,
  37. file_to_string(geometry_shader_filename),
  38. geometry_shader_max_vertices
  39. );
  40. }
  41. IGL_INLINE bool igl::OpenGL_shader::init(
  42. const std::string &vertex_shader_string,
  43. const std::string &fragment_shader_string,
  44. const std::string &fragment_data_name,
  45. const std::string &geometry_shader_string,
  46. int geometry_shader_max_vertices)
  47. {
  48. using namespace std;
  49. vertex_shader = create_shader_helper(GL_VERTEX_SHADER, vertex_shader_string);
  50. geometry_shader = create_shader_helper(GL_GEOMETRY_SHADER, geometry_shader_string);
  51. fragment_shader = create_shader_helper(GL_FRAGMENT_SHADER, fragment_shader_string);
  52. if (!vertex_shader || !fragment_shader)
  53. return false;
  54. program_shader = glCreateProgram();
  55. glAttachShader(program_shader, vertex_shader);
  56. glAttachShader(program_shader, fragment_shader);
  57. if (geometry_shader)
  58. {
  59. glAttachShader(program_shader, geometry_shader);
  60. /* This covers only basic cases and may need to be modified */
  61. glProgramParameteri(program_shader, GL_GEOMETRY_INPUT_TYPE, GL_TRIANGLES);
  62. glProgramParameteri(program_shader, GL_GEOMETRY_OUTPUT_TYPE, GL_TRIANGLES);
  63. glProgramParameteri(program_shader, GL_GEOMETRY_VERTICES_OUT, geometry_shader_max_vertices);
  64. }
  65. glBindFragDataLocation(program_shader, 0, fragment_data_name.c_str());
  66. glLinkProgram(program_shader);
  67. GLint status;
  68. glGetProgramiv(program_shader, GL_LINK_STATUS, &status);
  69. if (status != GL_TRUE)
  70. {
  71. char buffer[512];
  72. glGetProgramInfoLog(program_shader, 512, NULL, buffer);
  73. cerr << "Linker error: " << endl << buffer << endl;
  74. program_shader = 0;
  75. return false;
  76. }
  77. return true;
  78. }
  79. IGL_INLINE void igl::OpenGL_shader::bind()
  80. {
  81. glUseProgram(program_shader);
  82. }
  83. IGL_INLINE GLint igl::OpenGL_shader::attrib(const std::string &name) const
  84. {
  85. return glGetAttribLocation(program_shader, name.c_str());
  86. }
  87. IGL_INLINE GLint igl::OpenGL_shader::uniform(const std::string &name) const
  88. {
  89. return glGetUniformLocation(program_shader, name.c_str());
  90. }
  91. IGL_INLINE GLint igl::OpenGL_shader::bindVertexAttribArray(
  92. const std::string &name, GLuint bufferID, const Eigen::MatrixXf &M, bool refresh) const
  93. {
  94. GLint id = attrib(name);
  95. if (id < 0)
  96. return id;
  97. if (M.size() == 0)
  98. {
  99. glDisableVertexAttribArray(id);
  100. return id;
  101. }
  102. glBindBuffer(GL_ARRAY_BUFFER, bufferID);
  103. if (refresh)
  104. glBufferData(GL_ARRAY_BUFFER, sizeof(float)*M.size(), M.data(), GL_DYNAMIC_DRAW);
  105. glVertexAttribPointer(id, M.rows(), GL_FLOAT, GL_FALSE, 0, 0);
  106. glEnableVertexAttribArray(id);
  107. return id;
  108. }
  109. IGL_INLINE void igl::OpenGL_shader::free()
  110. {
  111. if (program_shader)
  112. {
  113. glDeleteProgram(program_shader);
  114. program_shader = 0;
  115. }
  116. if (vertex_shader)
  117. {
  118. glDeleteShader(vertex_shader);
  119. vertex_shader = 0;
  120. }
  121. if (fragment_shader)
  122. {
  123. glDeleteShader(fragment_shader);
  124. fragment_shader = 0;
  125. }
  126. if (geometry_shader)
  127. {
  128. glDeleteShader(geometry_shader);
  129. geometry_shader = 0;
  130. }
  131. }
  132. IGL_INLINE GLuint igl::OpenGL_shader::create_shader_helper(GLint type, const std::string &shader_string)
  133. {
  134. using namespace std;
  135. if (shader_string.empty())
  136. return (GLuint) 0;
  137. GLuint id = glCreateShader(type);
  138. const char *shader_string_const = shader_string.c_str();
  139. glShaderSource(id, 1, &shader_string_const, NULL);
  140. glCompileShader(id);
  141. GLint status;
  142. glGetShaderiv(id, GL_COMPILE_STATUS, &status);
  143. if (status != GL_TRUE)
  144. {
  145. char buffer[512];
  146. if (type == GL_VERTEX_SHADER)
  147. cerr << "Vertex shader:" << endl;
  148. else if (type == GL_FRAGMENT_SHADER)
  149. cerr << "Fragment shader:" << endl;
  150. else if (type == GL_GEOMETRY_SHADER)
  151. cerr << "Geometry shader:" << endl;
  152. cerr << shader_string << endl << endl;
  153. glGetShaderInfoLog(id, 512, NULL, buffer);
  154. cerr << "Error: " << endl << buffer << endl;
  155. return (GLuint) 0;
  156. }
  157. return id;
  158. }