Shader.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. // ----------------------------------------------------------------
  2. // From Game Programming in C++ by Sanjay Madhav
  3. // Copyright (C) 2017 Sanjay Madhav. All rights reserved.
  4. //
  5. // Released under the BSD License
  6. // See LICENSE in root directory for full details.
  7. // ----------------------------------------------------------------
  8. #include "Shader.h"
  9. #include "Texture.h"
  10. #include <SDL/SDL.h>
  11. #include <fstream>
  12. #include <sstream>
  13. Shader::Shader()
  14. : mShaderProgram(0)
  15. , mVertexShader(0)
  16. , mFragShader(0)
  17. {
  18. }
  19. Shader::~Shader()
  20. {
  21. }
  22. bool Shader::Load(const std::string& vertName, const std::string& fragName)
  23. {
  24. // Compile vertex and pixel shaders
  25. if (!CompileShader(vertName,
  26. GL_VERTEX_SHADER,
  27. mVertexShader) ||
  28. !CompileShader(fragName,
  29. GL_FRAGMENT_SHADER,
  30. mFragShader))
  31. {
  32. return false;
  33. }
  34. // Now create a shader program that
  35. // links together the vertex/frag shaders
  36. mShaderProgram = glCreateProgram();
  37. glAttachShader(mShaderProgram, mVertexShader);
  38. glAttachShader(mShaderProgram, mFragShader);
  39. glLinkProgram(mShaderProgram);
  40. // Verify that the program linked successfully
  41. if (!IsValidProgram())
  42. {
  43. return false;
  44. }
  45. return true;
  46. }
  47. void Shader::Unload()
  48. {
  49. // Delete the program/shaders
  50. glDeleteProgram(mShaderProgram);
  51. glDeleteShader(mVertexShader);
  52. glDeleteShader(mFragShader);
  53. }
  54. void Shader::SetActive()
  55. {
  56. // Set this program as the active one
  57. glUseProgram(mShaderProgram);
  58. }
  59. void Shader::SetMatrixUniform(const char* name, const Matrix4& matrix)
  60. {
  61. // Find the uniform by this name
  62. GLuint loc = glGetUniformLocation(mShaderProgram, name);
  63. // Send the matrix data to the uniform
  64. glUniformMatrix4fv(loc, 1, GL_TRUE, matrix.GetAsFloatPtr());
  65. }
  66. void Shader::SetMatrixUniforms(const char* name, Matrix4* matrices, unsigned count)
  67. {
  68. GLuint loc = glGetUniformLocation(mShaderProgram, name);
  69. // Send the matrix data to the uniform
  70. glUniformMatrix4fv(loc, count, GL_TRUE, matrices->GetAsFloatPtr());
  71. }
  72. void Shader::SetVectorUniform(const char* name, const Vector3& vector)
  73. {
  74. GLuint loc = glGetUniformLocation(mShaderProgram, name);
  75. // Send the vector data
  76. glUniform3fv(loc, 1, vector.GetAsFloatPtr());
  77. }
  78. void Shader::SetVector2Uniform(const char* name, const Vector2& vector)
  79. {
  80. GLuint loc = glGetUniformLocation(mShaderProgram, name);
  81. // Send the vector data
  82. glUniform2fv(loc, 1, vector.GetAsFloatPtr());
  83. }
  84. void Shader::SetFloatUniform(const char* name, float value)
  85. {
  86. GLuint loc = glGetUniformLocation(mShaderProgram, name);
  87. // Send the float data
  88. glUniform1f(loc, value);
  89. }
  90. void Shader::SetIntUniform(const char* name, int value)
  91. {
  92. GLuint loc = glGetUniformLocation(mShaderProgram, name);
  93. // Send the float data
  94. glUniform1i(loc, value);
  95. }
  96. bool Shader::CompileShader(const std::string& fileName,
  97. GLenum shaderType,
  98. GLuint& outShader)
  99. {
  100. // Open file
  101. std::ifstream shaderFile(fileName);
  102. if (shaderFile.is_open())
  103. {
  104. // Read all of the text into a string
  105. std::stringstream sstream;
  106. sstream << shaderFile.rdbuf();
  107. std::string contents = sstream.str();
  108. const char* contentsChar = contents.c_str();
  109. // Create a shader of the specified type
  110. outShader = glCreateShader(shaderType);
  111. // Set the source characters and try to compile
  112. glShaderSource(outShader, 1, &(contentsChar), nullptr);
  113. glCompileShader(outShader);
  114. if (!IsCompiled(outShader))
  115. {
  116. SDL_Log("Failed to compile shader %s", fileName.c_str());
  117. return false;
  118. }
  119. }
  120. else
  121. {
  122. SDL_Log("Shader file not found: %s", fileName.c_str());
  123. return false;
  124. }
  125. return true;
  126. }
  127. bool Shader::IsCompiled(GLuint shader)
  128. {
  129. GLint status;
  130. // Query the compile status
  131. glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
  132. if (status != GL_TRUE)
  133. {
  134. char buffer[512];
  135. memset(buffer, 0, 512);
  136. glGetShaderInfoLog(shader, 511, nullptr, buffer);
  137. SDL_Log("GLSL Compile Failed:\n%s", buffer);
  138. return false;
  139. }
  140. return true;
  141. }
  142. bool Shader::IsValidProgram()
  143. {
  144. GLint status;
  145. // Query the link status
  146. glGetProgramiv(mShaderProgram, GL_LINK_STATUS, &status);
  147. if (status != GL_TRUE)
  148. {
  149. char buffer[512];
  150. memset(buffer, 0, 512);
  151. glGetProgramInfoLog(mShaderProgram, 511, nullptr, buffer);
  152. SDL_Log("GLSL Link Status:\n%s", buffer);
  153. return false;
  154. }
  155. return true;
  156. }