#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; }