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