/* * Shader.cpp * * Copyright (C) 2009 Matthias Schiffer * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License along * with this program. If not, see . */ #include "Shader.h" #include #include #include #include namespace Zoom { boost::shared_ptr Shader::load(const std::string &vertexShader, const std::string &fragmentShader) { GLhandleARB program, vs = 0, fs = 0; bool ok = false; if(!vertexShader.empty()) vs = loadShader(vertexShader, GL_VERTEX_SHADER_ARB); if(!fragmentShader.empty()) fs = loadShader(fragmentShader, GL_FRAGMENT_SHADER_ARB); program = glCreateProgramObjectARB(); if(program) { if(vs) glAttachObjectARB(program, vs); if(fs) glAttachObjectARB(program, fs); glLinkProgramARB(program); if(glGetError()) { printInfoLog(program); } else { ok = true; } if(vs) { glDeleteObjectARB(vs); } if(fs) { glDeleteObjectARB(fs); } } if(ok) return boost::shared_ptr(new Shader(program)); else return boost::shared_ptr(); } GLhandleARB Shader::loadShader(const std::string &name, GLenum type) { std::vector lines; std::ifstream file(("shader/" + name).c_str(), std::ios_base::in); if(!file.good()) return 0; while(file.good() && !file.eof()) { std::string line; std::getline(file, line); if(!line.empty()) lines.push_back(line); } boost::scoped_array strings(new const char*[lines.size()]); for(std::size_t i = 0; i < lines.size(); ++i) { strings[i] = lines[i].c_str(); } bool ok = false; GLhandleARB shader = glCreateShaderObjectARB(type); if(shader) { glShaderSourceARB(shader, lines.size(), strings.get(), 0); glCompileShaderARB(shader); if(glGetError()) { printInfoLog(shader); glDeleteObjectARB(shader); } else { ok = true; } } if(ok) return shader; else return 0; } void Shader::printInfoLog(GLhandleARB obj) { int length = 0; glGetObjectParameterivARB(obj, GL_OBJECT_INFO_LOG_LENGTH_ARB, &length); if(length > 0) { boost::scoped_array log(new char[length]); int foo; glGetInfoLogARB(obj, length, &foo, log.get()); std::cerr << log.get() << std::endl; } } }