diff options
Diffstat (limited to 'src/opengl/shaders.cpp')
| -rw-r--r-- | src/opengl/shaders.cpp | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/src/opengl/shaders.cpp b/src/opengl/shaders.cpp new file mode 100644 index 0000000..34d4e8f --- /dev/null +++ b/src/opengl/shaders.cpp @@ -0,0 +1,149 @@ +#include "shaders.hpp" + +GLuint CompileShader(std::string shader_name){ + std::ifstream shader_file; + shader_file.open(std::string(SHADERS_RESOURCES) + "/" + shader_name); + if(!shader_file.is_open()) { + std::cout << "Failed to open: " << shader_name << std::endl; + exit(EXIT_FAILURE); + } + + std::string line; + char type='\0'; + std::stringstream ss[2]; + while(getline(shader_file, line)) { + if(line.find("- Vertex Shader -") != std::string::npos){ + type='v'; + } else if(line.find("- Fragment Shader -") != std::string::npos){ + type='f'; + } + + if(type=='v') + ss[0] << line << std::endl; + else if(type=='f') + ss[1] << line << std::endl; + } + + // Create ids + GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER); + GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER); + + // Compile vertex shader + std::string vsrc=ss[0].str(); + char const * vsrc_c = vsrc.c_str(); + glShaderSource(VertexShaderID, 1, &vsrc_c, NULL); + glCompileShader(VertexShaderID); + + // Compile fragment shader + std::string fsrc=ss[1].str(); + char const * fsrc_c = fsrc.c_str(); + glShaderSource(FragmentShaderID, 1, &fsrc_c, NULL); + glCompileShader(FragmentShaderID); + + // Link programs + GLuint ProgramID = glCreateProgram(); + glAttachShader(ProgramID, VertexShaderID); + glAttachShader(ProgramID, FragmentShaderID); + glLinkProgram(ProgramID); + + // Cleaning + glDetachShader(ProgramID, VertexShaderID); + glDetachShader(ProgramID, FragmentShaderID); + glDeleteShader(VertexShaderID); + glDeleteShader(FragmentShaderID); + + return ProgramID; +} + + +GLuint LoadShaders(const char * vertex_file_path,const char * fragment_file_path){ + + // Create the shaders + GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER); + GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER); + + // Read the Vertex Shader code from the file + std::string VertexShaderCode; + std::ifstream VertexShaderStream(vertex_file_path, std::ios::in); + if(VertexShaderStream.is_open()){ + std::stringstream sstr; + sstr << VertexShaderStream.rdbuf(); + VertexShaderCode = sstr.str(); + VertexShaderStream.close(); + }else{ + printf("Impossible to open %s. Are you in the right directory ? Don't forget to read the FAQ !\n", vertex_file_path); + getchar(); + return 0; + } + + // Read the Fragment Shader code from the file + std::string FragmentShaderCode; + std::ifstream FragmentShaderStream(fragment_file_path, std::ios::in); + if(FragmentShaderStream.is_open()){ + std::stringstream sstr; + sstr << FragmentShaderStream.rdbuf(); + FragmentShaderCode = sstr.str(); + FragmentShaderStream.close(); + } + + GLint Result = GL_FALSE; + int InfoLogLength; + + + // Compile Vertex Shader + printf("Compiling shader : %s\n", vertex_file_path); + char const * VertexSourcePointer = VertexShaderCode.c_str(); + glShaderSource(VertexShaderID, 1, &VertexSourcePointer , NULL); + glCompileShader(VertexShaderID); + + // Check Vertex Shader + glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result); + glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); + if ( InfoLogLength > 0 ){ + std::vector<char> VertexShaderErrorMessage(InfoLogLength+1); + glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]); + printf("%s\n", &VertexShaderErrorMessage[0]); + } + + + + // Compile Fragment Shader + printf("Compiling shader : %s\n", fragment_file_path); + char const * FragmentSourcePointer = FragmentShaderCode.c_str(); + glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer , NULL); + glCompileShader(FragmentShaderID); + + // Check Fragment Shader + glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result); + glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); + if ( InfoLogLength > 0 ){ + std::vector<char> FragmentShaderErrorMessage(InfoLogLength+1); + glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]); + printf("%s\n", &FragmentShaderErrorMessage[0]); + } + + // Link the program + printf("Linking program\n"); + GLuint ProgramID = glCreateProgram(); + glAttachShader(ProgramID, VertexShaderID); + glAttachShader(ProgramID, FragmentShaderID); + glLinkProgram(ProgramID); + + // Check the program + glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result); + glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength); + if ( InfoLogLength > 0 ){ + std::vector<char> ProgramErrorMessage(InfoLogLength+1); + glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]); + printf("%s\n", &ProgramErrorMessage[0]); + } + + + glDetachShader(ProgramID, VertexShaderID); + glDetachShader(ProgramID, FragmentShaderID); + + glDeleteShader(VertexShaderID); + glDeleteShader(FragmentShaderID); + + return ProgramID; +} |
