|
@@ -0,0 +1,283 @@
|
|
|
+#include "Shader.h"
|
|
|
+
|
|
|
+// Constructeurs et Destructeur
|
|
|
+
|
|
|
+Shader::Shader() : m_vertexID(0), m_fragmentID(0), m_programID(0), m_vertexSource(), m_fragmentSource()
|
|
|
+{
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+Shader::Shader(Shader const &shaderACopier)
|
|
|
+{
|
|
|
+ // Copie des fichiers sources
|
|
|
+
|
|
|
+ m_vertexSource = shaderACopier.m_vertexSource;
|
|
|
+ m_fragmentSource = shaderACopier.m_fragmentSource;
|
|
|
+
|
|
|
+
|
|
|
+ // Chargement du nouveau shader
|
|
|
+
|
|
|
+ charger();
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+Shader::Shader(std::string vertexSource, std::string fragmentSource) : m_vertexID(0), m_fragmentID(0), m_programID(0),
|
|
|
+ m_vertexSource(vertexSource), m_fragmentSource(fragmentSource)
|
|
|
+{
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+Shader::~Shader()
|
|
|
+{
|
|
|
+ // Destruction du shader
|
|
|
+
|
|
|
+ glDeleteShader(m_vertexID);
|
|
|
+ glDeleteShader(m_fragmentID);
|
|
|
+ glDeleteProgram(m_programID);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+// Méthodes
|
|
|
+
|
|
|
+Shader& Shader::operator=(Shader const &shaderACopier)
|
|
|
+{
|
|
|
+ // Copie des fichiers sources
|
|
|
+
|
|
|
+ m_vertexSource = shaderACopier.m_vertexSource;
|
|
|
+ m_fragmentSource = shaderACopier.m_fragmentSource;
|
|
|
+
|
|
|
+
|
|
|
+ // Chargement du nouveau shader
|
|
|
+
|
|
|
+ charger();
|
|
|
+
|
|
|
+
|
|
|
+ // Retour du pointeur this
|
|
|
+
|
|
|
+ return *this;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+bool Shader::charger()
|
|
|
+{
|
|
|
+ // Destruction d'un éventuel ancien Shader
|
|
|
+
|
|
|
+ if(m_vertexID!=0 && glIsShader(m_vertexID) == GL_TRUE)
|
|
|
+ glDeleteShader(m_vertexID);
|
|
|
+
|
|
|
+ if(m_fragmentID!=0 && glIsShader(m_fragmentID) == GL_TRUE)
|
|
|
+ glDeleteShader(m_fragmentID);
|
|
|
+
|
|
|
+ if(m_programID!=0 && glIsProgram(m_programID) == GL_TRUE)
|
|
|
+ glDeleteProgram(m_programID);
|
|
|
+
|
|
|
+
|
|
|
+ // Compilation des shaders
|
|
|
+
|
|
|
+ if(!compilerShader(m_vertexID, GL_VERTEX_SHADER, m_vertexSource))
|
|
|
+ return false;
|
|
|
+
|
|
|
+ if(!compilerShader(m_fragmentID, GL_FRAGMENT_SHADER, m_fragmentSource))
|
|
|
+ return false;
|
|
|
+
|
|
|
+
|
|
|
+ // Création du programme
|
|
|
+
|
|
|
+ m_programID = glCreateProgram();
|
|
|
+
|
|
|
+
|
|
|
+ // Association des shaders
|
|
|
+
|
|
|
+ glAttachShader(m_programID, m_vertexID);
|
|
|
+ glAttachShader(m_programID, m_fragmentID);
|
|
|
+
|
|
|
+
|
|
|
+ // Verrouillage des entrées shader
|
|
|
+
|
|
|
+ glBindAttribLocation(m_programID, 0, "in_Vertex");
|
|
|
+ glBindAttribLocation(m_programID, 1, "in_Color");
|
|
|
+ glBindAttribLocation(m_programID, 2, "in_TexCoord0");
|
|
|
+
|
|
|
+
|
|
|
+ // Linkage du programme
|
|
|
+
|
|
|
+ glLinkProgram(m_programID);
|
|
|
+
|
|
|
+
|
|
|
+ // Vérification du linkage
|
|
|
+
|
|
|
+ GLint erreurLink(0);
|
|
|
+ glGetProgramiv(m_programID, GL_LINK_STATUS, &erreurLink);
|
|
|
+
|
|
|
+
|
|
|
+ // S'il y a eu une erreur
|
|
|
+
|
|
|
+ if(erreurLink != GL_TRUE)
|
|
|
+ {
|
|
|
+ // Récupération de la taille de l'erreur
|
|
|
+
|
|
|
+ GLint tailleErreur(0);
|
|
|
+ glGetProgramiv(m_programID, GL_INFO_LOG_LENGTH, &tailleErreur);
|
|
|
+
|
|
|
+
|
|
|
+ // Allocation de mémoire
|
|
|
+
|
|
|
+ char *erreur = new char[tailleErreur + 1];
|
|
|
+
|
|
|
+
|
|
|
+ // Récupération de l'erreur
|
|
|
+
|
|
|
+ glGetShaderInfoLog(m_programID, tailleErreur, &tailleErreur, erreur);
|
|
|
+ erreur[tailleErreur] = '\0';
|
|
|
+
|
|
|
+
|
|
|
+ // Affichage de l'erreur
|
|
|
+
|
|
|
+ std::cout << erreur << std::endl;
|
|
|
+
|
|
|
+
|
|
|
+ // Libération de la mémoire et retour du booléen false
|
|
|
+
|
|
|
+ delete[] erreur;
|
|
|
+ glDeleteProgram(m_programID);
|
|
|
+
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ // Sinon c'est que tout s'est bien passé
|
|
|
+
|
|
|
+ else
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+bool Shader::compilerShader(GLuint &shader, GLenum type, std::string const &fichierSource)
|
|
|
+{
|
|
|
+ // Création du shader
|
|
|
+
|
|
|
+ shader = glCreateShader(type);
|
|
|
+
|
|
|
+
|
|
|
+ // Vérification du shader
|
|
|
+
|
|
|
+ if(shader == 0)
|
|
|
+ {
|
|
|
+ std::cout << "Erreur, le type de shader (" << type << ") n'existe pas" << std::endl;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ // Flux de lecture
|
|
|
+
|
|
|
+ std::ifstream fichier(fichierSource.c_str());
|
|
|
+
|
|
|
+
|
|
|
+ // Test d'ouverture
|
|
|
+
|
|
|
+ if(!fichier)
|
|
|
+ {
|
|
|
+ std::cout << "Erreur le fichier " << fichierSource << " est introuvable" << std::endl;
|
|
|
+ glDeleteShader(shader);
|
|
|
+
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ // Strings permettant de lire le code source
|
|
|
+
|
|
|
+ std::string ligne;
|
|
|
+ std::string codeSource;
|
|
|
+
|
|
|
+
|
|
|
+ // Lecture
|
|
|
+
|
|
|
+ while(getline(fichier, ligne))
|
|
|
+ codeSource += ligne + '\n';
|
|
|
+
|
|
|
+
|
|
|
+ // Fermeture du fichier
|
|
|
+
|
|
|
+ fichier.close();
|
|
|
+
|
|
|
+
|
|
|
+ // Récupération de la chaine C du code source
|
|
|
+
|
|
|
+ const GLchar* chaineCodeSource = codeSource.c_str();
|
|
|
+
|
|
|
+
|
|
|
+ // Envoi du code source au shader
|
|
|
+
|
|
|
+ glShaderSource(shader, 1, &chaineCodeSource, 0);
|
|
|
+
|
|
|
+
|
|
|
+ // Compilation du shader
|
|
|
+
|
|
|
+ glCompileShader(shader);
|
|
|
+
|
|
|
+
|
|
|
+ // Vérification de la compilation
|
|
|
+
|
|
|
+ GLint erreurCompilation(0);
|
|
|
+ glGetShaderiv(shader, GL_COMPILE_STATUS, &erreurCompilation);
|
|
|
+
|
|
|
+
|
|
|
+ // S'il y a eu une erreur
|
|
|
+
|
|
|
+ if(erreurCompilation != GL_TRUE)
|
|
|
+ {
|
|
|
+ // Récupération de la taille de l'erreur
|
|
|
+
|
|
|
+ GLint tailleErreur(0);
|
|
|
+ glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &tailleErreur);
|
|
|
+
|
|
|
+
|
|
|
+ // Allocation de mémoire
|
|
|
+
|
|
|
+ char *erreur = new char[tailleErreur + 1];
|
|
|
+
|
|
|
+
|
|
|
+ // Récupération de l'erreur
|
|
|
+
|
|
|
+ glGetShaderInfoLog(shader, tailleErreur, &tailleErreur, erreur);
|
|
|
+ erreur[tailleErreur] = '\0';
|
|
|
+
|
|
|
+
|
|
|
+ // Affichage de l'erreur
|
|
|
+
|
|
|
+ std::cout << erreur << std::endl;
|
|
|
+
|
|
|
+
|
|
|
+ // Libération de la mémoire et retour du booléen false
|
|
|
+
|
|
|
+ delete[] erreur;
|
|
|
+ glDeleteShader(shader);
|
|
|
+
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ // Sinon c'est que tout s'est bien passé
|
|
|
+
|
|
|
+ else
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
+bool Shader::chargerNouveauShader(std::string vertexSource, std::string fragmentSource)
|
|
|
+{
|
|
|
+ // Attribution du nouveau shader
|
|
|
+ m_vertexSource = vertexSource;
|
|
|
+ m_fragmentSource = fragmentSource;
|
|
|
+
|
|
|
+ // Chargement
|
|
|
+ return charger();
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+// Getter
|
|
|
+
|
|
|
+GLuint Shader::getProgramID() const
|
|
|
+{
|
|
|
+ return m_programID;
|
|
|
+}
|