PixelLightAPI
.
|
00001 /*********************************************************\ 00002 * File: Shader.h * 00003 * 00004 * Copyright (C) 2002-2012 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 optional shader compiler arguments the shader is using 00122 * 00123 * @return 00124 * The optional shader compiler arguments the shader is using (for example "version=150" when using Cg and a "glslv"/"glslg"/"glslf" profile) 00125 */ 00126 virtual PLCore::String GetArguments() const = 0; 00127 00128 /** 00129 * @brief 00130 * Returns the name of the shader entry point the shader is using 00131 * 00132 * @return 00133 * The name of the shader entry point the shader is using (for example "main") 00134 */ 00135 virtual PLCore::String GetEntry() const = 0; 00136 00137 /** 00138 * @brief 00139 * Sets the shader source code 00140 * 00141 * @param[in] sSourceCode 00142 * Shader source code, usually blank ASCII code 00143 * @param[in] sProfile 00144 * Shader profile to use, if empty string, a default profile will be used which usually 00145 * tries to use the best available profile that runs on most hardware 00146 * @param[in] sArguments 00147 * Optional shader compiler arguments, e.g. "version=150" when using Cg and a "glslv"/"glslg"/"glslf" profile 00148 * @param[in] sEntry 00149 * Entry point, if empty string, "main" is used as default 00150 * 00151 * @return 00152 * 'true' if all went fine, else 'false' 00153 * 00154 * @remarks 00155 * 'sProfile' is not supported by each shader-API and is in general shader-API dependent. GLSL doesn't have such 00156 * profiles, just something named "version" - one has to directly write into the shader. But even when this information 00157 * is not used for compiling the GLSL shader, we highly recommend to provide GLSL version information in the form of e.g. 00158 * "130" for OpenGL 3.0 shaders ("#version 130"). Within Cg, a basic vertex profile may be "arbvp1" and a basic 00159 * fragment profile "arbfp1". Cg also provides GLSL profiles: "glslv" for vertex shader, "glslg" for geometry shader and 00160 * "glslf" for fragment shader. 00161 * Please note that the profile is just a hint, if necessary, the implementation is free to choose another profile. 00162 * In general, be carefully when explicitly setting a profile - when using Cg, and one of the shaders, a GPU program 00163 * is composed of, is a GLSL profile like "glslv", all other shaders must use GLSL profiles as well! 00164 * 00165 * 'sEntry' is not supported by each shader-API. GLSL doesn't have such an user defined entry point and the main 00166 * function must always be "main". Cg supports entry points with names other than "main". 00167 * 00168 * Look out! When working with shaders you have to be prepared that a shader may work on one system, but fails to even 00169 * compile on another one. Sadly, even if there are e.g. official GLSL specifications, you CAN'T be sure that every 00170 * GPU driver is implementing them in detail. Here are some pitfalls which already produced some headaches... 00171 * 00172 * When using GLSL, don't forget to provide the #version directive! Quote from 00173 * "The OpenGL® Shading Language - Language Version: 3.30 - Document Revision: 6 - 11-Mar-2010" Page 14 00174 * "Version 1.10 of the language does not require shaders to include this directive, and shaders that do not include 00175 * a #version directive will be treated as targeting version 1.10." 00176 * 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 00177 * version... so don't trust your GPU driver when your GLSL code, using modern language features, also works for you without 00178 * #version directive, because it may not on other systems! OpenGL version and GLSL version can be a bit confusing, so 00179 * here's a version table: 00180 * GLSL #version OpenGL version Some comments 00181 * 110 2.0 00182 * 120 2.1 00183 * 130 3.0 Precision qualifiers added 00184 * "attribute" deprecated; linkage between a vertex shader and OpenGL for per-vertex data -> use "in" instead 00185 * "varying"/"centroid varying" deprecated; linkage between a vertex shader and a fragment shader for interpolated data -> use "in"/"out" instead 00186 * 140 3.1 00187 * 150 3.2 00188 * 330 3.3 00189 * 400 4.0 00190 * 410 4.1 00191 * #version must occur before any other statement in the program as stated within: 00192 * "The OpenGL® Shading Language - Language Version: 3.30 - Document Revision: 6 - 11-Mar-2010" Page 15 00193 * "The #version directive must occur in a shader before anything else, except for comments and white space." 00194 * ... 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") 00195 * you get the error message "error(#105) #version must occur before any other statement in the program" when breaking specification, 00196 * NVIDIA just accepts it without any error. 00197 * 00198 * 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 00199 * 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 00200 * fantastic, this lack of modern none NVIDIA profiles destroys many of Cg's advantages... 00201 */ 00202 virtual bool SetSourceCode(const PLCore::String &sSourceCode, const PLCore::String &sProfile = "", const PLCore::String &sArguments = "", const PLCore::String &sEntry = "") = 0; 00203 00204 00205 //[-------------------------------------------------------] 00206 //[ Protected functions ] 00207 //[-------------------------------------------------------] 00208 protected: 00209 /** 00210 * @brief 00211 * Constructor 00212 * 00213 * @param[in] cRenderer 00214 * Owner renderer 00215 * @param[in] nType 00216 * Resource type 00217 */ 00218 PLRENDERER_API Shader(Renderer &cRenderer, EType nType); 00219 00220 00221 //[-------------------------------------------------------] 00222 //[ Private functions ] 00223 //[-------------------------------------------------------] 00224 private: 00225 /** 00226 * @brief 00227 * Copy constructor 00228 * 00229 * @param[in] cSource 00230 * Source to copy from 00231 */ 00232 Shader(const Shader &cSource); 00233 00234 /** 00235 * @brief 00236 * Copy operator 00237 * 00238 * @param[in] cSource 00239 * Source to copy from 00240 * 00241 * @return 00242 * Reference to this instance 00243 */ 00244 Shader &operator =(const Shader &cSource); 00245 00246 00247 }; 00248 00249 00250 //[-------------------------------------------------------] 00251 //[ Namespace ] 00252 //[-------------------------------------------------------] 00253 } // PLRenderer 00254 00255 00256 #endif // __PLRENDERER_SHADER_H__
|