PVRTShader.cpp 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. /******************************************************************************
  2. @File PVRTShader.cpp
  3. @Title PVRTShader
  4. @Version
  5. @Copyright Copyright (C) Imagination Technologies Limited.
  6. @Platform ANSI compatible
  7. @Description Shader handling for OpenGL ES 2.0
  8. ******************************************************************************/
  9. #include "PVRTString.h"
  10. #include "PVRTShader.h"
  11. #include "PVRTResourceFile.h"
  12. #include "PVRTGlobal.h"
  13. /*!***************************************************************************
  14. @Function PVRTShaderLoadSourceFromMemory
  15. @Input pszShaderCode shader source code
  16. @Input Type type of shader (GL_VERTEX_SHADER or GL_FRAGMENT_SHADER)
  17. @Output pObject the resulting shader object
  18. @Output pReturnError the error message if it failed
  19. @Input aszDefineArray Array of defines to be pre-appended to shader string
  20. @Input uiDefArraySize Size of the define array
  21. @Return PVR_SUCCESS on success and PVR_FAIL on failure (also fills the str string)
  22. @Description Loads a shader source code into memory and compiles it.
  23. It also pre-appends the array of defines that have been passed in
  24. to the source code before compilation.
  25. *****************************************************************************/
  26. EPVRTError PVRTShaderLoadSourceFromMemory( const char* pszShaderCode,
  27. const GLenum Type,
  28. GLuint* const pObject,
  29. CPVRTString* const pReturnError,
  30. const char* const* aszDefineArray, GLuint uiDefArraySize)
  31. {
  32. // Append define's here if there are any
  33. CPVRTString pszShaderString;
  34. for(GLuint i = 0 ; i < uiDefArraySize; ++i)
  35. {
  36. pszShaderString += "#define ";
  37. pszShaderString += aszDefineArray[i];
  38. pszShaderString += "\n";
  39. }
  40. // Append the shader code to the string
  41. pszShaderString += pszShaderCode;
  42. /* Create and compile the shader object */
  43. *pObject = glCreateShader(Type);
  44. const char* pszString(pszShaderString.c_str());
  45. glShaderSource(*pObject, 1, &pszString, NULL);
  46. glCompileShader(*pObject);
  47. /* Test if compilation succeeded */
  48. GLint ShaderCompiled;
  49. glGetShaderiv(*pObject, GL_COMPILE_STATUS, &ShaderCompiled);
  50. if (!ShaderCompiled)
  51. {
  52. int i32InfoLogLength, i32CharsWritten;
  53. glGetShaderiv(*pObject, GL_INFO_LOG_LENGTH, &i32InfoLogLength);
  54. char* pszInfoLog = new char[i32InfoLogLength];
  55. glGetShaderInfoLog(*pObject, i32InfoLogLength, &i32CharsWritten, pszInfoLog);
  56. *pReturnError = CPVRTString("Failed to compile shader: ") + pszInfoLog + "\n";
  57. delete [] pszInfoLog;
  58. glDeleteShader(*pObject);
  59. return PVR_FAIL;
  60. }
  61. return PVR_SUCCESS;
  62. }
  63. /*!***************************************************************************
  64. @Function PVRTShaderLoadBinaryFromMemory
  65. @Input ShaderData shader compiled binary data
  66. @Input Size size of shader binary data in bytes
  67. @Input Type type of shader (GL_VERTEX_SHADER or GL_FRAGMENT_SHADER)
  68. @Input Format shader binary format
  69. @Output pObject the resulting shader object
  70. @Output pReturnError the error message if it failed
  71. @Return PVR_SUCCESS on success and PVR_FAIL on failure (also fills the str string)
  72. @Description Takes a shader binary from memory and passes it to the GL.
  73. *****************************************************************************/
  74. EPVRTError PVRTShaderLoadBinaryFromMemory( const void* const ShaderData,
  75. const size_t Size,
  76. const GLenum Type,
  77. const GLenum Format,
  78. GLuint* const pObject,
  79. CPVRTString* const pReturnError)
  80. {
  81. /* Create and compile the shader object */
  82. *pObject = glCreateShader(Type);
  83. // Get the list of supported binary formats
  84. // and if (more then 0) find given Format among them
  85. GLint numFormats = 0;
  86. GLint *listFormats;
  87. int i;
  88. glGetIntegerv(GL_NUM_SHADER_BINARY_FORMATS,&numFormats);
  89. if(numFormats != 0) {
  90. listFormats = new GLint[numFormats];
  91. for(i=0;i<numFormats;++i)
  92. listFormats[i] = 0;
  93. glGetIntegerv(GL_SHADER_BINARY_FORMATS,listFormats);
  94. for(i=0;i<numFormats;++i) {
  95. if(listFormats[i] == (int) Format) {
  96. glShaderBinary(1, pObject, Format, ShaderData, (GLint)Size);
  97. if (glGetError() != GL_NO_ERROR)
  98. {
  99. *pReturnError = CPVRTString("Failed to load binary shader\n");
  100. glDeleteShader(*pObject);
  101. return PVR_FAIL;
  102. }
  103. return PVR_SUCCESS;
  104. }
  105. }
  106. delete [] listFormats;
  107. }
  108. *pReturnError = CPVRTString("Failed to load binary shader\n");
  109. glDeleteShader(*pObject);
  110. return PVR_FAIL;
  111. }
  112. /*!***************************************************************************
  113. @Function PVRTShaderLoadFromFile
  114. @Input pszBinFile binary shader filename
  115. @Input pszSrcFile source shader filename
  116. @Input Type type of shader (GL_VERTEX_SHADER or GL_FRAGMENT_SHADER)
  117. @Input Format shader binary format, or 0 for source shader
  118. @Output pObject the resulting shader object
  119. @Output pReturnError the error message if it failed
  120. @Input pContext Context
  121. @Input aszDefineArray Array of defines to be pre-appended to shader string
  122. @Input uiDefArraySize Size of the define array
  123. @Return PVR_SUCCESS on success and PVR_FAIL on failure (also fills pReturnError)
  124. @Description Loads a shader file into memory and passes it to the GL.
  125. It also passes defines that need to be pre-appended to the shader before compilation.
  126. *****************************************************************************/
  127. EPVRTError PVRTShaderLoadFromFile( const char* const pszBinFile,
  128. const char* const pszSrcFile,
  129. const GLenum Type,
  130. const GLenum Format,
  131. GLuint* const pObject,
  132. CPVRTString* const pReturnError,
  133. const SPVRTContext* const pContext,
  134. const char* const* aszDefineArray, GLuint uiDefArraySize)
  135. {
  136. PVRT_UNREFERENCED_PARAMETER(pContext);
  137. *pReturnError = "";
  138. /*
  139. Prepending defines relies on altering the source file that is loaded.
  140. For this reason, the function calls the source loader instead of the binary loader if defines have
  141. been passed in.
  142. */
  143. if(Format && pszBinFile && uiDefArraySize == 0)
  144. {
  145. CPVRTResourceFile ShaderFile(pszBinFile);
  146. if (ShaderFile.IsOpen())
  147. {
  148. if(PVRTShaderLoadBinaryFromMemory(ShaderFile.DataPtr(), ShaderFile.Size(), Type, Format, pObject, pReturnError) == PVR_SUCCESS)
  149. return PVR_SUCCESS;
  150. }
  151. *pReturnError += CPVRTString("Failed to open shader ") + pszBinFile + "\n";
  152. }
  153. CPVRTResourceFile ShaderFile(pszSrcFile);
  154. if (!ShaderFile.IsOpen())
  155. {
  156. *pReturnError += CPVRTString("Failed to open shader ") + pszSrcFile + "\n";
  157. return PVR_FAIL;
  158. }
  159. return PVRTShaderLoadSourceFromMemory(ShaderFile.StringPtr(), Type, pObject, pReturnError, aszDefineArray, uiDefArraySize);
  160. }
  161. /*!***************************************************************************
  162. @Function PVRTCreateProgram
  163. @Output pProgramObject the created program object
  164. @Input VertexShader the vertex shader to link
  165. @Input FragmentShader the fragment shader to link
  166. @Input pszAttribs an array of attribute names
  167. @Input i32NumAttribs the number of attributes to bind
  168. @Output pReturnError the error message if it failed
  169. @Returns PVR_SUCCESS on success, PVR_FAIL if failure
  170. @Description Links a shader program.
  171. *****************************************************************************/
  172. EPVRTError PVRTCreateProgram( GLuint* const pProgramObject,
  173. const GLuint VertexShader,
  174. const GLuint FragmentShader,
  175. const char** const pszAttribs,
  176. const int i32NumAttribs,
  177. CPVRTString* const pReturnError)
  178. {
  179. *pProgramObject = glCreateProgram();
  180. glAttachShader(*pProgramObject, FragmentShader);
  181. glAttachShader(*pProgramObject, VertexShader);
  182. for (int i = 0; i < i32NumAttribs; ++i)
  183. {
  184. glBindAttribLocation(*pProgramObject, i, pszAttribs[i]);
  185. }
  186. // Link the program object
  187. glLinkProgram(*pProgramObject);
  188. GLint Linked;
  189. glGetProgramiv(*pProgramObject, GL_LINK_STATUS, &Linked);
  190. if (!Linked)
  191. {
  192. int i32InfoLogLength, i32CharsWritten;
  193. glGetProgramiv(*pProgramObject, GL_INFO_LOG_LENGTH, &i32InfoLogLength);
  194. char* pszInfoLog = new char[i32InfoLogLength];
  195. glGetProgramInfoLog(*pProgramObject, i32InfoLogLength, &i32CharsWritten, pszInfoLog);
  196. *pReturnError = CPVRTString("Failed to link: ") + pszInfoLog + "\n";
  197. delete [] pszInfoLog;
  198. return PVR_FAIL;
  199. }
  200. glUseProgram(*pProgramObject);
  201. return PVR_SUCCESS;
  202. }
  203. /*****************************************************************************
  204. End of file (PVRTShader.cpp)
  205. *****************************************************************************/