void Program::Link() { GLint res; glLinkProgram( obj ); glGetProgramiv( obj, GL_LINK_STATUS, &res ); if ( res == GL_FALSE ) throw LinkException( GetInfoLog() ); }
void Shader::Compile() { GLint res; glCompileShader( obj ); glGetShaderiv( obj, GL_COMPILE_STATUS, &res ); if ( res == GL_FALSE ) throw CompileException( GetInfoLog() ); }
bool operator()() { GLint logLength; Getiv(object_, GL_INFO_LOG_LENGTH, &logLength); if (logLength) { GLchar *log = new GLchar[logLength]; GetInfoLog(object_, logLength, &logLength, log); std::cout << "GLSL: " << log << std::endl; delete [] log; return false; } return true; }
void ShaderProgram::PrintInfoLog() { std::string errStr = GetInfoLog(); std::cout << errStr << std::endl; }
ShaderSource::ShaderSource(const string& name, Type shaderType, const string& source) : mShader(glCreateShader(shaderType == Vertex ? GL_VERTEX_SHADER : GL_FRAGMENT_SHADER)) { pwnAssert_NoGLError(); if(mShader == 0) { throw "failed to create shader"; } GLint length = source.length(); const char* sourcep = source.c_str(); glShaderSource(mShader, 1, &sourcep, &length); pwnAssert_NoGLError(); glCompileShader(mShader); pwnAssert_NoGLError(); if(false == CompileStatus(mShader)) { throw static_cast<string>(core::Str() << "Shader: " << name << " failed to compile: " << GetInfoLog(mShader)); } }
// // Link // void CShadingProgram::Link() { m_UniformCache.clear(); m_SamplerUniformCache.clear(); m_BindableUniformCache.clear(); m_Samplers.clear(); glLinkProgram( m_Program ); GLint LinkStatus; glGetProgramiv( m_Program, GL_LINK_STATUS, &LinkStatus ); if (LinkStatus != GL_TRUE) { m_LastInfoLog = GetInfoLog().c_str(); throw Sys::CException( this, "::Link() : Failed to link GLSL program. See program log for more details." ); } GLint ActiveUniforms; GLint MaxLength; glGetProgramiv( m_Program, GL_ACTIVE_UNIFORMS, &ActiveUniforms ); glGetProgramiv( m_Program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &MaxLength ); vector<GLchar> Name( MaxLength, '\0' ); GLenum Unit = GL_TEXTURE0; // Получаем описание всех юниформов, и если очередной юниформ является самплером, // резервируем для него текстурный блок и заносим его и местоположение юниформа в список. for (int i = 0; i < ActiveUniforms; ++i) { GLint Size; GLenum Type; //GLint Location; glGetActiveUniform( m_Program, i, MaxLength, NULL, &Size, &Type, &Name[ 0 ] ); switch (Type) { // OpenGL 2.0 case GL_SAMPLER_1D: case GL_SAMPLER_2D: case GL_SAMPLER_3D: case GL_SAMPLER_CUBE: case GL_SAMPLER_1D_SHADOW: case GL_SAMPLER_2D_SHADOW: // GL_ARB_shader_objects/GL_ARB_texture_rectangle case GL_SAMPLER_2D_RECT_ARB: case GL_SAMPLER_2D_RECT_SHADOW_ARB: // GL_EXT_gpu_shader4 case GL_SAMPLER_1D_ARRAY_EXT: case GL_SAMPLER_2D_ARRAY_EXT: //case GL_SAMPLER_BUFFER_EXT: ? case GL_SAMPLER_1D_ARRAY_SHADOW_EXT: case GL_SAMPLER_2D_ARRAY_SHADOW_EXT: case GL_SAMPLER_CUBE_SHADOW_EXT: case GL_INT_SAMPLER_1D_EXT: case GL_INT_SAMPLER_2D_EXT: case GL_INT_SAMPLER_3D_EXT: case GL_INT_SAMPLER_CUBE_EXT: case GL_INT_SAMPLER_2D_RECT_EXT: case GL_INT_SAMPLER_1D_ARRAY_EXT: case GL_INT_SAMPLER_2D_ARRAY_EXT: //case GL_INT_SAMPLER_BUFFER_EXT: ? case GL_UNSIGNED_INT_SAMPLER_1D_EXT: case GL_UNSIGNED_INT_SAMPLER_2D_EXT: case GL_UNSIGNED_INT_SAMPLER_3D_EXT: case GL_UNSIGNED_INT_SAMPLER_CUBE_EXT: case GL_UNSIGNED_INT_SAMPLER_2D_RECT_EXT: case GL_UNSIGNED_INT_SAMPLER_1D_ARRAY_EXT: case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY_EXT: //case GL_UNSIGNED_INT_SAMPLER_BUFFER_EXT: ? if (Unit - GL_TEXTURE0 == m_Caps.MaxTextureImageUnits) throw Sys::CException( this, "::Link() : Too many active uniforms of sampler type.\nNumber of samplers exceed implementation-dependent constant GL_MAX_TEXTURE_IMAGE_UNITS." ); { GLint Location = glGetUniformLocation( m_Program, &Name[ 0 ] ); m_Samplers[ Location ] = Unit++; } break; } } }