Shader.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  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::SetVectorUniform(const char* name, const Vector3& vector)
  67. {
  68. GLuint loc = glGetUniformLocation(mShaderProgram, name);
  69. // Send the vector data
  70. glUniform3fv(loc, 1, vector.GetAsFloatPtr());
  71. }
  72. void Shader::SetFloatUniform(const char* name, float value)
  73. {
  74. GLuint loc = glGetUniformLocation(mShaderProgram, name);
  75. // Send the float data
  76. glUniform1f(loc, value);
  77. }
  78. bool Shader::CompileShader(const std::string& fileName,
  79. GLenum shaderType,
  80. GLuint& outShader)
  81. {
  82. // Open file
  83. std::ifstream shaderFile(fileName);
  84. if (shaderFile.is_open())
  85. {
  86. // Read all the text into a string
  87. std::stringstream sstream;
  88. sstream << shaderFile.rdbuf();
  89. std::string contents = sstream.str();
  90. const char* contentsChar = contents.c_str();
  91. // Create a shader of the specified type
  92. outShader = glCreateShader(shaderType);
  93. // Set the source characters and try to compile
  94. glShaderSource(outShader, 1, &(contentsChar), nullptr);
  95. glCompileShader(outShader);
  96. if (!IsCompiled(outShader))
  97. {
  98. SDL_Log("Failed to compile shader %s", fileName.c_str());
  99. return false;
  100. }
  101. }
  102. else
  103. {
  104. SDL_Log("Shader file not found: %s", fileName.c_str());
  105. return false;
  106. }
  107. return true;
  108. }
  109. bool Shader::IsCompiled(GLuint shader)
  110. {
  111. GLint status;
  112. // Query the compile status
  113. glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
  114. if (status != GL_TRUE)
  115. {
  116. char buffer[512];
  117. memset(buffer, 0, 512);
  118. glGetShaderInfoLog(shader, 511, nullptr, buffer);
  119. SDL_Log("GLSL Compile Failed:\n%s", buffer);
  120. return false;
  121. }
  122. return true;
  123. }
  124. bool Shader::IsValidProgram()
  125. {
  126. GLint status;
  127. // Query the link status
  128. glGetProgramiv(mShaderProgram, GL_LINK_STATUS, &status);
  129. if (status != GL_TRUE)
  130. {
  131. char buffer[512];
  132. memset(buffer, 0, 512);
  133. glGetProgramInfoLog(mShaderProgram, 511, nullptr, buffer);
  134. SDL_Log("GLSL Link Status:\n%s", buffer);
  135. return false;
  136. }
  137. return true;
  138. }