Shader.cpp 5.0 KB

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