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