Shader.cpp 4.9 KB

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