Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

OgreGLSLProgram.cpp

Go to the documentation of this file.
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