ShaderProgramGL.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. #include "ShaderProgramGL.h"
  2. #include "VertexDeclarationGL.h"
  3. #include "oxgl.h"
  4. #ifndef __S3E__
  5. #include "SDL.h"
  6. #endif
  7. namespace oxygine
  8. {
  9. ShaderProgramGL::ShaderProgramGL(GLuint p) : _program(p)
  10. {
  11. }
  12. ShaderProgramGL::ShaderProgramGL(GLuint vs, GLuint ps, const VertexDeclarationGL* decl)
  13. {
  14. _program = createProgram(vs, ps, decl);
  15. }
  16. ShaderProgramGL::~ShaderProgramGL()
  17. {
  18. if (_program)
  19. oxglDeleteProgram(_program);
  20. CHECKGL();
  21. }
  22. unsigned int ShaderProgramGL::getID() const
  23. {
  24. return _program;
  25. }
  26. int ShaderProgramGL::getUniformLocation(const char* id) const
  27. {
  28. int i = oxglGetUniformLocation(_program, id);
  29. //if (i == -1)
  30. CHECKGL();
  31. return i;
  32. }
  33. bool ShaderProgramGL::getShaderBuildLog(GLuint shader, std::string& str)
  34. {
  35. GLint length = 0;
  36. GLint success = GL_TRUE;
  37. oxglGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length);
  38. if (length)
  39. {
  40. str.resize(length);
  41. oxglGetShaderInfoLog(shader, (int)str.size(), NULL, &str[0]);
  42. }
  43. else
  44. str.clear();
  45. GLint status = GL_TRUE;
  46. oxglGetShaderiv(shader, GL_COMPILE_STATUS, &status);
  47. return status == GL_TRUE;
  48. }
  49. bool ShaderProgramGL::getProgramBuildLog(GLuint program, std::string& str)
  50. {
  51. GLint length = 0;
  52. GLint success = GL_TRUE;
  53. oxglGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);
  54. if (length)
  55. {
  56. str.resize(length);
  57. oxglGetProgramInfoLog(program, (int)str.size(), NULL, &str[0]);
  58. }
  59. else
  60. str.clear();
  61. GLint status = GL_TRUE;
  62. oxglGetProgramiv(program, GL_LINK_STATUS, &status);
  63. return status == GL_TRUE;
  64. }
  65. unsigned int ShaderProgramGL::createShader(unsigned int type, const char* data, const char* prepend, const char* append, error_policy ep)
  66. {
  67. GLuint shader = oxglCreateShader(type);
  68. const char* sources[16];
  69. const char** ptr = &sources[0];
  70. bool gles = false;
  71. #ifdef __S3E__
  72. gles = true;
  73. #elif OXYGINE_SDL
  74. int profile = 0;
  75. SDL_GL_GetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, &profile);
  76. gles = profile == SDL_GL_CONTEXT_PROFILE_ES;
  77. #else
  78. #endif
  79. #ifndef EMSCRIPTEN
  80. if (!gles)
  81. {
  82. //log::messageln("not gles version");
  83. static const char nonGLES[] =
  84. "#define lowp\n"
  85. "#define mediump\n"
  86. "#define highp\n";
  87. *ptr = nonGLES;
  88. ptr++;
  89. }
  90. #endif
  91. #ifdef __ANDROID__
  92. *ptr = "#define ANDROID 1\n";
  93. ptr++;
  94. #endif
  95. if (prepend)
  96. {
  97. *ptr = prepend;
  98. ptr++;
  99. }
  100. *ptr = data;
  101. ptr++;
  102. if (append)
  103. {
  104. *ptr = append;
  105. ptr++;
  106. }
  107. int num = (int)(ptr - sources);
  108. oxglShaderSource(shader, num, sources, 0);
  109. oxglCompileShader(shader);
  110. std::string log;
  111. bool success = getShaderBuildLog(shader, log);
  112. if (success)
  113. {
  114. log::messageln("compiled shader: %s", log.c_str());
  115. }
  116. else
  117. {
  118. handleErrorPolicy(ep, "can't compile shader: %s", log.c_str());
  119. }
  120. checkGLError();
  121. return shader;
  122. }
  123. unsigned int ShaderProgramGL::createProgram(int vs, int fs, const VertexDeclarationGL* decl, bool deleteAttachedShaders)
  124. {
  125. int p = oxglCreateProgram();
  126. oxglAttachShader(p, vs);
  127. oxglAttachShader(p, fs);
  128. for (int i = 0; i < decl->numElements; ++i)
  129. oxglBindAttribLocation(p, decl->elements[i].index, decl->elements[i].name);
  130. oxglLinkProgram(p);
  131. std::string log;
  132. bool success = getProgramBuildLog(p, log);
  133. if (success)
  134. {
  135. //log::messageln("compiled shader: %s", log.c_str());
  136. oxglDetachShader(p, vs);
  137. oxglDetachShader(p, fs);
  138. if (deleteAttachedShaders)
  139. {
  140. oxglDeleteShader(vs);
  141. oxglDeleteShader(fs);
  142. }
  143. }
  144. else
  145. {
  146. log::error("can't link gl program: %s", log.c_str());
  147. oxglDeleteProgram(p);
  148. p = 0;
  149. }
  150. CHECKGL();
  151. return p;
  152. }
  153. }