#ifndef Magnum_Shader_h #define Magnum_Shader_h /* Copyright © 2010, 2011, 2012 Vladimír Vondruš This file is part of Magnum. Magnum is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License version 3 only, as published by the Free Software Foundation. Magnum 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 version 3 for more details. */ /** @file * @brief Class Magnum::Shader */ #include #include #include "Magnum.h" #include "Context.h" #include "magnumVisibility.h" namespace Magnum { /** @brief %Shader Allows loading and compiling the shader from file or directly from source string. See AbstractShaderProgram for more information. */ class MAGNUM_EXPORT Shader { Shader(const Shader& other) = delete; Shader& operator=(const Shader& other) = delete; public: /** @brief %Shader type */ enum class Type: GLenum { Vertex = GL_VERTEX_SHADER, /**< Vertex shader */ #ifndef MAGNUM_TARGET_GLES /** * Tessellation control shader * @requires_gl40 %Extension @extension{ARB,tessellation_shader} * @requires_gl Tessellation shaders are not available in OpenGL ES. */ TessellationControl = GL_TESS_CONTROL_SHADER, /** * Tessellation evaluation shader * @requires_gl40 %Extension @extension{ARB,tessellation_shader} * @requires_gl Tessellation shaders are not available in OpenGL ES. */ TessellationEvaluation = GL_TESS_EVALUATION_SHADER, /** * Geometry shader * @requires_gl32 %Extension @extension{ARB,geometry_shader4} * @requires_gl Geometry shaders are not available in OpenGL ES. */ Geometry = GL_GEOMETRY_SHADER, /** * Compute shader * @requires_gl43 %Extension @extension{ARB,compute_shader} * @requires_gl Compute shaders are not available in OpenGL ES. */ Compute = GL_COMPUTE_SHADER, #endif Fragment = GL_FRAGMENT_SHADER /**< Fragment shader */ }; /** @brief %Shader state */ enum class State { Initialized, /**< %Shader is loaded */ Compiled, /**< %Shader is compiled */ Failed /**< Compilation failed */ }; /** * @brief Load shader from source * @param version Target version * @param type %Shader type * @param source %Shader source * @return Shader instance * * Loads the shader from one source. Shorthand for * @code * Shader s(version, type); * s.addData(data); * @endcode * Note that it is also possible to create shader from more than one * source. */ inline static Shader fromData(Version version, Type type, const std::string& source) { Shader s(version, type); s.addSource(source); return s; } /** * @brief Load shader from file * @param version Target version * @param type %Shader type * @param filename Source filename * @return Shader instance * * Loads the shader from from one file. Shorthand for * @code * Shader s(version, type); * s.addFile(filename); * @endcode * Note that it is also possible to create shader from more than one * source. */ inline static Shader fromFile(Version version, Type type, const char* filename) { Shader s(version, type); s.addFile(filename); return s; } /** * @brief Constructor * @param version Target version * @param type %Shader type * * Creates empty OpenGL shader and adds @c \#version directive at the * beginning. Sources can be added with addSource() or addFile(). * @see fromData(), fromFile(), @fn_gl{CreateShader} */ explicit Shader(Version version, Type type); /** * @brief Destructor * * Deletes associated OpenGL shader. * @see @fn_gl{DeleteShader} */ inline ~Shader() { if(shader) glDeleteShader(shader); } /** @brief Move constructor */ Shader(Shader&& other); /** @brief Move assignment operator */ Shader& operator=(Shader&& other); /** * @brief %Shader type * * Set in constructor. */ inline Type type() const { return _type; } /** * @brief Compilation state * * Changes after calling compile(). */ inline State state() const { return _state; } /** * @brief Add shader source * @param source String with shader source * * If the shader is not compiled already, adds given source to source * list. Note that it is possible to compile shader from more than * one source. * @see addFile() */ inline void addSource(const std::string& source) { if(_state == State::Initialized) sources.push_back(source); } /** * @brief Add source file * @param filename Name of source file to read from * @return False if reading the file fails, true otherwise. * * @see addSource() */ bool addFile(const std::string& filename); /** * @brief Compile shader * @return Compiled shader or 0 if compilation failed. * * If the shader has any sources present and hasn't been compiled * before, it tries to compile it. If compilation fails or no sources * are present, returns 0. If the shader was compiled already, returns * already existing shader. * @see state(), @fn_gl{ShaderSource}, @fn_gl{CompileShader}, * @fn_gl{GetShader} with @def_gl{COMPILE_STATUS}, * @fn_gl{GetShaderInfoLog} */ GLuint compile(); private: Type _type; State _state; std::vector sources; GLuint shader; }; } #endif