PixelLightAPI
.
|
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__
|