Shader.cpp 3.1 KB

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