Clone of mesa.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

shaderutil.c 6.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. /**
  2. * Utilities for OpenGL shading language
  3. *
  4. * Brian Paul
  5. * 9 April 2008
  6. */
  7. #include <assert.h>
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include <GL/glew.h>
  12. #include <GL/glut.h>
  13. #include "shaderutil.h"
  14. /** time to compile previous shader */
  15. static GLdouble CompileTime = 0.0;
  16. /** time to linke previous program */
  17. static GLdouble LinkTime = 0.0;
  18. GLboolean
  19. ShadersSupported(void)
  20. {
  21. const char *version = (const char *) glGetString(GL_VERSION);
  22. if (version[0] == '2' && version[1] == '.') {
  23. return GL_TRUE;
  24. }
  25. else if (glutExtensionSupported("GL_ARB_vertex_shader")
  26. && glutExtensionSupported("GL_ARB_fragment_shader")
  27. && glutExtensionSupported("GL_ARB_shader_objects")) {
  28. fprintf(stderr, "Warning: Trying ARB GLSL instead of OpenGL 2.x. This may not work.\n");
  29. return GL_TRUE;
  30. }
  31. fprintf(stderr, "Sorry, GLSL not supported with this OpenGL.\n");
  32. return GL_FALSE;
  33. }
  34. GLuint
  35. CompileShaderText(GLenum shaderType, const char *text)
  36. {
  37. GLuint shader;
  38. GLint stat;
  39. GLdouble t0, t1;
  40. shader = glCreateShader(shaderType);
  41. glShaderSource(shader, 1, (const GLchar **) &text, NULL);
  42. t0 = glutGet(GLUT_ELAPSED_TIME) * 0.001;
  43. glCompileShader(shader);
  44. t1 = glutGet(GLUT_ELAPSED_TIME) * 0.001;
  45. CompileTime = t1 - t0;
  46. glGetShaderiv(shader, GL_COMPILE_STATUS, &stat);
  47. if (!stat) {
  48. GLchar log[1000];
  49. GLsizei len;
  50. glGetShaderInfoLog(shader, 1000, &len, log);
  51. fprintf(stderr, "Error: problem compiling shader: %s\n", log);
  52. exit(1);
  53. }
  54. else {
  55. /*printf("Shader compiled OK\n");*/
  56. }
  57. return shader;
  58. }
  59. /**
  60. * Read a shader from a file.
  61. */
  62. GLuint
  63. CompileShaderFile(GLenum shaderType, const char *filename)
  64. {
  65. const int max = 100*1000;
  66. int n;
  67. char *buffer = (char*) malloc(max);
  68. GLuint shader;
  69. FILE *f;
  70. f = fopen(filename, "r");
  71. if (!f) {
  72. fprintf(stderr, "Unable to open shader file %s\n", filename);
  73. free(buffer);
  74. return 0;
  75. }
  76. n = fread(buffer, 1, max, f);
  77. /*printf("read %d bytes from shader file %s\n", n, filename);*/
  78. if (n > 0) {
  79. buffer[n] = 0;
  80. shader = CompileShaderText(shaderType, buffer);
  81. }
  82. else {
  83. fclose(f);
  84. free(buffer);
  85. return 0;
  86. }
  87. fclose(f);
  88. free(buffer);
  89. return shader;
  90. }
  91. GLuint
  92. LinkShaders(GLuint vertShader, GLuint fragShader)
  93. {
  94. GLuint program = glCreateProgram();
  95. GLdouble t0, t1;
  96. assert(vertShader || fragShader);
  97. if (fragShader)
  98. glAttachShader(program, fragShader);
  99. if (vertShader)
  100. glAttachShader(program, vertShader);
  101. t0 = glutGet(GLUT_ELAPSED_TIME) * 0.001;
  102. glLinkProgram(program);
  103. t1 = glutGet(GLUT_ELAPSED_TIME) * 0.001;
  104. LinkTime = t1 - t0;
  105. /* check link */
  106. {
  107. GLint stat;
  108. glGetProgramiv(program, GL_LINK_STATUS, &stat);
  109. if (!stat) {
  110. GLchar log[1000];
  111. GLsizei len;
  112. glGetProgramInfoLog(program, 1000, &len, log);
  113. fprintf(stderr, "Shader link error:\n%s\n", log);
  114. return 0;
  115. }
  116. }
  117. return program;
  118. }
  119. GLboolean
  120. ValidateShaderProgram(GLuint program)
  121. {
  122. GLint stat;
  123. glValidateProgramARB(program);
  124. glGetProgramiv(program, GL_VALIDATE_STATUS, &stat);
  125. if (!stat) {
  126. GLchar log[1000];
  127. GLsizei len;
  128. glGetProgramInfoLog(program, 1000, &len, log);
  129. fprintf(stderr, "Program validation error:\n%s\n", log);
  130. return 0;
  131. }
  132. return (GLboolean) stat;
  133. }
  134. GLdouble
  135. GetShaderCompileTime(void)
  136. {
  137. return CompileTime;
  138. }
  139. GLdouble
  140. GetShaderLinkTime(void)
  141. {
  142. return LinkTime;
  143. }
  144. void
  145. SetUniformValues(GLuint program, struct uniform_info uniforms[])
  146. {
  147. GLuint i;
  148. for (i = 0; uniforms[i].name; i++) {
  149. uniforms[i].location
  150. = glGetUniformLocation(program, uniforms[i].name);
  151. switch (uniforms[i].type) {
  152. case GL_INT:
  153. case GL_SAMPLER_1D:
  154. case GL_SAMPLER_2D:
  155. case GL_SAMPLER_3D:
  156. case GL_SAMPLER_CUBE:
  157. case GL_SAMPLER_2D_RECT_ARB:
  158. assert(uniforms[i].value[0] >= 0.0F);
  159. glUniform1i(uniforms[i].location,
  160. (GLint) uniforms[i].value[0]);
  161. break;
  162. case GL_FLOAT:
  163. glUniform1fv(uniforms[i].location, 1, uniforms[i].value);
  164. break;
  165. case GL_FLOAT_VEC2:
  166. glUniform2fv(uniforms[i].location, 1, uniforms[i].value);
  167. break;
  168. case GL_FLOAT_VEC3:
  169. glUniform3fv(uniforms[i].location, 1, uniforms[i].value);
  170. break;
  171. case GL_FLOAT_VEC4:
  172. glUniform4fv(uniforms[i].location, 1, uniforms[i].value);
  173. break;
  174. default:
  175. if (strncmp(uniforms[i].name, "gl_", 3) == 0) {
  176. /* built-in uniform: ignore */
  177. }
  178. else {
  179. fprintf(stderr,
  180. "Unexpected uniform data type in SetUniformValues\n");
  181. abort();
  182. }
  183. }
  184. }
  185. }
  186. /** Get list of uniforms used in the program */
  187. GLuint
  188. GetUniforms(GLuint program, struct uniform_info uniforms[])
  189. {
  190. GLint n, max, i;
  191. glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &n);
  192. glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max);
  193. for (i = 0; i < n; i++) {
  194. GLint size, len;
  195. GLenum type;
  196. char name[100];
  197. glGetActiveUniform(program, i, 100, &len, &size, &type, name);
  198. uniforms[i].name = strdup(name);
  199. uniforms[i].size = size;
  200. uniforms[i].type = type;
  201. uniforms[i].location = glGetUniformLocation(program, name);
  202. }
  203. uniforms[i].name = NULL; /* end of list */
  204. return n;
  205. }
  206. void
  207. PrintUniforms(const struct uniform_info uniforms[])
  208. {
  209. GLint i;
  210. printf("Uniforms:\n");
  211. for (i = 0; uniforms[i].name; i++) {
  212. printf(" %d: %s size=%d type=0x%x loc=%d value=%g, %g, %g, %g\n",
  213. i,
  214. uniforms[i].name,
  215. uniforms[i].size,
  216. uniforms[i].type,
  217. uniforms[i].location,
  218. uniforms[i].value[0],
  219. uniforms[i].value[1],
  220. uniforms[i].value[2],
  221. uniforms[i].value[3]);
  222. }
  223. }
  224. /** Get list of attribs used in the program */
  225. GLuint
  226. GetAttribs(GLuint program, struct attrib_info attribs[])
  227. {
  228. GLint n, max, i;
  229. glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &n);
  230. glGetProgramiv(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &max);
  231. for (i = 0; i < n; i++) {
  232. GLint size, len;
  233. GLenum type;
  234. char name[100];
  235. glGetActiveAttrib(program, i, 100, &len, &size, &type, name);
  236. attribs[i].name = strdup(name);
  237. attribs[i].size = size;
  238. attribs[i].type = type;
  239. attribs[i].location = glGetAttribLocation(program, name);
  240. }
  241. attribs[i].name = NULL; /* end of list */
  242. return n;
  243. }
  244. void
  245. PrintAttribs(const struct attrib_info attribs[])
  246. {
  247. GLint i;
  248. printf("Attribs:\n");
  249. for (i = 0; attribs[i].name; i++) {
  250. printf(" %d: %s size=%d type=0x%x loc=%d\n",
  251. i,
  252. attribs[i].name,
  253. attribs[i].size,
  254. attribs[i].type,
  255. attribs[i].location);
  256. }
  257. }