void CShader::Link() { CheckedGLCall(glBindFragDataLocation(Handle, 0, "outColor")); CheckedGLCall(glLinkProgram(Handle)); int LinkStatus; CheckedGLCall(glGetProgramiv(Handle, GL_LINK_STATUS, & LinkStatus)); if (LinkStatus) { Linked = true; // Load active uniforms int ActiveUniforms = 0; int ActiveUniformMaxLength = 0; CheckedGLCall(glGetProgramiv(Handle, GL_ACTIVE_UNIFORMS, & ActiveUniforms)); CheckedGLCall(glGetProgramiv(Handle, GL_ACTIVE_UNIFORM_MAX_LENGTH, & ActiveUniformMaxLength)); for (int i = 0; i < ActiveUniforms; ++ i) { int Length = -1, Size = -1; uint DataType; char * Name = new char[ActiveUniformMaxLength + 1](); CheckedGLCall(glGetActiveUniform(Handle, i, ActiveUniformMaxLength, & Length, & Size, & DataType, Name)); Uniforms[Name] = glGetUniformLocation(Handle, Name); delete[] Name; } // Load active attributes int ActiveAttributes = 0; int ActiveAttributeMaxLength = 0; CheckedGLCall(glGetProgramiv(Handle, GL_ACTIVE_ATTRIBUTES, & ActiveAttributes)); CheckedGLCall(glGetProgramiv(Handle, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, & ActiveAttributeMaxLength)); for (GLint i = 0; i < ActiveAttributes; ++ i) { int Length = -1, Size = -1; uint DataType; char * Name = new char[ActiveAttributeMaxLength + 1]; CheckedGLCall(glGetActiveAttrib(Handle, i, ActiveAttributeMaxLength, & Length, & Size, & DataType, Name)); Attributes[Name] = std::make_pair(glGetAttribLocation(Handle, Name), DataType); delete[] Name; } } else { Log::Error("Failed to link shader program."); PrintProgramInfoLog(Handle); } }
//-------------------------------------------------------------- // Create shader from shader program files //-------------------------------------------------------------- bool Shader::CreateShader(const char* shadName) { vertShaderId = glCreateShader(GL_VERTEX_SHADER); fragShaderId = glCreateShader(GL_FRAGMENT_SHADER); shaderName = shadName; string prefix("Src\\"); string suffixVert(".vs"); string suffixFrag(".fs"); string pathVertShader = prefix; pathVertShader += shaderName; pathVertShader += suffixVert; //pathVertShader = prefix + shaderName + suffixVert; string pathFragShader = prefix; pathFragShader += shaderName; pathFragShader += suffixFrag; ReadSource(vertShaderId, pathVertShader.c_str()); ReadSource(fragShaderId, pathFragShader.c_str()); CompileSource(vertShaderId, "vertex"); CompileSource(fragShaderId, "fragment"); // Create the shader program object shaderProgId = glCreateProgram(); // Attach the shader objects to the shader program object glAttachShader(shaderProgId, vertShaderId); glAttachShader(shaderProgId, fragShaderId); // Delete the shader objects glDeleteShader(vertShaderId); glDeleteShader(fragShaderId); // Link the shader program object to the application glLinkProgram(shaderProgId); GLint linked; glGetProgramiv(shaderProgId, GL_LINK_STATUS, &linked); if ( linked == GL_FALSE ) { cerr << "Link error : " << shaderName.c_str() << endl; return false; } PrintProgramInfoLog(); return true; }
void LoadShaders(GLenum& program, const std::string& vert_shader_fn, const std::string& frag_shader_fn) { log_file << "===================" << std::endl; log_file << "Building Shader" << std::endl; log_file << "vertex shader: " << vert_shader_fn << std::endl; log_file << "fragment shader: " << frag_shader_fn << std::endl; log_file << "Loading source..."; std::string vertex_shader_source = GetShaderSource(vert_shader_fn); std::string fragment_shader_source = GetShaderSource(frag_shader_fn); log_file << "done." << std::endl; // Create Shader And Program Objects program = glCreateProgramObjectARB(); GLenum vertex_shader = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB); GLenum fragment_shader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB); // Load Shader Sources char* temp = (char*)vertex_shader_source.c_str(); glShaderSourceARB(vertex_shader, 1, (const GLcharARB**)&temp, NULL); temp = (char*)fragment_shader_source.c_str(); glShaderSourceARB(fragment_shader, 1, (const GLcharARB**)&temp, NULL); // Compile The Shaders log_file << "Compiling..."; glCompileShaderARB(vertex_shader); glCompileShaderARB(fragment_shader); log_file << "done." << std::endl; // Attach The Shader Objects To The Program Object glAttachObjectARB(program, vertex_shader); glAttachObjectARB(program, fragment_shader); // Link The Program Object log_file << "Linking..."; glLinkProgramARB(program); log_file << "done." << std::endl; PrintProgramInfoLog(program); // PrintShaderInfoLog(program); log_file << "===================" << std::endl; }
Shader::Shader(const std::string& vertex_shader_source, const std::string& fragment_shader_source) :program(0), vertex_shader(0), fragment_shader(0) { // Create Shader And Program Objects program = glCreateProgram(); vertex_shader = glCreateShader(GL_VERTEX_SHADER); fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); // Load Shader Sources char* temp = (char*)vertex_shader_source.c_str(); glShaderSource(vertex_shader, 1, (const char**)&temp, NULL); temp = (char*)fragment_shader_source.c_str(); glShaderSource(fragment_shader, 1, (const char**)&temp, NULL); // Compile The Shaders fprintf(stderr, "Compiling..."); glCompileShader(vertex_shader); PrintShaderInfoLog(vertex_shader); glCompileShader(fragment_shader); PrintShaderInfoLog(fragment_shader); fprintf(stderr, "done.\n"); // Attach The Shader Objects To The Program Object glAttachShader(program, vertex_shader); glAttachShader(program, fragment_shader); // Link The Program Object fprintf(stderr, "Linking..."); glLinkProgram(program); fprintf(stderr, "done.\n"); PrintProgramInfoLog(program); fprintf(stderr, "===================\n"); checkGLError(); }
int Shader::CompileProgram(const char* vs, const char* fs, const char* gs) { vertSrc = vs; fragSrc = fs; geomSrc = gs; const GLchar* vertexShaderSrc = (const GLchar*) vertSrc; const GLchar* fragmentShaderSrc = (const GLchar*) fragSrc; const GLchar* geometryShaderSrc = (const GLchar*) geomSrc; DeleteFile("shader_vertex.log"); DeleteFile("shader_fragment.log"); DeleteFile("shader_geometry.log"); DeleteFile("shader_link.log"); DeleteFile("shader_validation.log"); GLenum vertexShader = 0; GLenum fragmentShader = 0; GLenum geometryShader = 0; if(!vertSrc.IsEmpty()) { vertexShader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertexShader, 1, &vertexShaderSrc, NULL); glCompileShader(vertexShader); if(!IsProgramCompiled(vertexShader)) { PrintShaderInfoLog(vertexShader, "shader_vertex.log"); error = "Vertex shader compilation error:\n\n" + compileError; glDeleteShader(vertexShader); return -1; } } if(!fragSrc.IsEmpty()) { fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragmentShader, 1, &fragmentShaderSrc, NULL); glCompileShader(fragmentShader); if(!IsProgramCompiled(fragmentShader)) { PrintShaderInfoLog(fragmentShader, "shader_fragment.log"); error = "Fragment shader compilation error:\n\n" + compileError; glDeleteShader(fragmentShader); return -1; } } if(!geomSrc.IsEmpty()) { geometryShader = glCreateShader(GL_GEOMETRY_SHADER); glShaderSource(geometryShader, 1, &geometryShaderSrc, NULL); glCompileShader(geometryShader); if(!IsProgramCompiled(geometryShader)) { PrintShaderInfoLog(geometryShader, "shader_geometry.log"); error = "Geometry shader compilation error:\n\n" + compileError; glDeleteShader(geometryShader); return -1; } } program = glCreateProgram(); if(program > 0) { if(vertexShader > 0) glAttachShader(program, vertexShader); if(fragmentShader > 0) glAttachShader(program, fragmentShader); if(geometryShader > 0) glAttachShader(program, geometryShader); glLinkProgram(program); if(!IsProgramLinked(program)) { PrintProgramInfoLog(program, "shader_link.log"); PrintProgramValidationLog(program, "shader_validation.log"); glDeleteProgram(program); program = -1; } } else program = -1; return program; }