Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/RenderSystems/GL/src/GLSL/src/OgreGLSLLinkProgram.cpp @ 5

Last change on this file since 5 was 5, checked in by anonymous, 17 years ago

=hoffentlich gehts jetzt

File size: 10.7 KB
Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4    (Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright (c) 2000-2006 Torus Knot Software Ltd
8Also see acknowledgements in Readme.html
9
10This program is free software; you can redistribute it and/or modify it under
11the terms of the GNU Lesser General Public License as published by the Free Software
12Foundation; either version 2 of the License, or (at your option) any later
13version.
14
15This program is distributed in the hope that it will be useful, but WITHOUT
16ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public License along with
20this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21Place - Suite 330, Boston, MA 02111-1307, USA, or go to
22http://www.gnu.org/copyleft/lesser.txt.
23
24You may alternatively use this source under the terms of a specific version of
25the OGRE Unrestricted License provided you have obtained such a license from
26Torus Knot Software Ltd.
27-----------------------------------------------------------------------------
28*/
29
30#include "OgreGLSLExtSupport.h"
31#include "OgreGLSLLinkProgram.h"
32#include "OgreStringConverter.h"
33#include "OgreGLSLGpuProgram.h"
34#include "OgreGLSLProgram.h"
35#include "OgreGLSLLinkProgramManager.h"
36
37namespace Ogre {
38
39        //-----------------------------------------------------------------------
40#define NO_ATTRIB 0xFFFF
41        GLSLLinkProgram::GLSLLinkProgram(GLSLGpuProgram* vertexProgram, GLSLGpuProgram* fragmentProgram)
42        : mVertexProgram(vertexProgram)
43                , mFragmentProgram(fragmentProgram)
44                , mUniformRefsBuilt(false)
45        , mLinked(false)
46                , mTangentAttrib(NO_ATTRIB)
47                , mBinormalAttrib(NO_ATTRIB)
48                , mBlendIndicesAttrib(NO_ATTRIB)
49                , mBlendWeightsAttrib(NO_ATTRIB)
50
51        {
52                        checkForGLSLError( "GLSLLinkProgram::GLSLLinkProgram", "Error prior to Creating GLSL Program Object", 0 );
53                    mGLHandle = glCreateProgramObjectARB();
54                        checkForGLSLError( "GLSLLinkProgram::GLSLLinkProgram", "Error Creating GLSL Program Object", 0 );
55
56
57                        // tell shaders to attach themselves to the LinkProgram
58                        // let the shaders do the attaching since they may have several children to attach
59                        if (mVertexProgram)
60                        {
61                                mVertexProgram->getGLSLProgram()->attachToProgramObject(mGLHandle);
62                                setSkeletalAnimationIncluded(mVertexProgram->isSkeletalAnimationIncluded());
63                        }
64
65                        if (mFragmentProgram)
66                        {
67                                mFragmentProgram->getGLSLProgram()->attachToProgramObject(mGLHandle);
68                        }
69
70        }
71
72        //-----------------------------------------------------------------------
73        GLSLLinkProgram::~GLSLLinkProgram(void)
74        {
75                glDeleteObjectARB(mGLHandle);
76
77        }
78
79        //-----------------------------------------------------------------------
80        void GLSLLinkProgram::activate(void)
81        {
82                if (!mLinked)
83                {
84                        glLinkProgramARB( mGLHandle );
85                        glGetObjectParameterivARB( mGLHandle, GL_OBJECT_LINK_STATUS_ARB, &mLinked );
86                        // force logging and raise exception if not linked
87                        checkForGLSLError( "GLSLLinkProgram::Activate",
88                                "Error linking GLSL Program Object", mGLHandle, !mLinked, !mLinked );
89                        if(mLinked)
90                        {
91                                logObjectInfo( String("GLSL link result : "), mGLHandle );
92                                buildGLUniformReferences();
93                                extractAttributes();
94                        }
95
96                }
97
98                if (mLinked)
99                {
100                    glUseProgramObjectARB( mGLHandle );
101                }
102        }
103
104        //-----------------------------------------------------------------------
105        void GLSLLinkProgram::extractAttributes(void)
106        {
107                GLint attrib = glGetAttribLocationARB(mGLHandle, "tangent");
108                mTangentAttrib = (attrib == -1)? NO_ATTRIB : (GLuint)attrib;
109               
110                attrib = glGetAttribLocationARB(mGLHandle, "binormal");
111                mBinormalAttrib = (attrib == -1)? NO_ATTRIB : (GLuint)attrib;
112
113                attrib = glGetAttribLocationARB(mGLHandle, "blendIndices");
114                mBlendIndicesAttrib = (attrib == -1)? NO_ATTRIB : (GLuint)attrib;
115
116                attrib = glGetAttribLocationARB(mGLHandle, "blendWeights");
117                mBlendWeightsAttrib = (attrib == -1)? NO_ATTRIB : (GLuint)attrib;
118
119        }
120        //-----------------------------------------------------------------------
121        GLuint GLSLLinkProgram::getAttributeIndex(VertexElementSemantic semantic)
122        {
123                switch(semantic)
124                {
125                case VES_TANGENT:
126                        return mTangentAttrib;
127                case VES_BINORMAL:
128                        return mBinormalAttrib;
129                case VES_BLEND_WEIGHTS:
130                        return mBlendWeightsAttrib;
131                case VES_BLEND_INDICES:
132                        return mBlendIndicesAttrib;
133                default:
134                        assert(false && "Shouldn't be calling this with standard attribs!");
135                        return 0;
136                };
137        }
138        //-----------------------------------------------------------------------
139        bool GLSLLinkProgram::isAttributeValid(VertexElementSemantic semantic)
140        {
141                switch(semantic)
142                {
143                case VES_TANGENT:
144                        return mTangentAttrib != NO_ATTRIB;
145                case VES_BINORMAL:
146                        return mBinormalAttrib != NO_ATTRIB;
147                case VES_BLEND_WEIGHTS:
148                        return mBlendWeightsAttrib != NO_ATTRIB;
149                case VES_BLEND_INDICES:
150                        return mBlendIndicesAttrib != NO_ATTRIB;
151                default:
152                        return false;
153                };
154        }
155        //-----------------------------------------------------------------------
156        void GLSLLinkProgram::buildGLUniformReferences(void)
157        {
158                if (!mUniformRefsBuilt)
159                {
160                        const GpuConstantDefinitionMap* vertParams = 0;
161                        const GpuConstantDefinitionMap* fragParams = 0;
162
163                        if (mVertexProgram)
164                        {
165                                vertParams = &(mVertexProgram->getGLSLProgram()->getConstantDefinitions().map);
166                        }
167                        if (mFragmentProgram)
168                        {
169                                fragParams = &(mFragmentProgram->getGLSLProgram()->getConstantDefinitions().map);
170                        }
171
172                        GLSLLinkProgramManager::getSingleton().extractUniforms(
173                                mGLHandle, vertParams, fragParams, mGLUniformReferences);
174
175                        mUniformRefsBuilt = true;
176                }
177        }
178
179        //-----------------------------------------------------------------------
180        void GLSLLinkProgram::updateUniforms(GpuProgramParametersSharedPtr params, 
181                GpuProgramType fromProgType)
182        {
183                // iterate through uniform reference list and update uniform values
184                GLUniformReferenceIterator currentUniform = mGLUniformReferences.begin();
185                GLUniformReferenceIterator endUniform = mGLUniformReferences.end();
186
187                for (;currentUniform != endUniform; ++currentUniform)
188                {
189                        // Only pull values from buffer it's supposed to be in (vertex or fragment)
190                        // This method will be called twice, once for vertex program params,
191                        // and once for fragment program params.
192                        if (fromProgType == currentUniform->mSourceProgType)
193                        {
194                                const GpuConstantDefinition* def = currentUniform->mConstantDef;
195                                GLsizei glArraySize = (GLsizei)def->arraySize;
196
197                                // get the index in the parameter real list
198                                switch (def->constType)
199                                {
200                                case GCT_FLOAT1:
201                                        glUniform1fvARB(currentUniform->mLocation, glArraySize, 
202                                                params->getFloatPointer(def->physicalIndex));
203                                        break;
204                                case GCT_FLOAT2:
205                                        glUniform2fvARB(currentUniform->mLocation, glArraySize, 
206                                                params->getFloatPointer(def->physicalIndex));
207                                        break;
208                                case GCT_FLOAT3:
209                                        glUniform3fvARB(currentUniform->mLocation, glArraySize, 
210                                                params->getFloatPointer(def->physicalIndex));
211                                        break;
212                                case GCT_FLOAT4:
213                                        glUniform4fvARB(currentUniform->mLocation, glArraySize, 
214                                                params->getFloatPointer(def->physicalIndex));
215                                        break;
216                                case GCT_MATRIX_2X2:
217                                        glUniformMatrix2fvARB(currentUniform->mLocation, glArraySize, 
218                                                GL_TRUE, params->getFloatPointer(def->physicalIndex));
219                                        break;
220                                case GCT_MATRIX_2X3:
221                                        if (GLEW_VERSION_2_1)
222                                        {
223                                                glUniformMatrix2x3fv(currentUniform->mLocation, glArraySize, 
224                                                        GL_TRUE, params->getFloatPointer(def->physicalIndex));
225                                        }
226                                        break;
227                                case GCT_MATRIX_2X4:
228                                        if (GLEW_VERSION_2_1)
229                                        {
230                                                glUniformMatrix2x4fv(currentUniform->mLocation, glArraySize, 
231                                                        GL_TRUE, params->getFloatPointer(def->physicalIndex));
232                                        }
233                                        break;
234                                case GCT_MATRIX_3X2:
235                                        if (GLEW_VERSION_2_1)
236                                        {
237                                                glUniformMatrix3x2fv(currentUniform->mLocation, glArraySize, 
238                                                        GL_TRUE, params->getFloatPointer(def->physicalIndex));
239                                        }
240                                        break;
241                                case GCT_MATRIX_3X3:
242                                        glUniformMatrix3fvARB(currentUniform->mLocation, glArraySize, 
243                                                GL_TRUE, params->getFloatPointer(def->physicalIndex));
244                                        break;
245                                case GCT_MATRIX_3X4:
246                                        if (GLEW_VERSION_2_1)
247                                        {
248                                                glUniformMatrix3x4fv(currentUniform->mLocation, glArraySize, 
249                                                        GL_TRUE, params->getFloatPointer(def->physicalIndex));
250                                        }
251                                        break;
252                                case GCT_MATRIX_4X2:
253                                        if (GLEW_VERSION_2_1)
254                                        {
255                                                glUniformMatrix4x2fv(currentUniform->mLocation, glArraySize, 
256                                                        GL_TRUE, params->getFloatPointer(def->physicalIndex));
257                                        }
258                                        break;
259                                case GCT_MATRIX_4X3:
260                                        if (GLEW_VERSION_2_1)
261                                        {
262                                                glUniformMatrix4x3fv(currentUniform->mLocation, glArraySize, 
263                                                        GL_TRUE, params->getFloatPointer(def->physicalIndex));
264                                        }
265                                        break;
266                                case GCT_MATRIX_4X4:
267                                        glUniformMatrix4fvARB(currentUniform->mLocation, glArraySize, 
268                                                GL_TRUE, params->getFloatPointer(def->physicalIndex));
269                                        break;
270                                case GCT_INT1:
271                                        glUniform1ivARB(currentUniform->mLocation, glArraySize, 
272                                                params->getIntPointer(def->physicalIndex));
273                                        break;
274                                case GCT_INT2:
275                                        glUniform2ivARB(currentUniform->mLocation, glArraySize, 
276                                                params->getIntPointer(def->physicalIndex));
277                                        break;
278                                case GCT_INT3:
279                                        glUniform3ivARB(currentUniform->mLocation, glArraySize, 
280                                                params->getIntPointer(def->physicalIndex));
281                                        break;
282                                case GCT_INT4:
283                                        glUniform4ivARB(currentUniform->mLocation, glArraySize, 
284                                                params->getIntPointer(def->physicalIndex));
285                                        break;
286                                case GCT_SAMPLER1D:
287                                case GCT_SAMPLER1DSHADOW:
288                                case GCT_SAMPLER2D:
289                                case GCT_SAMPLER2DSHADOW:
290                                case GCT_SAMPLER3D:
291                                case GCT_SAMPLERCUBE:
292                                        // samplers handled like 1-element ints
293                                        glUniform1ivARB(currentUniform->mLocation, 1, 
294                                                params->getIntPointer(def->physicalIndex));
295                                        break;
296
297                                } // end switch
298#if OGRE_DEBUG_MODE
299                                checkForGLSLError( "GLSLLinkProgram::updateUniforms", "Error updating uniform", 0 );
300#endif
301
302                        }
303 
304                } // end for
305        }
306
307
308        //-----------------------------------------------------------------------
309        void GLSLLinkProgram::updatePassIterationUniforms(GpuProgramParametersSharedPtr params)
310        {
311                if (params->hasPassIterationNumber())
312                {
313                        size_t index = params->getPassIterationNumberIndex();
314
315                        GLUniformReferenceIterator currentUniform = mGLUniformReferences.begin();
316                        GLUniformReferenceIterator endUniform = mGLUniformReferences.end();
317
318                        // need to find the uniform that matches the multi pass entry
319                        for (;currentUniform != endUniform; ++currentUniform)
320                        {
321                                // get the index in the parameter real list
322                                if (index == currentUniform->mConstantDef->physicalIndex)
323                                {
324                                        glUniform1fvARB( currentUniform->mLocation, 1, params->getFloatPointer(index));
325                                        // there will only be one multipass entry
326                                        return;
327                                }
328                        }
329                }
330
331    }
332} // namespace Ogre
Note: See TracBrowser for help on using the repository browser.