Shader.cpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. #include "Shader.h"
  2. // Constructeurs et Destructeur
  3. Shader::Shader() : m_vertexID(0), m_fragmentID(0), m_programID(0), m_vertexSource(), m_fragmentSource()
  4. {
  5. }
  6. Shader::Shader(Shader const &shaderACopier)
  7. {
  8. // Copie des fichiers sources
  9. m_vertexSource = shaderACopier.m_vertexSource;
  10. m_fragmentSource = shaderACopier.m_fragmentSource;
  11. // Chargement du nouveau shader
  12. charger();
  13. }
  14. Shader::Shader(std::string vertexSource, std::string fragmentSource) : m_vertexID(0), m_fragmentID(0), m_programID(0),
  15. m_vertexSource(vertexSource), m_fragmentSource(fragmentSource)
  16. {
  17. }
  18. Shader::~Shader()
  19. {
  20. // Destruction du shader
  21. glDeleteShader(m_vertexID);
  22. glDeleteShader(m_fragmentID);
  23. glDeleteProgram(m_programID);
  24. }
  25. // Méthodes
  26. Shader& Shader::operator=(Shader const &shaderACopier)
  27. {
  28. // Copie des fichiers sources
  29. m_vertexSource = shaderACopier.m_vertexSource;
  30. m_fragmentSource = shaderACopier.m_fragmentSource;
  31. // Chargement du nouveau shader
  32. charger();
  33. // Retour du pointeur this
  34. return *this;
  35. }
  36. bool Shader::charger()
  37. {
  38. // Destruction d'un éventuel ancien Shader
  39. if(m_vertexID!=0 && glIsShader(m_vertexID) == GL_TRUE)
  40. glDeleteShader(m_vertexID);
  41. if(m_fragmentID!=0 && glIsShader(m_fragmentID) == GL_TRUE)
  42. glDeleteShader(m_fragmentID);
  43. if(m_programID!=0 && glIsProgram(m_programID) == GL_TRUE)
  44. glDeleteProgram(m_programID);
  45. // Compilation des shaders
  46. if(!compilerShader(m_vertexID, GL_VERTEX_SHADER, m_vertexSource))
  47. return false;
  48. if(!compilerShader(m_fragmentID, GL_FRAGMENT_SHADER, m_fragmentSource))
  49. return false;
  50. // Création du programme
  51. m_programID = glCreateProgram();
  52. // Association des shaders
  53. glAttachShader(m_programID, m_vertexID);
  54. glAttachShader(m_programID, m_fragmentID);
  55. // Verrouillage des entrées shader
  56. glBindAttribLocation(m_programID, 0, "in_Vertex");
  57. glBindAttribLocation(m_programID, 1, "in_Color");
  58. glBindAttribLocation(m_programID, 2, "in_TexCoord0");
  59. // Linkage du programme
  60. glLinkProgram(m_programID);
  61. // Vérification du linkage
  62. GLint erreurLink(0);
  63. glGetProgramiv(m_programID, GL_LINK_STATUS, &erreurLink);
  64. // S'il y a eu une erreur
  65. if(erreurLink != GL_TRUE)
  66. {
  67. // Récupération de la taille de l'erreur
  68. GLint tailleErreur(0);
  69. glGetProgramiv(m_programID, GL_INFO_LOG_LENGTH, &tailleErreur);
  70. // Allocation de mémoire
  71. char *erreur = new char[tailleErreur + 1];
  72. // Récupération de l'erreur
  73. glGetShaderInfoLog(m_programID, tailleErreur, &tailleErreur, erreur);
  74. erreur[tailleErreur] = '\0';
  75. // Affichage de l'erreur
  76. std::cout << erreur << std::endl;
  77. // Libération de la mémoire et retour du booléen false
  78. delete[] erreur;
  79. glDeleteProgram(m_programID);
  80. return false;
  81. }
  82. // Sinon c'est que tout s'est bien passé
  83. else
  84. return true;
  85. }
  86. bool Shader::compilerShader(GLuint &shader, GLenum type, std::string const &fichierSource)
  87. {
  88. // Création du shader
  89. shader = glCreateShader(type);
  90. // Vérification du shader
  91. if(shader == 0)
  92. {
  93. std::cout << "Erreur, le type de shader (" << type << ") n'existe pas" << std::endl;
  94. return false;
  95. }
  96. // Flux de lecture
  97. std::ifstream fichier(fichierSource.c_str());
  98. // Test d'ouverture
  99. if(!fichier)
  100. {
  101. std::cout << "Erreur le fichier " << fichierSource << " est introuvable" << std::endl;
  102. glDeleteShader(shader);
  103. return false;
  104. }
  105. // Strings permettant de lire le code source
  106. std::string ligne;
  107. std::string codeSource;
  108. // Lecture
  109. while(getline(fichier, ligne))
  110. codeSource += ligne + '\n';
  111. // Fermeture du fichier
  112. fichier.close();
  113. // Récupération de la chaine C du code source
  114. const GLchar* chaineCodeSource = codeSource.c_str();
  115. // Envoi du code source au shader
  116. glShaderSource(shader, 1, &chaineCodeSource, 0);
  117. // Compilation du shader
  118. glCompileShader(shader);
  119. // Vérification de la compilation
  120. GLint erreurCompilation(0);
  121. glGetShaderiv(shader, GL_COMPILE_STATUS, &erreurCompilation);
  122. // S'il y a eu une erreur
  123. if(erreurCompilation != GL_TRUE)
  124. {
  125. // Récupération de la taille de l'erreur
  126. GLint tailleErreur(0);
  127. glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &tailleErreur);
  128. // Allocation de mémoire
  129. char *erreur = new char[tailleErreur + 1];
  130. // Récupération de l'erreur
  131. glGetShaderInfoLog(shader, tailleErreur, &tailleErreur, erreur);
  132. erreur[tailleErreur] = '\0';
  133. // Affichage de l'erreur
  134. std::cout << erreur << std::endl;
  135. // Libération de la mémoire et retour du booléen false
  136. delete[] erreur;
  137. glDeleteShader(shader);
  138. return false;
  139. }
  140. // Sinon c'est que tout s'est bien passé
  141. else
  142. return true;
  143. }
  144. bool Shader::chargerNouveauShader(std::string vertexSource, std::string fragmentSource)
  145. {
  146. // Attribution du nouveau shader
  147. m_vertexSource = vertexSource;
  148. m_fragmentSource = fragmentSource;
  149. // Chargement
  150. return charger();
  151. }
  152. // Getter
  153. GLuint Shader::getProgramID() const
  154. {
  155. return m_programID;
  156. }