PixelLightAPI  .
Shader.h
Go to the documentation of this file.
00001 /*********************************************************\
00002  *  File: Shader.h                                       *
00003  *
00004  *  Copyright (C) 2002-2011 The PixelLight Team (http://www.pixellight.org/)
00005  *
00006  *  This file is part of PixelLight.
00007  *
00008  *  PixelLight is free software: you can redistribute it and/or modify
00009  *  it under the terms of the GNU Lesser General Public License as published by
00010  *  the Free Software Foundation, either version 3 of the License, or
00011  *  (at your option) any later version.
00012  *
00013  *  PixelLight is distributed in the hope that it will be useful,
00014  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00016  *  GNU Lesser General Public License for more details.
00017  *
00018  *  You should have received a copy of the GNU Lesser General Public License
00019  *  along with PixelLight. If not, see <http://www.gnu.org/licenses/>.
00020 \*********************************************************/
00021 
00022 
00023 #ifndef __PLRENDERER_SHADER_H__
00024 #define __PLRENDERER_SHADER_H__
00025 #pragma once
00026 
00027 
00028 //[-------------------------------------------------------]
00029 //[ Includes                                              ]
00030 //[-------------------------------------------------------]
00031 #include <PLCore/String/String.h>
00032 #include "PLRenderer/Renderer/Resource.h"
00033 
00034 
00035 //[-------------------------------------------------------]
00036 //[ Namespace                                             ]
00037 //[-------------------------------------------------------]
00038 namespace PLRenderer {
00039 
00040 
00041 //[-------------------------------------------------------]
00042 //[ Classes                                               ]
00043 //[-------------------------------------------------------]
00044 /**
00045 *  @brief
00046 *    Abstract renderer shader resource
00047 */
00048 class Shader : public Resource {
00049 
00050 
00051     //[-------------------------------------------------------]
00052     //[ Public static functions                               ]
00053     //[-------------------------------------------------------]
00054     public:
00055         /**
00056         *  @brief
00057         *    Removes precision qualifiers from the given GLSL shader source code
00058         *
00059         *  @param[in] sSourceCode
00060         *    Shader source code, usually blank ASCII code
00061         *
00062         *  @return
00063         *    The modified GLSL shader source code
00064         *
00065         *  @remarks
00066         *    From the "The OpenGL® Shading Language" specification "Language Version: 3.30, Document Revision: 6, 11-Mar-2010"
00067         *        "Precision qualifiers are added for code portability with OpenGL ES, not for functionality. They have the
00068         *         same syntax as in OpenGL ES, as described below, but they have no semantic meaning, which includes no
00069         *         effect on the precision used to store or operate on variables."
00070         *    Although the precision qualifiers "should" have no effect when not using OpenGL ES, we noticed that some NVIDIA GPU
00071         *    drivers produced compiler errors when using precision qualifiers. Due this buggy behavior, it's recommended to
00072         *    remove the precision qualifiers before passing on the shader source code to OpenGL.
00073         */
00074         static PLRENDERER_API PLCore::String RemovePrecisionQualifiersFromGLSL(const PLCore::String &sSourceCode);
00075 
00076 
00077     //[-------------------------------------------------------]
00078     //[ Public functions                                      ]
00079     //[-------------------------------------------------------]
00080     public:
00081         /**
00082         *  @brief
00083         *    Destructor
00084         */
00085         PLRENDERER_API virtual ~Shader();
00086 
00087 
00088     //[-------------------------------------------------------]
00089     //[ Public virtual Shader functions                       ]
00090     //[-------------------------------------------------------]
00091     public:
00092         /**
00093         *  @brief
00094         *    Returns the name of the shader language the shader is using
00095         *
00096         *  @return
00097         *    The name of the shader language the shader is using (for example "GLSL" or "Cg")
00098         */
00099         virtual PLCore::String GetShaderLanguage() const = 0;
00100 
00101         /**
00102         *  @brief
00103         *    Returns the shader source code
00104         *
00105         *  @return
00106         *    The shader source code
00107         */
00108         virtual PLCore::String GetSourceCode() const = 0;
00109 
00110         /**
00111         *  @brief
00112         *    Returns the name of the shader profile the shader is using
00113         *
00114         *  @return
00115         *    The name of the shader profile the shader is using (for example "arbvp1")
00116         */
00117         virtual PLCore::String GetProfile() const = 0;
00118 
00119         /**
00120         *  @brief
00121         *    Returns the name of the shader entry point the shader is using
00122         *
00123         *  @return
00124         *    The name of the shader entry point the shader is using (for example "main")
00125         */
00126         virtual PLCore::String GetEntry() const = 0;
00127 
00128         /**
00129         *  @brief
00130         *    Sets the shader source code
00131         *
00132         *  @param[in] sSourceCode
00133         *    Shader source code, usually blank ASCII code
00134         *  @param[in] sProfile
00135         *    Shader profile to use, if empty string, a default profile will be used which usually
00136         *    tries to use the best available profile that runs on most hardware
00137         *  @param[in] sEntry
00138         *    Entry point, if empty string, "main" is used as default
00139         *
00140         *  @return
00141         *    'true' if all went fine, else 'false'
00142         *
00143         *  @remarks
00144         *    'sProfile' is not supported by each shader-API and is in general shader-API dependent. GLSL doesn't have such
00145         *    profiles, just something named "version" - one has to directly write into the shader. But even when this information
00146         *    is not used for compiling the GLSL shader, we highly recommend to provide GLSL version information in the form of e.g.
00147         *    "130" for OpenGL 3.0 shaders ("#version 130"). Within Cg, a basic vertex profile may be "arbvp1" and a basic
00148         *    fragment profile "arbfp1". Cg also provides GLSL profiles: "glslv" for vertex shader, "glslg" for geometry shader and
00149         *    "glslf" for fragment shader.
00150         *    Please note that the profile is just a hint, if necessary, the implementation is free to choose another profile.
00151         *    In general, be carefully when explicitly setting a profile - when using Cg, and one of the shaders, a GPU program
00152         *    is composed of, is a GLSL profile like "glslv", all other shaders must use GLSL profiles as well!
00153         *
00154         *   'sEntry' is not supported by each shader-API. GLSL doesn't have such an user defined entry point and the main
00155         *   function must always be "main". Cg supports entry points with names other than "main".
00156         *
00157         *   Look out! When working with shaders you have to be prepared that a shader may work on one system, but fails to even
00158         *   compile on another one. Sadly, even if there are e.g. official GLSL specifications, you CAN'T be sure that every
00159         *   GPU driver is implementing them in detail. Here are some pitfalls which already produced some headaches...
00160         *
00161         *   When using GLSL, don't forget to provide the #version directive! Quote from
00162         *     "The OpenGL® Shading Language - Language Version: 3.30 - Document Revision: 6 - 11-Mar-2010" Page 14
00163         *       "Version 1.10 of the language does not require shaders to include this directive, and shaders that do not include
00164         *        a #version directive will be treated as targeting version 1.10."
00165         *   It looks like that AMD/ATI drivers ("AMD Catalyst™ 11.3") are NOT using just version 1.10 if there's no #version directive, but a higher
00166         *   version... so don't trust your GPU driver when your GLSL code, using modern language features, also works for you without
00167         *   #version directive, because it may not on other systems! OpenGL version and GLSL version can be a bit confusing, so
00168         *   here's a version table:
00169         *     GLSL #version    OpenGL version    Some comments
00170         *     110              2.0
00171         *     120              2.1
00172         *     130              3.0               Precision qualifiers added
00173         *                                        "attribute" deprecated; linkage between a vertex shader and OpenGL for per-vertex data -> use "in" instead
00174         *                                        "varying"/"centroid varying" deprecated; linkage between a vertex shader and a fragment shader for interpolated data -> use "in"/"out" instead
00175         *     140              3.1
00176         *     150              3.2
00177         *     330              3.3
00178         *     400              4.0
00179         *     410              4.1
00180         *  #version must occur before any other statement in the program as stated within:
00181         *    "The OpenGL® Shading Language - Language Version: 3.30 - Document Revision: 6 - 11-Mar-2010" Page 15
00182         *      "The #version directive must occur in a shader before anything else, except for comments and white space."
00183         *  ... sadly, this time NVIDIA (driver: "266.58 WHQL") is not implementing the specification in detail and while on AMD/ATI drivers ("AMD Catalyst™ 11.3")
00184         *  you get the error message "error(#105) #version must occur before any other statement in the program" when breaking specification,
00185         *  NVIDIA just accepts it without any error.
00186         *
00187         *  Enough on GLSL - now to Cg. Sadly, in general Cg is on AMD/ATI GPU's just poor due to the lack of modern profiles. When using Cg on none NVIDIA
00188         *  GPU's you have virtually no other change then using the GLSL profiles in order to write shaders using modern features. While the concept of Cg is
00189         *  fantastic, this lack of modern none NVIDIA profiles destroys many of Cg's advantages...
00190         */
00191         virtual bool SetSourceCode(const PLCore::String &sSourceCode, const PLCore::String &sProfile = "", const PLCore::String &sEntry = "") = 0;
00192 
00193 
00194     //[-------------------------------------------------------]
00195     //[ Protected functions                                   ]
00196     //[-------------------------------------------------------]
00197     protected:
00198         /**
00199         *  @brief
00200         *    Constructor
00201         *
00202         *  @param[in] cRenderer
00203         *    Owner renderer
00204         *  @param[in] nType
00205         *    Resource type
00206         */
00207         PLRENDERER_API Shader(Renderer &cRenderer, EType nType);
00208 
00209 
00210     //[-------------------------------------------------------]
00211     //[ Private functions                                     ]
00212     //[-------------------------------------------------------]
00213     private:
00214         /**
00215         *  @brief
00216         *    Copy constructor
00217         *
00218         *  @param[in] cSource
00219         *    Source to copy from
00220         */
00221         Shader(const Shader &cSource);
00222 
00223         /**
00224         *  @brief
00225         *    Copy operator
00226         *
00227         *  @param[in] cSource
00228         *    Source to copy from
00229         *
00230         *  @return
00231         *    Reference to this instance
00232         */
00233         Shader &operator =(const Shader &cSource);
00234 
00235 
00236 };
00237 
00238 
00239 //[-------------------------------------------------------]
00240 //[ Namespace                                             ]
00241 //[-------------------------------------------------------]
00242 } // PLRenderer
00243 
00244 
00245 #endif // __PLRENDERER_SHADER_H__


PixelLight PixelLight 0.9.10-R1
Copyright (C) 2002-2011 by The PixelLight Team
Last modified Fri Dec 23 2011 15:51:01
The content of this PixelLight document is published under the
Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported