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