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