00001 /* 00002 ----------------------------------------------------------------------------- 00003 This source file is part of OGRE 00004 (Object-oriented Graphics Rendering Engine) 00005 For the latest info, see http://www.ogre3d.org/ 00006 00007 Copyright © 2000-2003 The OGRE Team 00008 Also see acknowledgements in Readme.html 00009 00010 This program is free software you can redistribute it and/or modify it under 00011 the terms of the GNU Lesser General Public License as published by the Free Software 00012 Foundation either version 2 of the License, or (at your option) any later 00013 version. 00014 00015 This program is distributed in the hope that it will be useful, but WITHOUT 00016 ANY WARRANTY without even the implied warranty of MERCHANTABILITY or FITNESS 00017 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 00018 00019 You should have received a copy of the GNU Lesser General Public License along with 00020 this program if not, write to the Free Software Foundation, Inc., 59 Temple 00021 Place - Suite 330, Boston, MA 02111-1307, USA, or go to 00022 http://www.gnu.org/copyleft/lesser.txt. 00023 ----------------------------------------------------------------------------- 00024 */ 00025 #include "OgreGpuProgram.h" 00026 #include "OgreRoot.h" 00027 #include "OgreRenderSystem.h" 00028 #include "OgreRenderSystemCapabilities.h" 00029 #include "OgreStringConverter.h" 00030 #include "OgreGpuProgramManager.h" 00031 #include "OgreHighLevelGpuProgramManager.h" 00032 00033 #include "OgreGLSLProgram.h" 00034 #include "OgreGLSLGpuProgram.h" 00035 #include "OgreGLSLExtSupport.h" 00036 00037 namespace Ogre { 00038 00039 //----------------------------------------------------------------------- 00040 GLSLProgram::CmdAttach GLSLProgram::msCmdAttach; 00041 //----------------------------------------------------------------------- 00042 //--------------------------------------------------------------------------- 00043 void GLSLProgram::loadFromSource(void) 00044 { 00045 const char* SLSource = mSource.c_str(); 00046 glShaderSourceARB_ptr(mGLHandle, 1, &SLSource, NULL); 00047 // check for load errors 00048 checkForGLSLError( "GLSLProgram::loadFromSource", "Cannot load GLSL high-level shader source : " + mName, 0 ); 00049 00050 compile(); 00051 } 00052 00053 //--------------------------------------------------------------------------- 00054 bool GLSLProgram::compile(const bool checkErrors) 00055 { 00056 00057 glCompileShaderARB_ptr(mGLHandle); 00058 // check for compile errors 00059 glGetObjectParameterivARB_ptr(mGLHandle, GL_OBJECT_COMPILE_STATUS_ARB, &mCompiled); 00060 // force exception if not compiled 00061 if (checkErrors) 00062 { 00063 checkForGLSLError( "GLSLProgram::loadFromSource", "Cannot compile GLSL high-level shader : " + mName + " ", mGLHandle, !mCompiled, !mCompiled ); 00064 00065 if (mCompiled) 00066 { 00067 logObjectInfo( mName + " : GLSL compiled ", mGLHandle ); 00068 } 00069 } 00070 return (mCompiled == 1); 00071 00072 } 00073 00074 //----------------------------------------------------------------------- 00075 void GLSLProgram::createLowLevelImpl(void) 00076 { 00077 mAssemblerProgram = new GLSLGpuProgram( this ); 00078 } 00079 00080 //----------------------------------------------------------------------- 00081 void GLSLProgram::unloadImpl(void) 00082 { 00083 if (isSupported()) 00084 { 00085 glDeleteObjectARB_ptr(mGLHandle); 00086 } 00087 00088 // should we do this here? 00089 delete mAssemblerProgram; 00090 mAssemblerProgram = NULL; 00091 00092 } 00093 00094 //----------------------------------------------------------------------- 00095 void GLSLProgram::populateParameterNames(GpuProgramParametersSharedPtr params) 00096 { 00097 // can't populate parameter names in GLSL until link time 00098 // allow for names read from a material script to be added automatically to the list 00099 params->setAutoAddParamName(true); 00100 00101 } 00102 00103 //----------------------------------------------------------------------- 00104 GLSLProgram::GLSLProgram(const String& name, GpuProgramType gpType, 00105 const String& language) 00106 : HighLevelGpuProgram(name, gpType, language) 00107 { 00108 // add parameter command "attach" to the material serializer dictionary 00109 if (createParamDictionary("GLSLProgram")) 00110 { 00111 ParamDictionary* dict = getParamDictionary(); 00112 00113 dict->addParameter(ParameterDef("attach", 00114 "name of another GLSL program needed by this program", 00115 PT_STRING),&msCmdAttach); 00116 } 00117 00118 // want scenemanager to pass on surface and light states to the rendersystem 00119 mPassSurfaceAndLightStates = true; 00120 // only create a shader object if glsl is supported 00121 if (isSupported()) 00122 { 00123 checkForGLSLError( "GLSLProgram::GLSLProgram", "GL Errors before creating shader object", 0 ); 00124 // create shader object 00125 mGLHandle = glCreateShaderObjectARB_ptr( 00126 (gpType == GPT_VERTEX_PROGRAM) ? GL_VERTEX_SHADER_ARB : GL_FRAGMENT_SHADER_ARB ); 00127 00128 checkForGLSLError( "GLSLProgram::GLSLProgram", "Error creating GLSL shader Object", 0 ); 00129 } 00130 00131 00132 } 00133 00134 //----------------------------------------------------------------------- 00135 String GLSLProgram::CmdAttach::doGet(const void *target) const 00136 { 00137 return (static_cast<const GLSLProgram*>(target))->getAttachedShaderNames(); 00138 } 00139 //----------------------------------------------------------------------- 00140 void GLSLProgram::CmdAttach::doSet(void *target, const String& shaderNames) 00141 { 00142 //get all the shader program names: there could be more than one 00143 StringVector vecShaderNames = StringUtil::split(shaderNames, " \t", 0); 00144 00145 size_t programNameCount = vecShaderNames.size(); 00146 for ( size_t i = 0; i < programNameCount; ++i ) 00147 { 00148 static_cast<GLSLProgram*>(target)->attachChildShader(vecShaderNames[i]); 00149 } 00150 } 00151 00152 //----------------------------------------------------------------------- 00153 void GLSLProgram::attachChildShader(const String& name) 00154 { 00155 // is the name valid and already loaded? 00156 // check with the high level program manager to see if it was loaded 00157 HighLevelGpuProgram* hlProgram = static_cast<HighLevelGpuProgram*> (HighLevelGpuProgramManager::getSingleton().getByName(name)); 00158 if (hlProgram) 00159 { 00160 if (hlProgram->getSyntaxCode() == "glsl") 00161 { 00162 // make sure attached program source gets loaded and compiled 00163 // don't need a low level implementation for attached shader objects 00164 // loadHighLevelImpl will only load the source and compile once 00165 // so don't worry about calling it several times 00166 GLSLProgram* childShader = static_cast<GLSLProgram*>(hlProgram); 00167 // load the source and attach the child shader only if supported 00168 if (isSupported()) 00169 { 00170 childShader->loadHighLevelImpl(); 00171 // add to the container 00172 mAttachedGLSLPrograms.push_back( childShader ); 00173 mAttachedShaderNames += name + " "; 00174 } 00175 } 00176 } 00177 } 00178 00179 //----------------------------------------------------------------------- 00180 void GLSLProgram::attachToProgramObject( const GLhandleARB programObject ) 00181 { 00182 glAttachObjectARB_ptr( programObject, mGLHandle ); 00183 checkForGLSLError( "GLSLLinkProgram::GLSLLinkProgram", 00184 "Error attaching " + mName + " shader object to GLSL Program Object", programObject ); 00185 // attach child objects 00186 GLSLProgramContainerIterator childprogramcurrent = mAttachedGLSLPrograms.begin(); 00187 GLSLProgramContainerIterator childprogramend = mAttachedGLSLPrograms.end(); 00188 00189 while (childprogramcurrent != childprogramend) 00190 { 00191 00192 GLSLProgram* childShader = *childprogramcurrent; 00193 // bug in ATI GLSL linker : modules without main function must be recompiled each time 00194 // they are linked to a different program object 00195 // don't check for compile errors since there won't be any 00196 // *** minor inconvenience until ATI fixes there driver 00197 childShader->compile(false); 00198 00199 childShader->attachToProgramObject( programObject ); 00200 00201 childprogramcurrent++; 00202 } 00203 00204 } 00205 00206 00207 }
Copyright © 2002-2003 by The OGRE Team
Last modified Sun Nov 28 19:48:26 2004