Advertisement
Guest User

Untitled

a guest
Jan 21st, 2020
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.60 KB | None | 0 0
  1. #include "GLShader.h"
  2. #include <glm/mat4x4.hpp>
  3. #include <glm/gtc/matrix_transform.hpp>
  4. #include <glm/gtc/type_ptr.hpp>
  5.  
  6. ShaderData::ShaderData(){}
  7.  
  8. ShaderData::ShaderData(GLuint sh, GLenum type) {
  9. ShaderData::shader = sh; // идентификатор шейдера
  10. ShaderData::shader_type = type; // тип шейдера
  11. }
  12.  
  13. VariableData::VariableData() {}
  14.  
  15. VariableData::VariableData(GLint l, std::string n, GLenum t, GLsizei sz) {
  16. location = l;
  17. VariableData::name = n;
  18. VariableData::type = t;
  19. VariableData::size = sz;
  20. }
  21.  
  22. GLShader::GLShader()
  23. {
  24. GLShader::ShaderProgram = 0;
  25. GLShader::shaders = std::map<int, ShaderData>();
  26. GLShader::attributes = std::map<std::string, VariableData>();
  27. shader_count = 0;
  28. ShaderProgram = glCreateProgram();
  29. }
  30.  
  31.  
  32. GLShader::~GLShader()
  33. {
  34. glUseProgram(0);
  35. GLint act_cnt;
  36. glGetProgramiv(ShaderProgram, GL_ATTACHED_SHADERS, &act_cnt);
  37. GLuint * attached = new GLuint[act_cnt];
  38. glGetAttachedShaders(ShaderProgram, act_cnt, &act_cnt, attached);
  39. for (int i = 0; i < act_cnt; ++i) {
  40. glDetachShader(ShaderProgram, attached[i]);
  41.  
  42. }
  43. delete attached;
  44. glDeleteProgram(ShaderProgram);
  45.  
  46. for (int i = 0; i < shaders.size(); ++i) {
  47. glDeleteShader(shaders[i].shader);
  48. }
  49. }
  50.  
  51. int GLShader::load_shader(std::string filename, GLenum shader_type) {
  52. GLuint s = compileSource(filename, shader_type);
  53. ShaderData sd = ShaderData(s, shader_type);
  54. shaders.insert(std::pair<int, ShaderData>(shader_count, sd));
  55. return shader_count++;
  56.  
  57. }
  58.  
  59. bool GLShader::setUniformfv4(std::string name, glm::vec4 v)
  60. {
  61. auto vd = uniforms.find(name);
  62. if (vd == uniforms.end())
  63. return false; // no such uniform
  64. if (vd->second.type != GL_FLOAT_VEC4)
  65. return false; // type error
  66. glUniform4fv(vd->second.location, 1, glm::value_ptr(v));
  67. return true;
  68. }
  69.  
  70. bool GLShader::setUniformfv3(std::string name, glm::vec3 v)
  71. {
  72. auto vd = uniforms.find(name);
  73. if (vd == uniforms.end())
  74. return false; // no such uniform
  75. if (vd->second.type != GL_FLOAT_VEC3)
  76. return false; // type error
  77. glUniform3fv(vd->second.location, 1, glm::value_ptr(v));
  78. return true;
  79. }
  80.  
  81. bool GLShader::setUniformfv2(std::string name, glm::vec2 v)
  82. {
  83. auto vd = uniforms.find(name);
  84. if (vd == uniforms.end())
  85. return false; // no such uniform
  86. if (vd->second.type != GL_FLOAT_VEC2)
  87. return false; // type error
  88. glUniform2fv(vd->second.location, 1, glm::value_ptr(v));
  89. return true;
  90. }
  91.  
  92. bool GLShader::setUniformmat4(std::string name, bool transpose, glm::mat4 mat4)
  93. {
  94. auto vd = uniforms.find(name);
  95. if (vd == uniforms.end())
  96. return false; // no such uniform
  97. if (vd->second.type != GL_FLOAT_MAT4)
  98. return false; // type error
  99. glUniformMatrix4fv(vd->second.location, 1,transpose, glm::value_ptr(mat4));
  100. return true;
  101. }
  102.  
  103. bool GLShader::setUniformmat3(std::string name, bool transpose, glm::mat3 mat3)
  104. {
  105. auto vd = uniforms.find(name);
  106. if (vd == uniforms.end())
  107. return false; // no such uniform
  108. if (vd->second.type != GL_FLOAT_MAT3)
  109. return false; // type error
  110. glUniformMatrix3fv(vd->second.location, 1, transpose, glm::value_ptr(mat3));
  111. return true;
  112. }
  113.  
  114.  
  115. bool GLShader::setUniform1i(std::string name, const GLint value)
  116. {
  117. auto vd = uniforms.find(name);
  118. if (vd == uniforms.end())
  119. return false; // no such uniform
  120. if (vd->second.type != GL_INT)
  121. return false; // type error
  122. glUniform1i(vd->second.location, value);
  123. return true;
  124. }
  125.  
  126. bool GLShader::setUniform1s(std::string name, const GLint value)
  127. {
  128. auto vd = uniforms.find(name);
  129. if (vd == uniforms.end())
  130. return false; // no such uniform
  131. if (vd->second.type != GL_SAMPLER_2D)
  132. return false; // type error
  133. glUniform1i(vd->second.location, value);
  134. return true;
  135. }
  136.  
  137. bool GLShader::setUniform1f(std::string name, const GLfloat value)
  138. {
  139. auto vd = uniforms.find(name);
  140. if (vd == uniforms.end())
  141. return false; // no such uniform
  142. if (vd->second.type != GL_FLOAT)
  143. return false; // type error
  144. glUniform1f(vd->second.location, value);
  145. return true;
  146. }
  147.  
  148. bool GLShader::setUniform1b(std::string name, const bool value)
  149. {
  150. auto vd = uniforms.find(name);
  151. if (vd == uniforms.end())
  152. return false; // no such uniform
  153. if (vd->second.type != GL_BOOL)
  154. return false; // type error
  155. glUniform1i(vd->second.location, value);
  156. return true;
  157. }
  158.  
  159. GLint GLShader::getAttributeLocation(std::string name)
  160. {
  161. auto vd = attributes.find(name);
  162. if (vd == attributes.end())
  163. return -1; // no such attribute
  164. return vd->second.location;
  165. }
  166.  
  167. std::string GLShader::loadSourceFile(const std::string& source_file_name) {
  168. std::ifstream f(source_file_name);
  169. std::stringstream ss;
  170. ss << f.rdbuf();
  171. return ss.str();
  172. }
  173.  
  174. GLuint GLShader::compileSource(std::string filename, GLenum shader_type) {
  175. GLuint shader = glCreateShader(shader_type);
  176. std::string str = loadSourceFile(filename);
  177. const char * c = str.c_str();
  178. int len = str.length();
  179. glShaderSource(shader,1,&c,&len); // загружается исходный код на идентификатор шейдера
  180. glCompileShader(shader);
  181. printInfoLogShader(shader);
  182. return shader;
  183. }
  184.  
  185. void GLShader::printInfoLogShader(GLuint shader) {
  186. int infologLen = 0;
  187. int charsWritten = 0;
  188. char *infoLog;
  189. glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infologLen);
  190. if (infologLen > 1)
  191. {
  192. infoLog = new char[infologLen];
  193. if (infoLog == NULL)
  194. {
  195. std::cout << "ERROR: Could not allocate InfoLog buffer\n";
  196. exit(1);
  197. }
  198. glGetShaderInfoLog(shader, infologLen, &charsWritten, infoLog);
  199. std::cout << "InfoLog: " << infoLog << "\n\n\n";
  200. checkOpenGLerror();
  201. delete[] infoLog;
  202. }
  203. }
  204.  
  205. void GLShader::printInfoLogProgram() {
  206. int infologLen = 0;
  207. int charsWritten = 0;
  208. char *infoLog;
  209. glGetProgramiv(ShaderProgram, GL_INFO_LOG_LENGTH, &infologLen);
  210. if (infologLen > 1)
  211. {
  212. infoLog = new char[infologLen];
  213. if (infoLog == NULL)
  214. {
  215. std::cout << "ERROR: Could not allocate InfoLog buffer\n";
  216. exit(1);
  217. }
  218. glGetProgramInfoLog(ShaderProgram, infologLen, &charsWritten, infoLog);
  219. std::cout << "InfoLog: " << infoLog << "\n\n\n";
  220. checkOpenGLerror();
  221. delete[] infoLog;
  222. }
  223. }
  224.  
  225. void GLShader::linkProgram(int vertex_id, int fragment_id) {
  226. GLint act_cnt;
  227. glGetProgramiv(ShaderProgram, GL_ATTACHED_SHADERS, &act_cnt);
  228. GLuint * attached = new GLuint[act_cnt];
  229. glGetAttachedShaders(ShaderProgram, act_cnt, &act_cnt, attached);
  230. for (int i = 0; i < act_cnt; ++i)
  231. glDetachShader(ShaderProgram, attached[i]);
  232. delete attached;
  233.  
  234. glAttachShader(ShaderProgram, shaders[vertex_id].shader); // шейдер прикрепляется к программе
  235. checkOpenGLerror();
  236. printInfoLogProgram();
  237. glAttachShader(ShaderProgram, shaders[fragment_id].shader);
  238. checkOpenGLerror();
  239. printInfoLogProgram();
  240. glLinkProgram(ShaderProgram); // объединяет шейдеры между собой (in/out переменные должны сооответствовать)
  241.  
  242. int link_ok;
  243. glGetProgramiv(ShaderProgram, GL_LINK_STATUS, &link_ok);
  244. if (!link_ok)
  245. {
  246. std::cout << "error attach shaders \n";
  247. checkOpenGLerror();
  248. printInfoLogProgram();
  249. return;
  250. }
  251.  
  252. int count_attributes, max_length;
  253. attributes.clear();
  254. uniforms.clear();
  255. glGetProgramiv(ShaderProgram, GL_ACTIVE_ATTRIBUTES, &count_attributes);
  256. glGetProgramiv(ShaderProgram, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &max_length); // макс длина имени атрибута
  257. char* name = new char[max_length];
  258. for (int i= 0; i < count_attributes; ++i) {
  259. int size;
  260. GLenum type;
  261. glGetActiveAttrib(ShaderProgram, i, max_length, NULL, &size, &type, name); // возвращает информацию об активном атрибуте в шейдерной программе
  262. auto Loc = glGetAttribLocation(ShaderProgram, name);
  263. std::string sname = std::string(name);
  264. VariableData vb(Loc,sname, type, size);
  265. attributes.insert(std::pair<std::string, VariableData>(sname, vb));
  266. }
  267. delete name;
  268.  
  269.  
  270. glGetProgramiv(ShaderProgram, GL_ACTIVE_UNIFORMS, &count_attributes);
  271. glGetProgramiv(ShaderProgram, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max_length);
  272. name = new char[max_length];
  273. for (int i = 0; i < count_attributes; ++i) {
  274. int size;
  275. GLenum type;
  276. glGetActiveUniform(ShaderProgram, i, max_length, NULL, &size, &type, name);
  277. auto Loc = glGetUniformLocation(ShaderProgram, name);
  278. std::string sname = std::string(name);
  279. VariableData vb(Loc,sname, type, size);
  280. uniforms.insert(std::pair<std::string, VariableData>(sname, vb));
  281. }
  282. delete name;
  283.  
  284.  
  285. }
  286.  
  287. void GLShader::checkOpenGLerror()
  288. {
  289. GLenum errCode;
  290. if ((errCode = glGetError()) != GL_NO_ERROR)
  291. std::cout << "OpenGl error! - " << gluErrorString(errCode);
  292. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement