/Source/ShaderObject.cpp

http://ssaomx.codeplex.com · C++ · 463 lines · 370 code · 86 blank · 7 comment · 32 complexity · 2a8f4b885b808da8c4ac8068085f7071 MD5 · raw file

  1. #include "../Header/ShaderObject.h"
  2. #include "../Header/StringUtils.h"
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <sys/stat.h>
  6. #include <windows.h>
  7. #include <GL/glew.h>
  8. #include <GL/wglew.h>
  9. //#include <GL/glut.h>
  10. ShaderObject::ShaderObject (char *fragment):shader_id(0),num_vars(0){
  11. initShaders (fragment);
  12. }
  13. ShaderObject::ShaderObject(char *vertex, char *fragment):shader_id(0),num_vars(0){
  14. initShaders(vertex, fragment);
  15. }
  16. #ifdef USE_GEOMETRY_SHADERS
  17. ShaderObject::ShaderObject(char *vertex, char *fragment, char *geometry, unsigned int inPrimitive, unsigned int outPrimitive):shader_id(0),num_vars(0){
  18. initShaders(vertex, fragment, geometry, inPrimitive, outPrimitive);
  19. }
  20. ShaderObject::ShaderObject(char *vertex, char *geometry, unsigned int inPrimitive, unsigned int outPrimitive):shader_id(0),num_vars(0){
  21. initShaders(vertex, geometry, inPrimitive, outPrimitive);
  22. }
  23. #endif
  24. ShaderObject::~ShaderObject(){
  25. if(shader_id) glDeleteShader (shader_id);
  26. }
  27. char *ShaderObject::loadShaderCode (char* filename){
  28. FILE *shFile;
  29. //std::ifstream file;
  30. unsigned long len, readLen;
  31. char* fileData;
  32. struct stat f_status;
  33. if(stat(filename, &f_status)) return NULL;
  34. len = f_status.st_size;
  35. shFile = fopen(filename, "r");
  36. if(shFile == NULL) return NULL;
  37. fileData = new char[len+1];
  38. memset(fileData, ' ', len+1);
  39. readLen = fread(fileData, 1, len, shFile);
  40. fileData[len]=0;
  41. fclose(shFile);
  42. return fileData;
  43. }
  44. void ShaderObject::initShaders(char *fragment) {
  45. int progLinkSuccess;
  46. const char *Shader;
  47. GLuint fragmentHandler;
  48. GLuint programObject;
  49. shader_id = 0;
  50. if ((Shader = (const char *)loadShaderCode (fragment))==NULL){
  51. fprintf(stderr, "Unable to Load Shader %s \n",fragment);
  52. exit (1);
  53. }
  54. fragmentHandler = glCreateShader(GL_FRAGMENT_SHADER);
  55. glShaderSource (fragmentHandler , 1, &Shader, NULL);
  56. if (Shader) delete [] Shader, Shader = NULL;
  57. glCompileShader (fragmentHandler);
  58. programObject = glCreateProgram ();
  59. glAttachShader (programObject, fragmentHandler);
  60. glLinkProgram (programObject);
  61. glDeleteShader(fragmentHandler);
  62. glGetProgramiv (programObject, GL_LINK_STATUS, &progLinkSuccess);
  63. if (!progLinkSuccess) {
  64. glGetProgramiv (programObject, GL_INFO_LOG_LENGTH, &progLinkSuccess);
  65. Shader = new const char [progLinkSuccess];
  66. glGetProgramInfoLog (programObject, progLinkSuccess, NULL, (char*)Shader);
  67. fprintf (stdout, "\n%s\n", Shader);
  68. fprintf(stderr, "Shader could not be linked %s\n",fragment);
  69. delete [] Shader;
  70. Shader = NULL;
  71. exit(1);
  72. }
  73. fprintf (stdout, "%s\nbuild succeeded...\n", fragment);
  74. shader_id = programObject;
  75. glUseProgram (shader_id);
  76. num_vars=0;
  77. initVarInfo();
  78. }
  79. void ShaderObject::initShaders(char *vertex, char *fragment){
  80. int progLinkSuccess;
  81. const char *Shader;
  82. GLuint vertexHandler, fragmentHandler;
  83. GLuint programObject;
  84. shader_id = 0;
  85. if ((Shader = (const char *)loadShaderCode (vertex))==NULL){
  86. fprintf(stderr, "Unable to Load Vertex Shader %s\n", vertex);
  87. exit (1);
  88. }
  89. vertexHandler = glCreateShader(GL_VERTEX_SHADER);
  90. glShaderSource (vertexHandler , 1, &Shader, NULL);
  91. delete[] Shader;
  92. if ((Shader = (const char *)loadShaderCode (fragment))==NULL){
  93. fprintf(stderr, "Unable to Load Shader %s\n", fragment);
  94. exit (1);
  95. }
  96. fragmentHandler = glCreateShader(GL_FRAGMENT_SHADER);
  97. glShaderSource (fragmentHandler , 1, &Shader, NULL);
  98. delete[] Shader;
  99. glCompileShader (vertexHandler);
  100. glCompileShader (fragmentHandler);
  101. programObject = glCreateProgram ();
  102. glAttachShader (programObject, vertexHandler);
  103. glAttachShader (programObject, fragmentHandler);
  104. glLinkProgram (programObject);
  105. glDeleteShader(vertexHandler);
  106. glDeleteShader(fragmentHandler);
  107. glGetProgramiv (programObject, GL_LINK_STATUS, &progLinkSuccess);
  108. if (!progLinkSuccess) {
  109. glGetProgramiv (programObject, GL_INFO_LOG_LENGTH, &progLinkSuccess);
  110. Shader = new const char [progLinkSuccess];
  111. glGetProgramInfoLog (programObject, progLinkSuccess, NULL, (char*)Shader);
  112. fprintf (stdout, "\n%s\n", Shader);
  113. fprintf(stderr, "Shader could not be linked %s\n", vertex, fragment);
  114. delete [] Shader;
  115. Shader = NULL;
  116. exit(1);
  117. }
  118. fprintf (stdout, "%s\n%s\nbuild succeeded...\n", vertex, fragment);
  119. shader_id = programObject;
  120. glUseProgram (shader_id);
  121. num_vars=0;
  122. initVarInfo();
  123. }
  124. #ifdef USE_GEOMETRY_SHADERS
  125. void ShaderObject::initShaders(char *vertex, char *fragment, char *geometry, unsigned int inPrimitive, unsigned int outPrimitive){
  126. int progLinkSuccess;
  127. const char *Shader;
  128. GLuint vertexHandler, fragmentHandler, geometryHandler;
  129. GLuint programObject;
  130. shader_id = 0;
  131. if ((Shader = (const char *)loadShaderCode (vertex))==NULL){
  132. fprintf(stderr, "Unable to Load Vertex Shader %s\n", vertex);
  133. exit (1);
  134. }
  135. vertexHandler = glCreateShader(GL_VERTEX_SHADER);
  136. glShaderSource (vertexHandler , 1, &Shader, NULL);
  137. delete[] Shader;
  138. if ((Shader = (const char *)loadShaderCode (geometry))==NULL){
  139. fprintf(stderr, "Unable to Load Shader %s\n", geometry);
  140. exit (1);
  141. }
  142. geometryHandler = glCreateShader(GL_GEOMETRY_SHADER_EXT);
  143. glShaderSource (geometryHandler , 1, &Shader, NULL);
  144. delete[] Shader;
  145. if ((Shader = (const char *)loadShaderCode (fragment))==NULL){
  146. fprintf(stderr, "Unable to Load Shader %s\n", fragment);
  147. exit (1);
  148. }
  149. fragmentHandler = glCreateShader(GL_FRAGMENT_SHADER);
  150. glShaderSource (fragmentHandler , 1, &Shader, NULL);
  151. delete[] Shader;
  152. glCompileShader (vertexHandler);
  153. glCompileShader (geometryHandler);
  154. glCompileShader (fragmentHandler);
  155. programObject = glCreateProgram ();
  156. glAttachShader (programObject, vertexHandler);
  157. glAttachShader (programObject, geometryHandler);
  158. glAttachShader (programObject, fragmentHandler);
  159. glProgramParameteriEXT(programObject,GL_GEOMETRY_INPUT_TYPE_EXT , inPrimitive );
  160. glProgramParameteriEXT(programObject,GL_GEOMETRY_OUTPUT_TYPE_EXT , outPrimitive );
  161. glProgramParameteriEXT(programObject,GL_GEOMETRY_VERTICES_OUT_EXT, 4);
  162. glLinkProgram (programObject);
  163. glDeleteShader(vertexHandler);
  164. glDeleteShader(geometryHandler);
  165. glDeleteShader(fragmentHandler);
  166. glGetProgramiv (programObject, GL_LINK_STATUS, &progLinkSuccess);
  167. if (!progLinkSuccess) {
  168. glGetProgramiv (programObject, GL_INFO_LOG_LENGTH, &progLinkSuccess);
  169. Shader = new const char [progLinkSuccess];
  170. glGetProgramInfoLog (programObject, progLinkSuccess, NULL, (char*)Shader);
  171. fprintf (stdout, "\n%s\n%s\n%s\n%s\n", vertex, geometry, fragment,Shader);
  172. fprintf(stderr, "Shader could not be linked\n");
  173. delete [] Shader;
  174. Shader = NULL;
  175. exit(1);
  176. }
  177. fprintf (stdout, "%s\n%s\n%s\nbuild succeeded...\n", vertex, geometry, fragment);
  178. shader_id = programObject;
  179. glUseProgram (shader_id);
  180. num_vars=0;
  181. initVarInfo();
  182. }
  183. void ShaderObject::initShaders(char *vertex, char *geometry, unsigned int inPrimitive, unsigned int outPrimitive){
  184. int progLinkSuccess;
  185. const char *Shader;
  186. GLuint vertexHandler, geometryHandler;
  187. GLuint programObject;
  188. shader_id = 0;
  189. if ((Shader = (const char *)loadShaderCode (vertex))==NULL){
  190. fprintf(stderr, "Unable to Load Vertex Shader %s\n", vertex);
  191. exit (1);
  192. }
  193. vertexHandler = glCreateShader(GL_VERTEX_SHADER);
  194. glShaderSource (vertexHandler , 1, &Shader, NULL);
  195. delete[] Shader;
  196. if ((Shader = (const char *)loadShaderCode (geometry))==NULL){
  197. fprintf(stderr, "Unable to Load Shader %s\n", geometry);
  198. exit (1);
  199. }
  200. geometryHandler = glCreateShader(GL_GEOMETRY_SHADER_EXT);
  201. glShaderSource (geometryHandler , 1, &Shader, NULL);
  202. delete[] Shader;
  203. glCompileShader (vertexHandler);
  204. glCompileShader (geometryHandler);
  205. programObject = glCreateProgram ();
  206. glAttachShader (programObject, vertexHandler);
  207. glAttachShader (programObject, geometryHandler);
  208. glProgramParameteriEXT(programObject,GL_GEOMETRY_INPUT_TYPE_EXT , inPrimitive );
  209. glProgramParameteriEXT(programObject,GL_GEOMETRY_OUTPUT_TYPE_EXT , outPrimitive );
  210. glProgramParameteriEXT(programObject,GL_GEOMETRY_VERTICES_OUT_EXT, 4);
  211. glLinkProgram (programObject);
  212. glDeleteShader(vertexHandler);
  213. glDeleteShader(geometryHandler);
  214. glGetProgramiv (programObject, GL_LINK_STATUS, &progLinkSuccess);
  215. if (!progLinkSuccess) {
  216. glGetProgramiv (programObject, GL_INFO_LOG_LENGTH, &progLinkSuccess);
  217. Shader = new const char [progLinkSuccess];
  218. glGetProgramInfoLog (programObject, progLinkSuccess, NULL, (char*)Shader);
  219. fprintf (stdout, "\n%s\n%s\n%s\n", vertex, geometry, Shader);
  220. fprintf(stderr, "Shader could not be linked\n");
  221. delete [] Shader;
  222. Shader = NULL;
  223. exit(1);
  224. }
  225. fprintf (stdout, "%s\n%s\nbuild succeeded...\n", vertex, geometry);
  226. shader_id = programObject;
  227. glUseProgram (shader_id);
  228. num_vars=0;
  229. initVarInfo();
  230. }
  231. #endif
  232. void ShaderObject::initVarInfo(){
  233. char *buffer;
  234. int len, bufLen;
  235. if(!shader_id) return;
  236. num_vars = 0;
  237. glGetProgramiv(shader_id, GL_ACTIVE_UNIFORMS, &num_vars);
  238. glGetProgramiv(shader_id, GL_ACTIVE_UNIFORM_MAX_LENGTH, &bufLen);
  239. buffer = new char[bufLen+1];
  240. for(int i=0; i<num_vars; ++i){
  241. variable_ids[i] = i;
  242. glGetActiveUniform (shader_id, i, bufLen, &len, &variable_sizes[i], &variable_types[i], buffer);
  243. buffer[len+1]=0;
  244. variable_names[i] = StringUtils::registerString(buffer);
  245. }
  246. delete[] buffer;
  247. }
  248. void ShaderObject::setUniformi(char *name, int value){
  249. int i;
  250. for(i=0; i<num_vars; ++i){
  251. if(!_stricmp(name, variable_names[i])){
  252. //glUniform1iARB(variable_ids[i], value);
  253. glUniform1i(variable_ids[i], value);
  254. break;
  255. }
  256. }
  257. // i = glGetUniformLocationARB (shader_id, name);
  258. // glUniform1iARB(i, value);
  259. }
  260. void ShaderObject::setUniformf(char *name, float value){
  261. int i;
  262. for(i=0; i<num_vars; ++i){
  263. if(!_stricmp(name, variable_names[i])){
  264. glUniform1fARB(variable_ids[i], value);
  265. break;
  266. }
  267. }
  268. }
  269. void ShaderObject::setUniformiv(char *name, int *value, int size){
  270. unsigned int i;
  271. i = glGetUniformLocation(shader_id, name);
  272. switch(size){
  273. case 1:
  274. glUniform1ivARB (i, 1, value);
  275. break;
  276. case 2:
  277. glUniform2ivARB (i, 1, value);
  278. break;
  279. case 3:
  280. glUniform3ivARB (i, 1, value);
  281. break;
  282. case 4:
  283. glUniform4ivARB (i, 1, value);
  284. break;
  285. }
  286. }
  287. void ShaderObject::setUniformfv(char *name, float *value, int size){
  288. unsigned int i;
  289. i = glGetUniformLocation(shader_id, name);
  290. switch(size){
  291. case 1:
  292. glUniform1fv(i, 1, value);
  293. break;
  294. case 2:
  295. glUniform2fv(i, 1, value);
  296. break;
  297. case 3:
  298. glUniform3fv(i, 1, value);
  299. break;
  300. case 4:
  301. glUniform4fv(i, 1, value);
  302. break;
  303. case 7:
  304. glUniform1fv(i, 7, value);
  305. break;
  306. }
  307. }
  308. void ShaderObject::setUniformMatrix(char *name, float *value, int size)
  309. {
  310. unsigned int i;
  311. i = glGetUniformLocation(shader_id, name);
  312. switch (size)
  313. {
  314. case 2:
  315. glUniformMatrix2fv(i, 1, GL_FALSE, value);
  316. break;
  317. case 3:
  318. glUniformMatrix3fv(i, 1, GL_FALSE, value);
  319. break;
  320. case 4:
  321. glUniformMatrix4fv(i, 1, GL_FALSE, value);
  322. break;
  323. }
  324. }
  325. void ShaderObject::activate(){
  326. //glUseProgramObjectARB(shader_id);
  327. glUseProgram(shader_id);
  328. }
  329. void ShaderObject::deactivate(){
  330. //glUseProgramObjectARB(0);
  331. glUseProgram(0);
  332. }
  333. void ShaderObject::setBindableUniform (char *name, unsigned int buffer)
  334. {
  335. unsigned int i;
  336. for (i=0;i<(unsigned int) num_vars; ++i) {
  337. if(!_stricmp(name, variable_names[i])){
  338. glUniformBufferEXT(shader_id, variable_ids[i], buffer);
  339. break;
  340. }
  341. }
  342. }
  343. void ShaderObject::unSetBindableUniform (char *name)
  344. {
  345. unsigned int i;
  346. for (i=0;i<(unsigned int) num_vars; ++i) {
  347. if(!_stricmp(name, variable_names[i])){
  348. glUniformBufferEXT(shader_id, variable_ids[i], 0);
  349. break;
  350. }
  351. }
  352. }
  353. int ShaderObject::getBindableUniformSize(char *name) {
  354. unsigned int i;
  355. for (i=0;i<(unsigned int) num_vars; ++i) {
  356. if(!_stricmp(name, variable_names[i])){
  357. return glGetUniformBufferSizeEXT(shader_id, variable_ids[i]);
  358. }
  359. }
  360. return 0;
  361. }
  362. void ShaderObject::getMaxBindableUniformSize (int &val)
  363. {
  364. glGetIntegerv (GL_MAX_BINDABLE_UNIFORM_SIZE_EXT, &val);
  365. }
  366. void ShaderObject::getMaxVertexBindableUniforms (int &val)
  367. {
  368. glGetIntegerv (GL_MAX_VERTEX_BINDABLE_UNIFORMS_EXT, &val);
  369. }
  370. void ShaderObject::getMaxFragmentBindableUniforms(int &val)
  371. {
  372. glGetIntegerv (GL_MAX_FRAGMENT_BINDABLE_UNIFORMS_EXT, &val);
  373. }
  374. void ShaderObject::getMaxGeometryBindableUniforms (int &val)
  375. {
  376. glGetIntegerv (GL_MAX_GEOMETRY_BINDABLE_UNIFORMS_EXT, &val);
  377. }