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

# OgreGLSLLinkProgram.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-2002 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
    00026 #include "OgreGLSLExtSupport.h"
    00027 #include "OgreGpuProgram.h"
    00028 #include "OgreGLSLLinkProgram.h"
    00029
    00030 namespace Ogre {
    00031
    00032     //-----------------------------------------------------------------------
    00033
    00034     GLSLLinkProgram::GLSLLinkProgram(void) : mLinked(false),
    00035         mUniformRefsBuilt(false)
    00036     {
    00037             checkForGLSLError( "GLSLLinkProgram::GLSLLinkProgram", "Error prior to Creating GLSL Program Object", 0 );
    00038             mGLHandle = glCreateProgramObjectARB_ptr();
    00039             checkForGLSLError( "GLSLLinkProgram::GLSLLinkProgram", "Error Creating GLSL Program Object", 0 );
    00040
    00041     }
    00042
    00043     //-----------------------------------------------------------------------
    00044     GLSLLinkProgram::~GLSLLinkProgram(void)
    00045     {
    00046         glDeleteObjectARB_ptr(mGLHandle);
    00047
    00048     }
    00049
    00050     //-----------------------------------------------------------------------
    00051     void GLSLLinkProgram::activate(void)
    00052     {
    00053         if (!mLinked)
    00054         {
    00055             glLinkProgramARB_ptr( mGLHandle );
    00056             glGetObjectParameterivARB_ptr( mGLHandle, GL_OBJECT_LINK_STATUS_ARB, &mLinked );
    00057             // force logging and raise exception if not linked
    00058             checkForGLSLError( "GLSLLinkProgram::Activate",
    00059                 "Error linking GLSL Program Object", mGLHandle, !mLinked, !mLinked );
    00060             if(mLinked)
    00061             {
    00062                 logObjectInfo( String("GLSL link result : "), mGLHandle );
    00063                 buildUniformReferences();
    00064             }
    00065
    00066         }
    00067
    00068         if (mLinked)
    00069         {
    00070             glUseProgramObjectARB_ptr( mGLHandle );
    00071         }
    00072     }
    00073
    00074     //-----------------------------------------------------------------------
    00075     void GLSLLinkProgram::buildUniformReferences(void)
    00076     {
    00077         if (!mUniformRefsBuilt)
    00078         {
    00079             // scan through the active uniforms and add them to the reference list
    00080             int    uniformCount;
    00081             GLint  size;
    00082             //GLenum type;
    00083             #define BUFFERSIZE 100
    00084             char   uniformName[BUFFERSIZE];
    00085             //GLint location;
    00086             UniformReference newUniformReference;
    00087
    00088             // get the number of active uniforms
    00089             glGetObjectParameterivARB_ptr(mGLHandle, GL_OBJECT_ACTIVE_UNIFORMS_ARB,
    00090                     &uniformCount);
    00091
    00092             // Loop over each of the active uniforms, and add them to the reference container
    00093             // only do this for user defined uniforms, ignore built in gl state uniforms
    00094             for (int index = 0; index < uniformCount; index++)
    00095             {
    00096                 glGetActiveUniformARB_ptr(mGLHandle, index, BUFFERSIZE, NULL, &size, &newUniformReference.mType, uniformName);
    00097                 // don't add built in uniforms
    00098                 newUniformReference.mLocation = glGetUniformLocationARB_ptr(mGLHandle, uniformName);
    00099                 if (newUniformReference.mLocation >= 0)
    00100                 {
    00101                     // user defined uniform found, add it to the reference list
    00102                     newUniformReference.mName = String( uniformName );
    00103                     // decode uniform size and type
    00104                     switch (newUniformReference.mType)
    00105                     {
    00106                     case GL_FLOAT:
    00107                         newUniformReference.isReal = true;
    00108                         newUniformReference.mElementCount = 1;
    00109                         break;
    00110
    00111                     case GL_FLOAT_VEC2_ARB:
    00112                         newUniformReference.isReal = true;
    00113                         newUniformReference.mElementCount = 2;
    00114                         break;
    00115
    00116                     case GL_FLOAT_VEC3_ARB:
    00117                         newUniformReference.isReal = true;
    00118                         newUniformReference.mElementCount = 3;
    00119                         break;
    00120
    00121                     case GL_FLOAT_VEC4_ARB:
    00122                         newUniformReference.isReal = true;
    00123                         newUniformReference.mElementCount = 4;
    00124                         break;
    00125
    00126                     case GL_INT:
    00127                     case GL_SAMPLER_1D_ARB:
    00128                     case GL_SAMPLER_2D_ARB:
    00129                     case GL_SAMPLER_3D_ARB:
    00130                     case GL_SAMPLER_CUBE_ARB:
    00131                         newUniformReference.isReal = false;
    00132                         newUniformReference.mElementCount = 1;
    00133                         break;
    00134
    00135                     case GL_INT_VEC2_ARB:
    00136                         newUniformReference.isReal = false;
    00137                         newUniformReference.mElementCount = 2;
    00138                         break;
    00139
    00140                     case GL_INT_VEC3_ARB:
    00141                         newUniformReference.isReal = false;
    00142                         newUniformReference.mElementCount = 3;
    00143                         break;
    00144
    00145                     case GL_INT_VEC4_ARB:
    00146                         newUniformReference.isReal = false;
    00147                         newUniformReference.mElementCount = 4;
    00148                         break;
    00149                     }// end switch
    00150
    00151                     mUniformReferences.push_back(newUniformReference);
    00152
    00153                 } // end if
    00154             } // end for
    00155
    00156             mUniformRefsBuilt = true;
    00157         }
    00158     }
    00159
    00160     //-----------------------------------------------------------------------
    00161     void GLSLLinkProgram::updateUniforms(GpuProgramParametersSharedPtr params)
    00162     {
    00163         // iterate through uniform reference list and update uniform values
    00164         UniformReferenceIterator currentUniform = mUniformReferences.begin();
    00165         UniformReferenceIterator endUniform = mUniformReferences.end();
    00166
    00167         GpuProgramParameters::RealConstantEntry* currentRealConstant;
    00168         GpuProgramParameters::IntConstantEntry* currentIntConstant;
    00169
    00170         while (currentUniform != endUniform)
    00171         {
    00172             // get the index in the parameter real list
    00173
    00174             if (currentUniform->isReal)
    00175             {
    00176                 currentRealConstant = params->getNamedRealConstantEntry( currentUniform->mName );
    00177                 if (currentRealConstant != NULL)
    00178                 {
    00179                     if (currentRealConstant->isSet)
    00180                     {
    00181                         switch (currentUniform->mElementCount)
    00182                         {
    00183                         case 1:
    00184                             glUniform1fvARB_ptr( currentUniform->mLocation, 1, currentRealConstant->val );
    00185                             break;
    00186
    00187                         case 2:
    00188                             glUniform2fvARB_ptr( currentUniform->mLocation, 1, currentRealConstant->val );
    00189                             break;
    00190
    00191                         case 3:
    00192                             glUniform3fvARB_ptr( currentUniform->mLocation, 1, currentRealConstant->val );
    00193                             break;
    00194
    00195                         case 4:
    00196                             glUniform4fvARB_ptr( currentUniform->mLocation, 1, currentRealConstant->val );
    00197                             break;
    00198
    00199                         } // end switch
    00200                     }
    00201                 }
    00202             }
    00203             else
    00204             {
    00205                 currentIntConstant = params->getNamedIntConstantEntry( currentUniform->mName );
    00206                 if (currentIntConstant != NULL)
    00207                 {
    00208                     if (currentIntConstant->isSet)
    00209                     {
    00210                         switch (currentUniform->mElementCount)
    00211                         {
    00212                         case 1:
    00213                             glUniform1ivARB_ptr( currentUniform->mLocation, 1, currentIntConstant->val );
    00214                             break;
    00215
    00216                         case 2:
    00217                             glUniform2ivARB_ptr( currentUniform->mLocation, 1, currentIntConstant->val );
    00218                             break;
    00219
    00220                         case 3:
    00221                             glUniform3ivARB_ptr( currentUniform->mLocation, 1, currentIntConstant->val );
    00222                             break;
    00223
    00224                         case 4:
    00225                             glUniform4ivARB_ptr( currentUniform->mLocation, 1, currentIntConstant->val );
    00226                             break;
    00227                         } // end switch
    00228                     }
    00229                 }
    00230
    00231             }
    00232
    00233
    00234             // get the next uniform
    00235             ++currentUniform;
    00236
    00237         } // end while
    00238     }
    00239
    00240
    00241 } // namespace Ogre

Copyright © 2002-2003 by The OGRE Team
Last modified Sun Nov 28 19:48:26 2004