Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/ogre/OgreMain/src/OgreGpuProgram.cpp @ 11

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

=hoffentlich gehts jetzt

File size: 82.9 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#include "OgreStableHeaders.h"
30#include "OgreGpuProgram.h"
31#include "OgreHighLevelGpuProgram.h"
32#include "OgreGpuProgramManager.h"
33#include "OgreVector3.h"
34#include "OgreVector4.h"
35#include "OgreAutoParamDataSource.h"
36#include "OgreLight.h"
37#include "OgreRoot.h"
38#include "OgreRenderSystem.h"
39#include "OgreRenderSystemCapabilities.h"
40#include "OgreStringConverter.h"
41#include "OgreLogManager.h"
42
43namespace Ogre
44{
45    //-----------------------------------------------------------------------------
46    GpuProgram::CmdType GpuProgram::msTypeCmd;
47    GpuProgram::CmdSyntax GpuProgram::msSyntaxCmd;
48    GpuProgram::CmdSkeletal GpuProgram::msSkeletalCmd;
49        GpuProgram::CmdMorph GpuProgram::msMorphCmd;
50        GpuProgram::CmdPose GpuProgram::msPoseCmd;
51        GpuProgram::CmdVTF GpuProgram::msVTFCmd;
52
53
54    GpuProgramParameters::AutoConstantDefinition GpuProgramParameters::AutoConstantDictionary[] = {
55        AutoConstantDefinition(ACT_WORLD_MATRIX,                  "world_matrix",                16, ET_REAL, ACDT_NONE),
56        AutoConstantDefinition(ACT_INVERSE_WORLD_MATRIX,          "inverse_world_matrix",        16, ET_REAL, ACDT_NONE),
57        AutoConstantDefinition(ACT_TRANSPOSE_WORLD_MATRIX,             "transpose_world_matrix",            16, ET_REAL, ACDT_NONE),
58        AutoConstantDefinition(ACT_INVERSE_TRANSPOSE_WORLD_MATRIX, "inverse_transpose_world_matrix", 16, ET_REAL, ACDT_NONE),
59
60        AutoConstantDefinition(ACT_WORLD_MATRIX_ARRAY_3x4,        "world_matrix_array_3x4",      12, ET_REAL, ACDT_NONE),
61        AutoConstantDefinition(ACT_WORLD_MATRIX_ARRAY,            "world_matrix_array",          16, ET_REAL, ACDT_NONE),
62
63        AutoConstantDefinition(ACT_VIEW_MATRIX,                   "view_matrix",                 16, ET_REAL, ACDT_NONE),
64        AutoConstantDefinition(ACT_INVERSE_VIEW_MATRIX,           "inverse_view_matrix",         16, ET_REAL, ACDT_NONE),
65        AutoConstantDefinition(ACT_TRANSPOSE_VIEW_MATRIX,              "transpose_view_matrix",             16, ET_REAL, ACDT_NONE),
66        AutoConstantDefinition(ACT_INVERSE_TRANSPOSE_VIEW_MATRIX,       "inverse_transpose_view_matrix",     16, ET_REAL, ACDT_NONE),
67
68        AutoConstantDefinition(ACT_PROJECTION_MATRIX,             "projection_matrix",           16, ET_REAL, ACDT_NONE),
69        AutoConstantDefinition(ACT_INVERSE_PROJECTION_MATRIX,          "inverse_projection_matrix",         16, ET_REAL, ACDT_NONE),
70        AutoConstantDefinition(ACT_TRANSPOSE_PROJECTION_MATRIX,        "transpose_projection_matrix",       16, ET_REAL, ACDT_NONE),
71        AutoConstantDefinition(ACT_INVERSE_TRANSPOSE_PROJECTION_MATRIX, "inverse_transpose_projection_matrix", 16, ET_REAL, ACDT_NONE),
72
73        AutoConstantDefinition(ACT_VIEWPROJ_MATRIX,               "viewproj_matrix",             16, ET_REAL, ACDT_NONE),
74        AutoConstantDefinition(ACT_INVERSE_VIEWPROJ_MATRIX,       "inverse_viewproj_matrix",     16, ET_REAL, ACDT_NONE),
75        AutoConstantDefinition(ACT_TRANSPOSE_VIEWPROJ_MATRIX,          "transpose_viewproj_matrix",         16, ET_REAL, ACDT_NONE),
76        AutoConstantDefinition(ACT_INVERSE_TRANSPOSE_VIEWPROJ_MATRIX,   "inverse_transpose_viewproj_matrix", 16, ET_REAL, ACDT_NONE),
77
78        AutoConstantDefinition(ACT_WORLDVIEW_MATRIX,              "worldview_matrix",            16, ET_REAL, ACDT_NONE),
79        AutoConstantDefinition(ACT_INVERSE_WORLDVIEW_MATRIX,      "inverse_worldview_matrix",    16, ET_REAL, ACDT_NONE),
80        AutoConstantDefinition(ACT_TRANSPOSE_WORLDVIEW_MATRIX,         "transpose_worldview_matrix",        16, ET_REAL, ACDT_NONE),
81        AutoConstantDefinition(ACT_INVERSE_TRANSPOSE_WORLDVIEW_MATRIX, "inverse_transpose_worldview_matrix", 16, ET_REAL, ACDT_NONE),
82
83        AutoConstantDefinition(ACT_WORLDVIEWPROJ_MATRIX,          "worldviewproj_matrix",        16, ET_REAL, ACDT_NONE),
84        AutoConstantDefinition(ACT_INVERSE_WORLDVIEWPROJ_MATRIX,       "inverse_worldviewproj_matrix",      16, ET_REAL, ACDT_NONE),
85        AutoConstantDefinition(ACT_TRANSPOSE_WORLDVIEWPROJ_MATRIX,     "transpose_worldviewproj_matrix",    16, ET_REAL, ACDT_NONE),
86        AutoConstantDefinition(ACT_INVERSE_TRANSPOSE_WORLDVIEWPROJ_MATRIX, "inverse_transpose_worldviewproj_matrix", 16, ET_REAL, ACDT_NONE),
87
88        AutoConstantDefinition(ACT_RENDER_TARGET_FLIPPING,          "render_target_flipping",         1, ET_REAL, ACDT_NONE),
89
90        AutoConstantDefinition(ACT_FOG_COLOUR,                    "fog_colour",                   4, ET_REAL, ACDT_NONE),
91        AutoConstantDefinition(ACT_FOG_PARAMS,                    "fog_params",                   4, ET_REAL, ACDT_NONE),
92
93        AutoConstantDefinition(ACT_SURFACE_AMBIENT_COLOUR,          "surface_ambient_colour",           4, ET_REAL, ACDT_NONE),
94        AutoConstantDefinition(ACT_SURFACE_DIFFUSE_COLOUR,          "surface_diffuse_colour",           4, ET_REAL, ACDT_NONE),
95        AutoConstantDefinition(ACT_SURFACE_SPECULAR_COLOUR,         "surface_specular_colour",          4, ET_REAL, ACDT_NONE),
96        AutoConstantDefinition(ACT_SURFACE_EMISSIVE_COLOUR,         "surface_emissive_colour",          4, ET_REAL, ACDT_NONE),
97        AutoConstantDefinition(ACT_SURFACE_SHININESS,               "surface_shininess",                1, ET_REAL, ACDT_NONE),
98
99        AutoConstantDefinition(ACT_AMBIENT_LIGHT_COLOUR,          "ambient_light_colour",         4, ET_REAL, ACDT_NONE),
100        AutoConstantDefinition(ACT_LIGHT_DIFFUSE_COLOUR,          "light_diffuse_colour",         4, ET_REAL, ACDT_INT),
101        AutoConstantDefinition(ACT_LIGHT_SPECULAR_COLOUR,         "light_specular_colour",        4, ET_REAL, ACDT_INT),
102        AutoConstantDefinition(ACT_LIGHT_ATTENUATION,             "light_attenuation",            4, ET_REAL, ACDT_INT),
103                AutoConstantDefinition(ACT_SPOTLIGHT_PARAMS,              "spotlight_params",             4, ET_REAL, ACDT_INT),
104        AutoConstantDefinition(ACT_LIGHT_POSITION,                "light_position",               4, ET_REAL, ACDT_INT),
105        AutoConstantDefinition(ACT_LIGHT_POSITION_OBJECT_SPACE,   "light_position_object_space",  4, ET_REAL, ACDT_INT),
106                AutoConstantDefinition(ACT_LIGHT_POSITION_VIEW_SPACE,          "light_position_view_space",    4, ET_REAL, ACDT_INT),
107        AutoConstantDefinition(ACT_LIGHT_DIRECTION,               "light_direction",              4, ET_REAL, ACDT_INT),
108        AutoConstantDefinition(ACT_LIGHT_DIRECTION_OBJECT_SPACE,  "light_direction_object_space", 4, ET_REAL, ACDT_INT),
109                AutoConstantDefinition(ACT_LIGHT_DIRECTION_VIEW_SPACE,         "light_direction_view_space",   4, ET_REAL, ACDT_INT),
110                AutoConstantDefinition(ACT_LIGHT_DISTANCE_OBJECT_SPACE,   "light_distance_object_space",  1, ET_REAL, ACDT_INT),
111        AutoConstantDefinition(ACT_LIGHT_POWER_SCALE,                     "light_power",  1, ET_REAL, ACDT_INT),
112                AutoConstantDefinition(ACT_LIGHT_DIFFUSE_COLOUR_ARRAY,          "light_diffuse_colour_array",         4, ET_REAL, ACDT_INT),
113                AutoConstantDefinition(ACT_LIGHT_SPECULAR_COLOUR_ARRAY,         "light_specular_colour_array",        4, ET_REAL, ACDT_INT),
114                AutoConstantDefinition(ACT_LIGHT_ATTENUATION_ARRAY,             "light_attenuation_array",            4, ET_REAL, ACDT_INT),
115                AutoConstantDefinition(ACT_LIGHT_POSITION_ARRAY,                "light_position_array",               4, ET_REAL, ACDT_INT),
116                AutoConstantDefinition(ACT_LIGHT_POSITION_OBJECT_SPACE_ARRAY,   "light_position_object_space_array",  4, ET_REAL, ACDT_INT),
117                AutoConstantDefinition(ACT_LIGHT_POSITION_VIEW_SPACE_ARRAY,          "light_position_view_space_array",    4, ET_REAL, ACDT_INT),
118                AutoConstantDefinition(ACT_LIGHT_DIRECTION_ARRAY,               "light_direction_array",              4, ET_REAL, ACDT_INT),
119                AutoConstantDefinition(ACT_LIGHT_DIRECTION_OBJECT_SPACE_ARRAY,  "light_direction_object_space_array", 4, ET_REAL, ACDT_INT),
120                AutoConstantDefinition(ACT_LIGHT_DIRECTION_VIEW_SPACE_ARRAY,         "light_direction_view_space_array",   4, ET_REAL, ACDT_INT),
121                AutoConstantDefinition(ACT_LIGHT_DISTANCE_OBJECT_SPACE_ARRAY,   "light_distance_object_space_array",  1, ET_REAL, ACDT_INT),
122                AutoConstantDefinition(ACT_LIGHT_POWER_SCALE_ARRAY,               "light_power_array",  1, ET_REAL, ACDT_INT),
123                AutoConstantDefinition(ACT_SPOTLIGHT_PARAMS_ARRAY,              "spotlight_params_array",             4, ET_REAL, ACDT_INT),
124
125        AutoConstantDefinition(ACT_DERIVED_AMBIENT_LIGHT_COLOUR,    "derived_ambient_light_colour",     4, ET_REAL, ACDT_NONE),
126        AutoConstantDefinition(ACT_DERIVED_SCENE_COLOUR,            "derived_scene_colour",             4, ET_REAL, ACDT_NONE),
127        AutoConstantDefinition(ACT_DERIVED_LIGHT_DIFFUSE_COLOUR,    "derived_light_diffuse_colour",     4, ET_REAL, ACDT_INT),
128        AutoConstantDefinition(ACT_DERIVED_LIGHT_SPECULAR_COLOUR,   "derived_light_specular_colour",    4, ET_REAL, ACDT_INT),
129        AutoConstantDefinition(ACT_DERIVED_LIGHT_DIFFUSE_COLOUR_ARRAY,  "derived_light_diffuse_colour_array",   4, ET_REAL, ACDT_INT),
130        AutoConstantDefinition(ACT_DERIVED_LIGHT_SPECULAR_COLOUR_ARRAY, "derived_light_specular_colour_array",  4, ET_REAL, ACDT_INT),
131
132        AutoConstantDefinition(ACT_SHADOW_EXTRUSION_DISTANCE,     "shadow_extrusion_distance",    1, ET_REAL, ACDT_INT),
133        AutoConstantDefinition(ACT_CAMERA_POSITION,               "camera_position",              3, ET_REAL, ACDT_NONE),
134        AutoConstantDefinition(ACT_CAMERA_POSITION_OBJECT_SPACE,  "camera_position_object_space", 3, ET_REAL, ACDT_NONE),
135        AutoConstantDefinition(ACT_TEXTURE_VIEWPROJ_MATRIX,       "texture_viewproj_matrix",     16, ET_REAL, ACDT_INT),
136        AutoConstantDefinition(ACT_CUSTOM,                        "custom",                       4, ET_REAL, ACDT_INT),  // *** needs to be tested
137        AutoConstantDefinition(ACT_TIME,                               "time",                               1, ET_REAL, ACDT_REAL),
138        AutoConstantDefinition(ACT_TIME_0_X,                      "time_0_x",                     4, ET_REAL, ACDT_REAL),
139        AutoConstantDefinition(ACT_COSTIME_0_X,                   "costime_0_x",                  4, ET_REAL, ACDT_REAL),
140        AutoConstantDefinition(ACT_SINTIME_0_X,                   "sintime_0_x",                  4, ET_REAL, ACDT_REAL),
141        AutoConstantDefinition(ACT_TANTIME_0_X,                   "tantime_0_x",                  4, ET_REAL, ACDT_REAL),
142        AutoConstantDefinition(ACT_TIME_0_X_PACKED,               "time_0_x_packed",              4, ET_REAL, ACDT_REAL),
143        AutoConstantDefinition(ACT_TIME_0_1,                      "time_0_1",                     4, ET_REAL, ACDT_REAL),
144        AutoConstantDefinition(ACT_COSTIME_0_1,                   "costime_0_1",                  4, ET_REAL, ACDT_REAL),
145        AutoConstantDefinition(ACT_SINTIME_0_1,                   "sintime_0_1",                  4, ET_REAL, ACDT_REAL),
146        AutoConstantDefinition(ACT_TANTIME_0_1,                   "tantime_0_1",                  4, ET_REAL, ACDT_REAL),
147        AutoConstantDefinition(ACT_TIME_0_1_PACKED,               "time_0_1_packed",              4, ET_REAL, ACDT_REAL),
148        AutoConstantDefinition(ACT_TIME_0_2PI,                    "time_0_2pi",                   4, ET_REAL, ACDT_REAL),
149        AutoConstantDefinition(ACT_COSTIME_0_2PI,                 "costime_0_2pi",                4, ET_REAL, ACDT_REAL),
150        AutoConstantDefinition(ACT_SINTIME_0_2PI,                 "sintime_0_2pi",                4, ET_REAL, ACDT_REAL),
151        AutoConstantDefinition(ACT_TANTIME_0_2PI,                 "tantime_0_2pi",                4, ET_REAL, ACDT_REAL),
152        AutoConstantDefinition(ACT_TIME_0_2PI_PACKED,             "time_0_2pi_packed",            4, ET_REAL, ACDT_REAL),
153        AutoConstantDefinition(ACT_FRAME_TIME,                    "frame_time",                   1, ET_REAL, ACDT_REAL),
154        AutoConstantDefinition(ACT_FPS,                           "fps",                          1, ET_REAL, ACDT_NONE),
155        AutoConstantDefinition(ACT_VIEWPORT_WIDTH,                "viewport_width",               1, ET_REAL, ACDT_NONE),
156        AutoConstantDefinition(ACT_VIEWPORT_HEIGHT,               "viewport_height",              1, ET_REAL, ACDT_NONE),
157        AutoConstantDefinition(ACT_INVERSE_VIEWPORT_WIDTH,        "inverse_viewport_width",       1, ET_REAL, ACDT_NONE),
158        AutoConstantDefinition(ACT_INVERSE_VIEWPORT_HEIGHT,       "inverse_viewport_height",      1, ET_REAL, ACDT_NONE),
159        AutoConstantDefinition(ACT_VIEWPORT_SIZE,                 "viewport_size",                4, ET_REAL, ACDT_NONE),
160        AutoConstantDefinition(ACT_VIEW_DIRECTION,                "view_direction",               3, ET_REAL, ACDT_NONE),
161        AutoConstantDefinition(ACT_VIEW_SIDE_VECTOR,              "view_side_vector",             3, ET_REAL, ACDT_NONE),
162        AutoConstantDefinition(ACT_VIEW_UP_VECTOR,                "view_up_vector",               3, ET_REAL, ACDT_NONE),
163        AutoConstantDefinition(ACT_FOV,                           "fov",                          1, ET_REAL, ACDT_NONE),
164        AutoConstantDefinition(ACT_NEAR_CLIP_DISTANCE,            "near_clip_distance",           1, ET_REAL, ACDT_NONE),
165        AutoConstantDefinition(ACT_FAR_CLIP_DISTANCE,             "far_clip_distance",            1, ET_REAL, ACDT_NONE),
166        AutoConstantDefinition(ACT_PASS_NUMBER,                        "pass_number",                        1, ET_REAL, ACDT_NONE),
167        AutoConstantDefinition(ACT_PASS_ITERATION_NUMBER,              "pass_iteration_number",              1, ET_REAL, ACDT_NONE),
168                AutoConstantDefinition(ACT_ANIMATION_PARAMETRIC,               "animation_parametric",               4, ET_REAL, ACDT_INT),
169                AutoConstantDefinition(ACT_TEXEL_OFFSETS,               "texel_offsets",                                  4, ET_REAL, ACDT_NONE),
170                AutoConstantDefinition(ACT_SCENE_DEPTH_RANGE,           "scene_depth_range",                      4, ET_REAL, ACDT_NONE),
171                AutoConstantDefinition(ACT_SHADOW_SCENE_DEPTH_RANGE,    "shadow_scene_depth_range",               4, ET_REAL, ACDT_INT),
172        AutoConstantDefinition(ACT_TEXTURE_SIZE,                "texture_size",                   4, ET_REAL, ACDT_INT),
173        AutoConstantDefinition(ACT_INVERSE_TEXTURE_SIZE,        "inverse_texture_size",           4, ET_REAL, ACDT_INT),
174        AutoConstantDefinition(ACT_PACKED_TEXTURE_SIZE,         "packed_texture_size",            4, ET_REAL, ACDT_INT),
175    };
176
177        //---------------------------------------------------------------------
178        void GpuNamedConstants::generateConstantDefinitionArrayEntries(
179                const String& paramName, const GpuConstantDefinition& baseDef)
180        {
181                // Copy definition for use with arrays
182                GpuConstantDefinition arrayDef = baseDef;
183                arrayDef.arraySize = 1;
184                String arrayName;
185
186                // Add parameters for array accessors
187                // [0] will refer to the same location, [1+] will increment
188                // only populate others individually up to 16 array slots so as not to get out of hand
189
190                // paramName[0] version will always exist
191                size_t maxArrayIndex = 1;
192                if (baseDef.arraySize <= 16)
193                        maxArrayIndex = baseDef.arraySize;
194
195                for (size_t i = 0; i < maxArrayIndex; i++)
196                {
197                        arrayName = paramName + "[" + StringConverter::toString(i) + "]";
198                        map.insert(GpuConstantDefinitionMap::value_type(arrayName, arrayDef));
199                        // increment location
200                        arrayDef.physicalIndex += arrayDef.elementSize;
201                }
202                // note no increment of buffer sizes since this is shared with main array def
203
204        }
205   
206
207    //-----------------------------------------------------------------------------
208    GpuProgram::GpuProgram(ResourceManager* creator, const String& name, ResourceHandle handle,
209        const String& group, bool isManual, ManualResourceLoader* loader) 
210        :Resource(creator, name, handle, group, isManual, loader),
211        mType(GPT_VERTEX_PROGRAM), mLoadFromFile(true), mSkeletalAnimation(false),
212        mVertexTextureFetch(false), mPassSurfaceAndLightStates(false), mCompileError(false)
213    {
214    }
215    //-----------------------------------------------------------------------------
216    void GpuProgram::setType(GpuProgramType t)
217    {
218        mType = t;
219    }
220    //-----------------------------------------------------------------------------
221    void GpuProgram::setSyntaxCode(const String& syntax)
222    {
223        mSyntaxCode = syntax;
224    }
225    //-----------------------------------------------------------------------------
226    void GpuProgram::setSourceFile(const String& filename)
227    {
228        mFilename = filename;
229        mSource.clear();
230        mLoadFromFile = true;
231                mCompileError = false;
232    }
233    //-----------------------------------------------------------------------------
234    void GpuProgram::setSource(const String& source)
235    {
236        mSource = source;
237        mFilename.clear();
238        mLoadFromFile = false;
239                mCompileError = false;
240    }
241
242    //-----------------------------------------------------------------------------
243    void GpuProgram::loadImpl(void)
244    {
245        if (mLoadFromFile)
246        {
247            // find & load source code
248            DataStreamPtr stream = 
249                ResourceGroupManager::getSingleton().openResource(
250                                        mFilename, mGroup, true, this);
251            mSource = stream->getAsString();
252        }
253
254        // Call polymorphic load
255                try 
256                {
257                        loadFromSource();
258                }
259                catch (const Exception&)
260                {
261                        // will already have been logged
262                        StringUtil::StrStreamType str;
263                        str << "Gpu program " << mName << " encountered an error "
264                                << "during loading and is thus not supported.";
265                        LogManager::getSingleton().logMessage(str.str());
266
267                        mCompileError = true;
268                }
269
270    }
271    //-----------------------------------------------------------------------------
272    bool GpuProgram::isRequiredCapabilitiesSupported(void) const
273    {
274                const RenderSystemCapabilities* caps = 
275                        Root::getSingleton().getRenderSystem()->getCapabilities();
276
277        // If skeletal animation is being done, we need support for UBYTE4
278        if (isSkeletalAnimationIncluded() && 
279            !caps->hasCapability(RSC_VERTEX_FORMAT_UBYTE4))
280        {
281            return false;
282        }
283
284                // Vertex texture fetch required?
285                if (isVertexTextureFetchRequired() && 
286                        !caps->hasCapability(RSC_VERTEX_TEXTURE_FETCH))
287                {
288                        return false;
289                }
290
291        return true;
292    }
293    //-----------------------------------------------------------------------------
294    bool GpuProgram::isSupported(void) const
295    {
296        if (mCompileError || !isRequiredCapabilitiesSupported())
297            return false;
298
299        return GpuProgramManager::getSingleton().isSyntaxSupported(mSyntaxCode);
300    }
301    //-----------------------------------------------------------------------------
302    GpuProgramParametersSharedPtr GpuProgram::createParameters(void)
303    {
304        // Default implementation simply returns standard parameters.
305        GpuProgramParametersSharedPtr ret = 
306            GpuProgramManager::getSingleton().createParameters();
307                // link shared logical / physical map for low-level use
308                ret->_setLogicalIndexes(&mFloatLogicalToPhysical, &mIntLogicalToPhysical);
309
310        // Copy in default parameters if present
311        if (!mDefaultParams.isNull())
312            ret->copyConstantsFrom(*(mDefaultParams.get()));
313       
314        return ret;
315    }
316    //-----------------------------------------------------------------------------
317    GpuProgramParametersSharedPtr GpuProgram::getDefaultParameters(void)
318    {
319        if (mDefaultParams.isNull())
320        {
321            mDefaultParams = createParameters();
322        }
323        return mDefaultParams;
324    }
325    //-----------------------------------------------------------------------------
326    void GpuProgram::setupBaseParamDictionary(void)
327    {
328        ParamDictionary* dict = getParamDictionary();
329
330        dict->addParameter(
331            ParameterDef("type", "'vertex_program' or 'fragment_program'",
332                PT_STRING), &msTypeCmd);
333        dict->addParameter(
334            ParameterDef("syntax", "Syntax code, e.g. vs_1_1", PT_STRING), &msSyntaxCmd);
335        dict->addParameter(
336            ParameterDef("includes_skeletal_animation", 
337            "Whether this vertex program includes skeletal animation", PT_BOOL), 
338            &msSkeletalCmd);
339                dict->addParameter(
340                        ParameterDef("includes_morph_animation", 
341                        "Whether this vertex program includes morph animation", PT_BOOL), 
342                        &msMorphCmd);
343                dict->addParameter(
344                        ParameterDef("includes_pose_animation", 
345                        "The number of poses this vertex program supports for pose animation", PT_INT), 
346                        &msPoseCmd);
347                dict->addParameter(
348                        ParameterDef("uses_vertex_texture_fetch", 
349                        "Whether this vertex program requires vertex texture fetch support.", PT_BOOL), 
350                        &msVTFCmd);
351    }
352
353    //-----------------------------------------------------------------------
354    const String& GpuProgram::getLanguage(void) const
355    {
356        static const String language = "asm";
357
358        return language;
359    }
360
361
362
363    //-----------------------------------------------------------------------------
364    //      GpuProgramParameters Methods
365    //-----------------------------------------------------------------------------
366        GpuProgramParameters::GpuProgramParameters() :
367                mFloatLogicalToPhysical(0)
368                , mIntLogicalToPhysical(0)
369                , mNamedConstants(0)
370                , mTransposeMatrices(false)
371                , mIgnoreMissingParams(false)
372                , mActivePassIterationIndex(std::numeric_limits<size_t>::max()) 
373    {
374    }
375    //-----------------------------------------------------------------------------
376
377    GpuProgramParameters::GpuProgramParameters(const GpuProgramParameters& oth)
378    {
379        *this = oth;
380    }
381
382    //-----------------------------------------------------------------------------
383    GpuProgramParameters& GpuProgramParameters::operator=(const GpuProgramParameters& oth)
384    {
385        // let compiler perform shallow copies of structures
386        // AutoConstantEntry, RealConstantEntry, IntConstantEntry
387        mFloatConstants = oth.mFloatConstants;
388        mIntConstants  = oth.mIntConstants;
389        mAutoConstants = oth.mAutoConstants;
390                mFloatLogicalToPhysical = oth.mFloatLogicalToPhysical;
391                mIntLogicalToPhysical = oth.mIntLogicalToPhysical;
392                mNamedConstants = oth.mNamedConstants;
393
394        mTransposeMatrices = oth.mTransposeMatrices;
395        mIgnoreMissingParams  = oth.mIgnoreMissingParams;
396                mActivePassIterationIndex = oth.mActivePassIterationIndex;
397
398                return *this;
399    }
400        //---------------------------------------------------------------------
401        void GpuProgramParameters::_setNamedConstants(
402                const GpuNamedConstants* namedConstants)
403        {
404                mNamedConstants = namedConstants;
405
406                // Determine any extension to local buffers
407
408                // Size and reset buffer (fill with zero to make comparison later ok)
409                if (namedConstants->floatBufferSize > mFloatConstants.size())
410                {
411                        mFloatConstants.insert(mFloatConstants.end(), 
412                                namedConstants->floatBufferSize - mFloatConstants.size(), 0.0f);
413                }
414                if (namedConstants->intBufferSize > mIntConstants.size())
415                {
416                        mIntConstants.insert(mIntConstants.end(), 
417                                namedConstants->intBufferSize - mIntConstants.size(), 0);
418                }
419        }
420        //---------------------------------------------------------------------
421        void GpuProgramParameters::_setLogicalIndexes(
422                GpuLogicalBufferStruct* floatIndexMap, 
423                GpuLogicalBufferStruct* intIndexMap)
424        {
425                mFloatLogicalToPhysical = floatIndexMap;
426                mIntLogicalToPhysical = intIndexMap;
427
428                // resize the internal buffers
429                // Note that these will only contain something after the first parameter
430                // set has set some parameters
431
432                // Size and reset buffer (fill with zero to make comparison later ok)
433                if (floatIndexMap->bufferSize > mFloatConstants.size())
434                {
435                        mFloatConstants.insert(mFloatConstants.end(), 
436                                floatIndexMap->bufferSize - mFloatConstants.size(), 0.0f);
437                }
438                if (intIndexMap->bufferSize > mIntConstants.size())
439                {
440                        mIntConstants.insert(mIntConstants.end(), 
441                                intIndexMap->bufferSize - mIntConstants.size(), 0);
442                }
443
444        }
445        //---------------------------------------------------------------------()
446    void GpuProgramParameters::setConstant(size_t index, const Vector4& vec)
447    {
448        setConstant(index, vec.ptr(), 1);
449    }
450        //-----------------------------------------------------------------------------
451        void GpuProgramParameters::setConstant(size_t index, Real val)
452        {
453                setConstant(index, Vector4(val, 0.0f, 0.0f, 0.0f));
454        }
455    //-----------------------------------------------------------------------------
456    void GpuProgramParameters::setConstant(size_t index, const Vector3& vec)
457    {
458        setConstant(index, Vector4(vec.x, vec.y, vec.z, 1.0f));
459    }
460    //-----------------------------------------------------------------------------
461    void GpuProgramParameters::setConstant(size_t index, const Matrix4& m)
462    {
463        // set as 4x 4-element floats
464        if (mTransposeMatrices)
465        {
466            Matrix4 t = m.transpose();
467            GpuProgramParameters::setConstant(index, t[0], 4);
468        }
469        else
470        {
471            GpuProgramParameters::setConstant(index, m[0], 4);
472        }
473
474    }
475    //-----------------------------------------------------------------------------
476    void GpuProgramParameters::setConstant(size_t index, const Matrix4* pMatrix, 
477        size_t numEntries)
478    {
479        if (mTransposeMatrices)
480        {
481            for (size_t i = 0; i < numEntries; ++i)
482            {
483                Matrix4 t = pMatrix[i].transpose();
484                GpuProgramParameters::setConstant(index, t[0], 4);
485                index += 4;
486            }
487        }
488        else
489        {
490            GpuProgramParameters::setConstant(index, pMatrix[0][0], 4 * numEntries);
491        }
492
493    }
494    //-----------------------------------------------------------------------------
495    void GpuProgramParameters::setConstant(size_t index, const ColourValue& colour)
496    {
497        setConstant(index, colour.ptr(), 1);
498    }
499    //-----------------------------------------------------------------------------
500    void GpuProgramParameters::setConstant(size_t index, const float *val, size_t count)
501    {
502                // Raw buffer size is 4x count
503                size_t rawCount = count * 4;
504                // get physical index
505                assert(mFloatLogicalToPhysical && "GpuProgram hasn't set up the logical -> physical map!");
506
507                size_t physicalIndex = _getFloatConstantPhysicalIndex(index, rawCount);
508
509        // Copy
510                _writeRawConstants(physicalIndex, val, rawCount);
511
512    }
513    //-----------------------------------------------------------------------------
514    void GpuProgramParameters::setConstant(size_t index, const double *val, size_t count)
515    {
516                // Raw buffer size is 4x count
517                size_t rawCount = count * 4;
518                // get physical index
519                assert(mFloatLogicalToPhysical && "GpuProgram hasn't set up the logical -> physical map!");
520
521                size_t physicalIndex = _getFloatConstantPhysicalIndex(index, rawCount);
522                assert(physicalIndex + rawCount <= mFloatConstants.size());
523                // Copy manually since cast required
524                for (size_t i = 0; i < rawCount; ++i)
525                {
526                        mFloatConstants[physicalIndex + i] = 
527                                static_cast<float>(val[i]);
528                }
529
530    }
531    //-----------------------------------------------------------------------------
532    void GpuProgramParameters::setConstant(size_t index, const int *val, size_t count)
533    {
534                // Raw buffer size is 4x count
535                size_t rawCount = count * 4;
536                // get physical index
537                assert(mIntLogicalToPhysical && "GpuProgram hasn't set up the logical -> physical map!");
538
539                size_t physicalIndex = _getIntConstantPhysicalIndex(index, rawCount);
540                // Copy
541                _writeRawConstants(physicalIndex, val, rawCount);
542    }
543        //-----------------------------------------------------------------------------
544        void GpuProgramParameters::_writeRawConstant(size_t physicalIndex, const Vector4& vec,
545                size_t count)
546        {
547                // remember, raw content access uses raw float count rather than float4
548                // write either the number requested (for packed types) or up to 4
549                _writeRawConstants(physicalIndex, vec.ptr(), std::min(count, (size_t)4));
550        }
551        //-----------------------------------------------------------------------------
552        void GpuProgramParameters::_writeRawConstant(size_t physicalIndex, Real val)
553        {
554                _writeRawConstants(physicalIndex, &val, 1);
555        }
556        //-----------------------------------------------------------------------------
557        void GpuProgramParameters::_writeRawConstant(size_t physicalIndex, int val)
558        {
559                _writeRawConstants(physicalIndex, &val, 1);
560        }
561        //-----------------------------------------------------------------------------
562        void GpuProgramParameters::_writeRawConstant(size_t physicalIndex, const Vector3& vec)
563        {
564                _writeRawConstants(physicalIndex, vec.ptr(), 3);               
565        }
566        //-----------------------------------------------------------------------------
567        void GpuProgramParameters::_writeRawConstant(size_t physicalIndex, const Matrix4& m)
568        {
569
570                // remember, raw content access uses raw float count rather than float4
571                if (mTransposeMatrices)
572                {
573                        Matrix4 t = m.transpose();
574                        _writeRawConstants(physicalIndex, t[0], 16);
575                }
576                else
577                {
578                        _writeRawConstants(physicalIndex, m[0], 16);
579                }
580
581        }
582        //-----------------------------------------------------------------------------
583        void GpuProgramParameters::_writeRawConstant(size_t physicalIndex, const Matrix4* pMatrix, size_t numEntries)
584        {
585                // remember, raw content access uses raw float count rather than float4
586                if (mTransposeMatrices)
587                {
588                        for (size_t i = 0; i < numEntries; ++i)
589                        {
590                                Matrix4 t = pMatrix[i].transpose();
591                                _writeRawConstants(physicalIndex, t[0], 16);
592                                physicalIndex += 16;
593                        }
594                }
595                else
596                {
597                        _writeRawConstants(physicalIndex, pMatrix[0][0], 16 * numEntries);
598                }
599
600
601        }
602        //-----------------------------------------------------------------------------
603        void GpuProgramParameters::_writeRawConstant(size_t physicalIndex, 
604                const ColourValue& colour, size_t count)
605        {
606                // write either the number requested (for packed types) or up to 4
607                _writeRawConstants(physicalIndex, colour.ptr(), std::min(count, (size_t)4));
608        }
609        //-----------------------------------------------------------------------------
610        void GpuProgramParameters::_writeRawConstants(size_t physicalIndex, const double* val, size_t count)
611        {
612                assert(physicalIndex + count <= mFloatConstants.size());
613                for (size_t i = 0; i < count; ++i)
614                {
615                        mFloatConstants[physicalIndex+i] = static_cast<float>(val[i]);
616                }
617        }
618        //-----------------------------------------------------------------------------
619        void GpuProgramParameters::_writeRawConstants(size_t physicalIndex, const float* val, size_t count)
620        {
621                assert(physicalIndex + count <= mFloatConstants.size());
622                memcpy(&mFloatConstants[physicalIndex], val, sizeof(float) * count);
623        }
624        //-----------------------------------------------------------------------------
625        void GpuProgramParameters::_writeRawConstants(size_t physicalIndex, const int* val, size_t count)
626        {
627                assert(physicalIndex + count <= mIntConstants.size());
628                memcpy(&mIntConstants[physicalIndex], val, sizeof(int) * count);
629        }
630        //-----------------------------------------------------------------------------
631        void GpuProgramParameters::_readRawConstants(size_t physicalIndex, size_t count, float* dest)
632        {
633                assert(physicalIndex + count <= mFloatConstants.size());
634                memcpy(dest, &mFloatConstants[physicalIndex], sizeof(float) * count);
635        }
636        //-----------------------------------------------------------------------------
637        void GpuProgramParameters::_readRawConstants(size_t physicalIndex, size_t count, int* dest)
638        {
639                assert(physicalIndex + count <= mIntConstants.size());
640                memcpy(dest, &mIntConstants[physicalIndex], sizeof(int) * count);
641        }
642        //-----------------------------------------------------------------------------
643        size_t GpuProgramParameters::_getFloatConstantPhysicalIndex(
644                size_t logicalIndex, size_t requestedSize) 
645        {
646                if (!mFloatLogicalToPhysical)
647                        OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, 
648                                "This is not a low-level parameter parameter object",
649                                "GpuProgramParameters::_getFloatConstantPhysicalIndex");
650
651                size_t physicalIndex;
652                OGRE_LOCK_MUTEX(mFloatLogicalToPhysical->mutex)
653
654                GpuLogicalIndexUseMap::iterator logi = mFloatLogicalToPhysical->map.find(logicalIndex);
655                if (logi == mFloatLogicalToPhysical->map.end())
656                {
657                        if (requestedSize)
658                        {
659                                physicalIndex = mFloatConstants.size();
660
661                // Expand at buffer end
662                mFloatConstants.insert(mFloatConstants.end(), requestedSize, 0.0f);
663
664                                // Record extended size for future GPU params re-using this information
665                                mFloatLogicalToPhysical->bufferSize = mFloatConstants.size();
666
667                                // low-level programs will not know about mapping ahead of time, so
668                                // populate it. Other params objects will be able to just use this
669                                // accepted mapping since the constant structure will be the same
670
671                                // Set up a mapping for all items in the count
672                                size_t currPhys = physicalIndex;
673                                size_t count = requestedSize / 4;
674                                for (size_t logicalNum = 0; logicalNum < count; ++logicalNum)
675                                {
676                                        mFloatLogicalToPhysical->map.insert(
677                                                GpuLogicalIndexUseMap::value_type(
678                                                        logicalIndex + logicalNum, 
679                                                        GpuLogicalIndexUse(currPhys, requestedSize)));
680                                        currPhys += 4;
681                                }
682                        }
683                        else
684                        {
685                                // no match & ignore
686                                return std::numeric_limits<size_t>::max();
687                        }
688
689                }
690                else
691                {
692                        physicalIndex = logi->second.physicalIndex;
693                        // check size
694                        if (logi->second.currentSize < requestedSize)
695                        {
696                                // init buffer entry wasn't big enough; could be a mistake on the part
697                                // of the original use, or perhaps a variable length we can't predict
698                                // until first actual runtime use e.g. world matrix array
699                                size_t insertCount = requestedSize - logi->second.currentSize;
700                                FloatConstantList::iterator insertPos = mFloatConstants.begin();
701                                std::advance(insertPos, physicalIndex);
702                                mFloatConstants.insert(insertPos, insertCount, 0.0f);
703                                // shift all physical positions after this one
704                                for (GpuLogicalIndexUseMap::iterator i = mFloatLogicalToPhysical->map.begin();
705                                        i != mFloatLogicalToPhysical->map.end(); ++i)
706                                {
707                                        if (i->second.physicalIndex > physicalIndex)
708                                                i->second.physicalIndex += insertCount;
709                                }
710                                for (AutoConstantList::iterator i = mAutoConstants.begin();
711                                        i != mAutoConstants.end(); ++i)
712                                {
713                                        if (i->physicalIndex > physicalIndex)
714                                                i->physicalIndex += insertCount;
715                                }
716                        }
717                }
718
719                return physicalIndex;
720        }
721        //-----------------------------------------------------------------------------
722        size_t GpuProgramParameters::_getIntConstantPhysicalIndex(
723                size_t logicalIndex, size_t requestedSize)
724        {
725                if (!mIntLogicalToPhysical)
726                        OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, 
727                        "This is not a low-level parameter parameter object",
728                        "GpuProgramParameters::_getIntConstantPhysicalIndex");
729
730                size_t physicalIndex;
731                OGRE_LOCK_MUTEX(mIntLogicalToPhysical->mutex)
732
733                        GpuLogicalIndexUseMap::iterator logi = mIntLogicalToPhysical->map.find(logicalIndex);
734                if (logi == mIntLogicalToPhysical->map.end())
735                {
736                        if (requestedSize)
737                        {
738                                physicalIndex = mIntConstants.size();
739
740                // Expand at buffer end
741                mIntConstants.insert(mIntConstants.end(), requestedSize, 0);
742
743                                // Record extended size for future GPU params re-using this information
744                                mIntLogicalToPhysical->bufferSize = mIntConstants.size();
745
746                                // low-level programs will not know about mapping ahead of time, so
747                                // populate it. Other params objects will be able to just use this
748                                // accepted mapping since the constant structure will be the same
749
750                                // Set up a mapping for all items in the count
751                                size_t currPhys = physicalIndex;
752                                size_t count = requestedSize / 4;
753                                for (size_t logicalNum = 0; logicalNum < count; ++logicalNum)
754                                {
755                                        mIntLogicalToPhysical->map.insert(
756                                                GpuLogicalIndexUseMap::value_type(
757                                                logicalIndex + logicalNum, 
758                                                GpuLogicalIndexUse(currPhys, requestedSize)));
759                                        currPhys += 4;
760                                }
761                        }
762                        else
763                        {
764                                // no match
765                                return std::numeric_limits<size_t>::max();
766                        }
767
768                }
769                else
770                {
771                        physicalIndex = logi->second.physicalIndex;
772                        // check size
773                        if (logi->second.currentSize < requestedSize)
774                        {
775                                // init buffer entry wasn't big enough; could be a mistake on the part
776                                // of the original use, or perhaps a variable length we can't predict
777                                // until first actual runtime use e.g. world matrix array
778                                size_t insertCount = requestedSize - logi->second.currentSize;
779                                IntConstantList::iterator insertPos = mIntConstants.begin();
780                                std::advance(insertPos, physicalIndex);
781                                mIntConstants.insert(insertPos, insertCount, 0);
782                                // shift all physical positions after this one
783                                for (GpuLogicalIndexUseMap::iterator i = mIntLogicalToPhysical->map.begin();
784                                        i != mIntLogicalToPhysical->map.end(); ++i)
785                                {
786                                        if (i->second.physicalIndex > physicalIndex)
787                                                i->second.physicalIndex += insertCount;
788                                }
789                                for (AutoConstantList::iterator i = mAutoConstants.begin();
790                                        i != mAutoConstants.end(); ++i)
791                                {
792                                        if (i->physicalIndex > physicalIndex)
793                                                i->physicalIndex += insertCount;
794                                }
795                        }
796                }
797
798                return physicalIndex;
799        }
800        //-----------------------------------------------------------------------------
801        size_t GpuProgramParameters::getFloatLogicalIndexForPhysicalIndex(size_t physicalIndex)
802        {
803                // perhaps build a reverse map of this sometime (shared in GpuProgram)
804                for (GpuLogicalIndexUseMap::iterator i = mFloatLogicalToPhysical->map.begin();
805                        i != mFloatLogicalToPhysical->map.end(); ++i)
806                {
807                        if (i->second.physicalIndex == physicalIndex)
808                                return i->first;
809                }
810                return std::numeric_limits<size_t>::max();
811
812        }
813        //-----------------------------------------------------------------------------
814        size_t GpuProgramParameters::getIntLogicalIndexForPhysicalIndex(size_t physicalIndex)
815        {
816                // perhaps build a reverse map of this sometime (shared in GpuProgram)
817                for (GpuLogicalIndexUseMap::iterator i = mIntLogicalToPhysical->map.begin();
818                        i != mIntLogicalToPhysical->map.end(); ++i)
819                {
820                        if (i->second.physicalIndex == physicalIndex)
821                                return i->first;
822                }
823                return std::numeric_limits<size_t>::max();
824
825        }
826        //-----------------------------------------------------------------------------
827        GpuConstantDefinitionIterator GpuProgramParameters::getConstantDefinitionIterator(void) const
828        {
829                if (!mNamedConstants)
830                        OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, 
831                                "This params object is not based on a program with named parameters.",
832                                "GpuProgramParameters::getConstantDefinitionIterator");
833
834                return GpuConstantDefinitionIterator(mNamedConstants->map.begin(), 
835                        mNamedConstants->map.end());
836
837        }
838        //-----------------------------------------------------------------------------
839        const GpuNamedConstants& GpuProgramParameters::getConstantDefinitions() const
840        {
841                if (!mNamedConstants)
842                        OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, 
843                        "This params object is not based on a program with named parameters.",
844                        "GpuProgramParameters::getConstantDefinitionIterator");
845
846                return *mNamedConstants;
847        }
848        //-----------------------------------------------------------------------------
849        const GpuConstantDefinition& GpuProgramParameters::getConstantDefinition(const String& name) const
850        {
851                if (!mNamedConstants)
852                        OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, 
853                        "This params object is not based on a program with named parameters.",
854                        "GpuProgramParameters::getConstantDefinitionIterator");
855
856
857                // locate, and throw exception if not found
858                const GpuConstantDefinition* def = _findNamedConstantDefinition(name, true);
859
860                return *def;
861
862        }
863        //-----------------------------------------------------------------------------
864        const GpuConstantDefinition* 
865        GpuProgramParameters::_findNamedConstantDefinition(const String& name, 
866                bool throwExceptionIfNotFound) const
867        {
868                if (!mNamedConstants)
869                {
870                        if (throwExceptionIfNotFound)
871                                OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, 
872                                "Named constants have not been initialised, perhaps a compile error.",
873                                "GpuProgramParameters::_findNamedConstantDefinition");
874                        return 0;
875                }
876
877                GpuConstantDefinitionMap::const_iterator i = mNamedConstants->map.find(name);
878                if (i == mNamedConstants->map.end())
879                {
880                        if (throwExceptionIfNotFound)
881                                OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, 
882                                "Parameter called " + name + " does not exist. ",
883                                "GpuProgramParameters::_findNamedConstantDefinition");
884                        return 0;
885                }
886                else
887                {
888                        return &(i->second);
889                }
890        }
891    //-----------------------------------------------------------------------------
892    void GpuProgramParameters::setAutoConstant(size_t index, AutoConstantType acType, size_t extraInfo)
893    {
894                // Get auto constant definition for sizing
895                const AutoConstantDefinition* autoDef = getAutoConstantDefinition(acType);
896                // round up to nearest multiple of 4
897                size_t sz = autoDef->elementCount;
898                if (sz % 4 > 0)
899                {
900                        sz += 4 - (sz % 4);
901                }
902
903                size_t physicalIndex = _getFloatConstantPhysicalIndex(index, sz);
904
905                _setRawAutoConstant(physicalIndex, acType, extraInfo);
906    }
907        //-----------------------------------------------------------------------------
908        void GpuProgramParameters::_setRawAutoConstant(size_t physicalIndex, 
909                AutoConstantType acType, size_t extraInfo, size_t elementSize)
910        {
911                // update existing index if it exists
912                bool found = false;
913                for (AutoConstantList::iterator i = mAutoConstants.begin(); 
914                        i != mAutoConstants.end(); ++i)
915                {
916                        if (i->physicalIndex == physicalIndex)
917                        {
918                                i->paramType = acType;
919                                i->data = extraInfo;
920                                i->elementCount = elementSize;
921                                found = true;
922                                break;
923                        }
924                }
925                if (!found)
926                        mAutoConstants.push_back(AutoConstantEntry(acType, physicalIndex, extraInfo, elementSize));
927
928        }
929        //-----------------------------------------------------------------------------
930        void GpuProgramParameters::_setRawAutoConstantReal(size_t physicalIndex, 
931                AutoConstantType acType, Real rData, size_t elementSize)
932        {
933                // update existing index if it exists
934                bool found = false;
935                for (AutoConstantList::iterator i = mAutoConstants.begin(); 
936                        i != mAutoConstants.end(); ++i)
937                {
938                        if (i->physicalIndex == physicalIndex)
939                        {
940                                i->paramType = acType;
941                                i->fData = rData;
942                                i->elementCount = elementSize;
943                                found = true;
944                                break;
945                        }
946                }
947                if (!found)
948                        mAutoConstants.push_back(AutoConstantEntry(acType, physicalIndex, rData, elementSize));
949
950        }
951        //-----------------------------------------------------------------------------
952        void GpuProgramParameters::clearAutoConstant(size_t index)
953        {
954                size_t physicalIndex = _getFloatConstantPhysicalIndex(index, 0);
955                if (physicalIndex != std::numeric_limits<size_t>::max())
956                {
957                        // update existing index if it exists
958                        for (AutoConstantList::iterator i = mAutoConstants.begin(); 
959                                i != mAutoConstants.end(); ++i)
960                        {
961                                if (i->physicalIndex == physicalIndex)
962                                {
963                                        mAutoConstants.erase(i);
964                                        break;
965                                }
966                        }
967                }
968        }
969        //-----------------------------------------------------------------------------
970        void GpuProgramParameters::clearNamedAutoConstant(const String& name)
971        {
972                const GpuConstantDefinition* def = _findNamedConstantDefinition(name);
973                if (def)
974                {
975                        // Autos are always floating point
976                        if (def->isFloat())
977                        {
978                                for (AutoConstantList::iterator i = mAutoConstants.begin(); 
979                                        i != mAutoConstants.end(); ++i)
980                                {
981                                        if (i->physicalIndex == def->physicalIndex)
982                                        {
983                                                mAutoConstants.erase(i);
984                                                break;
985                                        }
986                                }
987                        }
988
989                }
990        }
991    //-----------------------------------------------------------------------------
992    void GpuProgramParameters::clearAutoConstants(void)
993    {
994        mAutoConstants.clear();
995    }
996    //-----------------------------------------------------------------------------
997    GpuProgramParameters::AutoConstantIterator GpuProgramParameters::getAutoConstantIterator(void) const
998    {
999        return AutoConstantIterator(mAutoConstants.begin(), mAutoConstants.end());
1000    }
1001    //-----------------------------------------------------------------------------
1002    void GpuProgramParameters::setAutoConstantReal(size_t index, AutoConstantType acType, Real rData)
1003    {
1004                // Get auto constant definition for sizing
1005                const AutoConstantDefinition* autoDef = getAutoConstantDefinition(acType);
1006                // round up to nearest multiple of 4
1007                size_t sz = autoDef->elementCount;
1008                if (sz % 4 > 0)
1009                {
1010                        sz += 4 - (sz % 4);
1011                }
1012
1013                size_t physicalIndex = _getFloatConstantPhysicalIndex(index, sz);
1014
1015                _setRawAutoConstantReal(physicalIndex, acType, rData);
1016    }
1017    //-----------------------------------------------------------------------------
1018
1019    //-----------------------------------------------------------------------------
1020    void GpuProgramParameters::_updateAutoParamsNoLights(const AutoParamDataSource& source)
1021    {
1022        if (!hasAutoConstants()) return; // abort early if no autos
1023        Vector3 vec3;
1024        Vector4 vec4;
1025        size_t index;
1026        size_t numMatrices;
1027        const Matrix4* pMatrix;
1028        size_t m;
1029
1030                mActivePassIterationIndex = std::numeric_limits<size_t>::max();
1031
1032                // Autoconstant index is not a physical index
1033        AutoConstantList::const_iterator i, iend;
1034        iend = mAutoConstants.end();
1035        for (i = mAutoConstants.begin(); i != iend; ++i)
1036        {
1037            switch(i->paramType)
1038            {
1039            case ACT_WORLD_MATRIX:
1040                _writeRawConstant(i->physicalIndex, source.getWorldMatrix());
1041                break;
1042            case ACT_INVERSE_WORLD_MATRIX:
1043                _writeRawConstant(i->physicalIndex, source.getInverseWorldMatrix());
1044                break;
1045            case ACT_TRANSPOSE_WORLD_MATRIX:
1046               _writeRawConstant(i->physicalIndex, source.getTransposeWorldMatrix());
1047               break;
1048            case ACT_INVERSE_TRANSPOSE_WORLD_MATRIX:
1049               _writeRawConstant(i->physicalIndex, source.getInverseTransposeWorldMatrix());
1050               break;
1051
1052            case ACT_WORLD_MATRIX_ARRAY_3x4:
1053                // Loop over matrices
1054                pMatrix = source.getWorldMatrixArray();
1055                numMatrices = source.getWorldMatrixCount();
1056                index = i->physicalIndex;
1057                for (m = 0; m < numMatrices; ++m)
1058                {
1059                    _writeRawConstants(index, (*pMatrix)[0], 12);
1060                    index += 12;
1061                    ++pMatrix;
1062                }
1063               
1064                break;
1065            case ACT_WORLD_MATRIX_ARRAY:
1066                _writeRawConstant(i->physicalIndex, source.getWorldMatrixArray(), 
1067                    source.getWorldMatrixCount());
1068                break;
1069            case ACT_VIEW_MATRIX:
1070                _writeRawConstant(i->physicalIndex, source.getViewMatrix());
1071                break;
1072            case ACT_INVERSE_VIEW_MATRIX:
1073               _writeRawConstant(i->physicalIndex, source.getInverseViewMatrix());
1074               break;
1075            case ACT_TRANSPOSE_VIEW_MATRIX:
1076               _writeRawConstant(i->physicalIndex, source.getTransposeViewMatrix());
1077               break;
1078            case ACT_INVERSE_TRANSPOSE_VIEW_MATRIX:
1079               _writeRawConstant(i->physicalIndex, source.getInverseTransposeViewMatrix());
1080               break;
1081
1082            case ACT_PROJECTION_MATRIX:
1083                _writeRawConstant(i->physicalIndex, source.getProjectionMatrix());
1084                break;
1085            case ACT_INVERSE_PROJECTION_MATRIX:
1086               _writeRawConstant(i->physicalIndex, source.getInverseProjectionMatrix());
1087               break;
1088            case ACT_TRANSPOSE_PROJECTION_MATRIX:
1089               _writeRawConstant(i->physicalIndex, source.getTransposeProjectionMatrix());
1090               break;
1091            case ACT_INVERSE_TRANSPOSE_PROJECTION_MATRIX:
1092               _writeRawConstant(i->physicalIndex, source.getInverseTransposeProjectionMatrix());
1093               break;
1094
1095            case ACT_VIEWPROJ_MATRIX:
1096                _writeRawConstant(i->physicalIndex, source.getViewProjectionMatrix());
1097                break;
1098            case ACT_INVERSE_VIEWPROJ_MATRIX:
1099               _writeRawConstant(i->physicalIndex, source.getInverseViewProjMatrix());
1100               break;
1101            case ACT_TRANSPOSE_VIEWPROJ_MATRIX:
1102               _writeRawConstant(i->physicalIndex, source.getTransposeViewProjMatrix());
1103               break;
1104            case ACT_INVERSE_TRANSPOSE_VIEWPROJ_MATRIX:
1105               _writeRawConstant(i->physicalIndex, source.getInverseTransposeViewProjMatrix());
1106               break;
1107
1108            case ACT_WORLDVIEW_MATRIX:
1109                _writeRawConstant(i->physicalIndex, source.getWorldViewMatrix());
1110                break;
1111            case ACT_INVERSE_WORLDVIEW_MATRIX:
1112                _writeRawConstant(i->physicalIndex, source.getInverseWorldViewMatrix());
1113                break;
1114            case ACT_TRANSPOSE_WORLDVIEW_MATRIX:
1115               _writeRawConstant(i->physicalIndex, source.getTransposeWorldViewMatrix());
1116               break;
1117            case ACT_INVERSE_TRANSPOSE_WORLDVIEW_MATRIX:
1118               _writeRawConstant(i->physicalIndex, source.getInverseTransposeWorldViewMatrix());
1119               break;
1120
1121            case ACT_WORLDVIEWPROJ_MATRIX:
1122                _writeRawConstant(i->physicalIndex, source.getWorldViewProjMatrix());
1123                break;
1124            case ACT_INVERSE_WORLDVIEWPROJ_MATRIX:
1125               _writeRawConstant(i->physicalIndex, source.getInverseWorldViewProjMatrix());
1126               break;
1127            case ACT_TRANSPOSE_WORLDVIEWPROJ_MATRIX:
1128               _writeRawConstant(i->physicalIndex, source.getTransposeWorldViewProjMatrix());
1129               break;
1130            case ACT_INVERSE_TRANSPOSE_WORLDVIEWPROJ_MATRIX:
1131               _writeRawConstant(i->physicalIndex, source.getInverseTransposeWorldViewProjMatrix());
1132               break;
1133
1134            case ACT_RENDER_TARGET_FLIPPING:
1135               _writeRawConstant(i->physicalIndex, source.getCurrentRenderTarget()->requiresTextureFlipping() ? -1.f : +1.f);
1136               break;
1137
1138            // NB ambient light still here because it's not related to a specific light
1139            case ACT_AMBIENT_LIGHT_COLOUR: 
1140                _writeRawConstant(i->physicalIndex, source.getAmbientLightColour(), 
1141                                        i->elementCount);
1142                break;
1143            case ACT_DERIVED_AMBIENT_LIGHT_COLOUR:
1144                _writeRawConstant(i->physicalIndex, source.getDerivedAmbientLightColour(),
1145                    i->elementCount);
1146                break;
1147            case ACT_DERIVED_SCENE_COLOUR:
1148                _writeRawConstant(i->physicalIndex, source.getDerivedSceneColour(),
1149                    i->elementCount);
1150                break;
1151
1152            case ACT_FOG_COLOUR:
1153                _writeRawConstant(i->physicalIndex, source.getFogColour());
1154                break;
1155            case ACT_FOG_PARAMS:
1156                _writeRawConstant(i->physicalIndex, source.getFogParams(), i->elementCount);
1157                break;
1158
1159            case ACT_SURFACE_AMBIENT_COLOUR:
1160                _writeRawConstant(i->physicalIndex, source.getSurfaceAmbientColour(),
1161                    i->elementCount);
1162                break;
1163            case ACT_SURFACE_DIFFUSE_COLOUR:
1164                _writeRawConstant(i->physicalIndex, source.getSurfaceDiffuseColour(),
1165                    i->elementCount);
1166                break;
1167            case ACT_SURFACE_SPECULAR_COLOUR:
1168                _writeRawConstant(i->physicalIndex, source.getSurfaceSpecularColour(),
1169                    i->elementCount);
1170                break;
1171            case ACT_SURFACE_EMISSIVE_COLOUR:
1172                _writeRawConstant(i->physicalIndex, source.getSurfaceEmissiveColour(),
1173                    i->elementCount);
1174                break;
1175            case ACT_SURFACE_SHININESS:
1176                _writeRawConstant(i->physicalIndex, source.getSurfaceShininess());
1177                break;
1178
1179            case ACT_CAMERA_POSITION:
1180                _writeRawConstant(i->physicalIndex, source.getCameraPosition(), i->elementCount);
1181                break;
1182            case ACT_CAMERA_POSITION_OBJECT_SPACE:
1183                _writeRawConstant(i->physicalIndex, source.getCameraPositionObjectSpace(), i->elementCount);
1184                break;
1185
1186            case ACT_TIME:
1187               _writeRawConstant(i->physicalIndex, source.getTime() * i->fData);
1188               break;
1189           case ACT_TIME_0_X:
1190               _writeRawConstant(i->physicalIndex, source.getTime_0_X(i->fData));
1191               break;
1192            case ACT_COSTIME_0_X:
1193               _writeRawConstant(i->physicalIndex, source.getCosTime_0_X(i->fData));
1194               break;
1195            case ACT_SINTIME_0_X:
1196               _writeRawConstant(i->physicalIndex, source.getSinTime_0_X(i->fData));
1197               break;
1198            case ACT_TANTIME_0_X:
1199               _writeRawConstant(i->physicalIndex, source.getTanTime_0_X(i->fData));
1200               break;
1201            case ACT_TIME_0_X_PACKED:
1202               _writeRawConstant(i->physicalIndex, source.getTime_0_X_packed(i->fData), i->elementCount);
1203               break;
1204            case ACT_TIME_0_1:
1205               _writeRawConstant(i->physicalIndex, source.getTime_0_1(i->fData));
1206               break;
1207            case ACT_COSTIME_0_1:
1208               _writeRawConstant(i->physicalIndex, source.getCosTime_0_1(i->fData));
1209               break;
1210            case ACT_SINTIME_0_1:
1211               _writeRawConstant(i->physicalIndex, source.getSinTime_0_1(i->fData));
1212               break;
1213            case ACT_TANTIME_0_1:
1214               _writeRawConstant(i->physicalIndex, source.getTanTime_0_1(i->fData));
1215               break;
1216            case ACT_TIME_0_1_PACKED:
1217               _writeRawConstant(i->physicalIndex, source.getTime_0_1_packed(i->fData), i->elementCount);
1218               break;
1219            case ACT_TIME_0_2PI:
1220               _writeRawConstant(i->physicalIndex, source.getTime_0_2Pi(i->fData));
1221               break;
1222            case ACT_COSTIME_0_2PI:
1223               _writeRawConstant(i->physicalIndex, source.getCosTime_0_2Pi(i->fData));
1224               break;
1225            case ACT_SINTIME_0_2PI:
1226               _writeRawConstant(i->physicalIndex, source.getSinTime_0_2Pi(i->fData));
1227               break;
1228            case ACT_TANTIME_0_2PI:
1229               _writeRawConstant(i->physicalIndex, source.getTanTime_0_2Pi(i->fData));
1230               break;
1231            case ACT_TIME_0_2PI_PACKED:
1232               _writeRawConstant(i->physicalIndex, source.getTime_0_2Pi_packed(i->fData), i->elementCount);
1233               break;
1234            case ACT_FRAME_TIME:
1235               _writeRawConstant(i->physicalIndex, source.getFrameTime() * i->fData);
1236               break;
1237            case ACT_FPS:
1238               _writeRawConstant(i->physicalIndex, source.getFPS());
1239               break;
1240            case ACT_VIEWPORT_WIDTH:
1241               _writeRawConstant(i->physicalIndex, source.getViewportWidth());
1242               break;
1243            case ACT_VIEWPORT_HEIGHT:
1244               _writeRawConstant(i->physicalIndex, source.getViewportHeight());
1245               break;
1246            case ACT_INVERSE_VIEWPORT_WIDTH:
1247               _writeRawConstant(i->physicalIndex, source.getInverseViewportWidth());
1248               break;
1249            case ACT_INVERSE_VIEWPORT_HEIGHT:
1250               _writeRawConstant(i->physicalIndex, source.getInverseViewportHeight());
1251               break;
1252            case ACT_VIEWPORT_SIZE:
1253               _writeRawConstant(i->physicalIndex, Vector4(
1254                   source.getViewportWidth(),
1255                   source.getViewportHeight(),
1256                   source.getInverseViewportWidth(),
1257                   source.getInverseViewportHeight()), i->elementCount);
1258               break;
1259                        case ACT_TEXEL_OFFSETS:
1260                                {
1261                                        RenderSystem* rsys = Root::getSingleton().getRenderSystem();
1262                                        _writeRawConstant(i->physicalIndex, Vector4(
1263                                                rsys->getHorizontalTexelOffset(), 
1264                                                rsys->getVerticalTexelOffset(), 
1265                                                rsys->getHorizontalTexelOffset() * source.getInverseViewportWidth(),
1266                                                rsys->getVerticalTexelOffset() * source.getInverseViewportHeight()),
1267                                                i->elementCount);
1268                                }
1269                                break;
1270            case ACT_TEXTURE_SIZE:
1271                _writeRawConstant(i->physicalIndex, source.getTextureSize(i->data), i->elementCount);
1272                break;
1273            case ACT_INVERSE_TEXTURE_SIZE:
1274                _writeRawConstant(i->physicalIndex, source.getInverseTextureSize(i->data), i->elementCount);
1275                break;
1276            case ACT_PACKED_TEXTURE_SIZE:
1277                _writeRawConstant(i->physicalIndex, source.getPackedTextureSize(i->data), i->elementCount);
1278                break;
1279                        case ACT_SCENE_DEPTH_RANGE:
1280                                _writeRawConstant(i->physicalIndex, source.getSceneDepthRange(), i->elementCount);
1281                                break;
1282            case ACT_VIEW_DIRECTION:
1283               _writeRawConstant(i->physicalIndex, source.getViewDirection());
1284               break;
1285            case ACT_VIEW_SIDE_VECTOR:
1286               _writeRawConstant(i->physicalIndex, source.getViewSideVector());
1287               break;
1288            case ACT_VIEW_UP_VECTOR:
1289               _writeRawConstant(i->physicalIndex, source.getViewUpVector());
1290               break;
1291            case ACT_FOV:
1292               _writeRawConstant(i->physicalIndex, source.getFOV());
1293               break;
1294            case ACT_NEAR_CLIP_DISTANCE:
1295               _writeRawConstant(i->physicalIndex, source.getNearClipDistance());
1296               break;
1297            case ACT_FAR_CLIP_DISTANCE:
1298               _writeRawConstant(i->physicalIndex, source.getFarClipDistance());
1299               break;
1300            case ACT_PASS_NUMBER:
1301                _writeRawConstant(i->physicalIndex, (float)source.getPassNumber());
1302                break;
1303            case ACT_PASS_ITERATION_NUMBER:
1304                _writeRawConstant(i->physicalIndex, 0.0f);
1305                mActivePassIterationIndex = i->physicalIndex;
1306                break;
1307            case ACT_CUSTOM:
1308                        case ACT_ANIMATION_PARAMETRIC:
1309                source.getCurrentRenderable()->_updateCustomGpuParameter(*i, this);
1310                break;
1311            default:
1312                break;
1313            }
1314        }
1315    }
1316    //-----------------------------------------------------------------------------
1317    void GpuProgramParameters::_updateAutoParamsLightsOnly(const AutoParamDataSource& source)
1318    {
1319        if (!hasAutoConstants()) return; // abort early if no autos
1320        Vector3 vec3;
1321        Vector4 vec4;
1322                Matrix3 m3;
1323
1324        AutoConstantList::const_iterator i, iend;
1325        iend = mAutoConstants.end();
1326        for (i = mAutoConstants.begin(); i != iend; ++i)
1327        {
1328            switch(i->paramType)
1329            {
1330            case ACT_LIGHT_DIFFUSE_COLOUR:
1331                _writeRawConstant(i->physicalIndex, source.getLight(i->data).getDiffuseColour(), i->elementCount);
1332                break;
1333            case ACT_LIGHT_SPECULAR_COLOUR:
1334                _writeRawConstant(i->physicalIndex, source.getLight(i->data).getSpecularColour(), i->elementCount);
1335                break;
1336            case ACT_LIGHT_POSITION:
1337                // Get as 4D vector, works for directional lights too
1338                                // Use element count in case uniform slot is smaller
1339                _writeRawConstant(i->physicalIndex, 
1340                    source.getLight(i->data).getAs4DVector(), i->elementCount);
1341                break;
1342            case ACT_LIGHT_DIRECTION:
1343                vec3 = source.getLight(i->data).getDerivedDirection();
1344                // Set as 4D vector for compatibility
1345                                // Use element count in case uniform slot is smaller
1346                _writeRawConstant(i->physicalIndex, Vector4(vec3.x, vec3.y, vec3.z, 1.0f), i->elementCount);
1347                break;
1348            case ACT_LIGHT_POSITION_OBJECT_SPACE:
1349                _writeRawConstant(i->physicalIndex, 
1350                    source.getInverseWorldMatrix().transformAffine(
1351                                                source.getLight(i->data).getAs4DVector()), 
1352                                        i->elementCount);
1353                break;
1354            case ACT_LIGHT_DIRECTION_OBJECT_SPACE:
1355                                // We need the inverse of the inverse transpose
1356                                source.getInverseTransposeWorldMatrix().inverse().extract3x3Matrix(m3);
1357                                vec3 = m3 * source.getLight(i->data).getDerivedDirection();
1358                                vec3.normalise();
1359                // Set as 4D vector for compatibility
1360                _writeRawConstant(i->physicalIndex, Vector4(vec3.x, vec3.y, vec3.z, 0.0f), i->elementCount);
1361                break;
1362                        case ACT_LIGHT_POSITION_VIEW_SPACE:
1363                _writeRawConstant(i->physicalIndex, 
1364                    source.getViewMatrix().transformAffine(source.getLight(i->data).getAs4DVector()), i->elementCount);
1365                break;
1366            case ACT_LIGHT_DIRECTION_VIEW_SPACE:
1367                                source.getInverseTransposeViewMatrix().extract3x3Matrix(m3);
1368                                // inverse transpose in case of scaling
1369                                vec3 = m3 * source.getLight(i->data).getDerivedDirection();
1370                vec3.normalise();
1371                // Set as 4D vector for compatibility
1372                _writeRawConstant(i->physicalIndex, Vector4(vec3.x, vec3.y, vec3.z, 0.0f),i->elementCount);
1373                break;
1374            case ACT_LIGHT_DISTANCE_OBJECT_SPACE:
1375                vec3 = source.getInverseWorldMatrix().transformAffine(source.getLight(i->data).getDerivedPosition());
1376                _writeRawConstant(i->physicalIndex, vec3.length());
1377                break;
1378            case ACT_SHADOW_EXTRUSION_DISTANCE:
1379                _writeRawConstant(i->physicalIndex, source.getShadowExtrusionDistance());
1380                break;
1381                        case ACT_SHADOW_SCENE_DEPTH_RANGE:
1382                                _writeRawConstant(i->physicalIndex, source.getShadowSceneDepthRange(i->data));
1383                                break;
1384            case ACT_LIGHT_POWER_SCALE:
1385                                _writeRawConstant(i->physicalIndex, source.getLight(i->data).getPowerScale());
1386                                break;
1387            case ACT_LIGHT_ATTENUATION:
1388            {
1389                // range, const, linear, quad
1390                const Light& l = source.getLight(i->data);
1391                vec4.x = l.getAttenuationRange();
1392                vec4.y = l.getAttenuationConstant();
1393                vec4.z = l.getAttenuationLinear();
1394                vec4.w = l.getAttenuationQuadric();
1395                _writeRawConstant(i->physicalIndex, vec4, i->elementCount);
1396                break;
1397            }
1398                        case ACT_SPOTLIGHT_PARAMS:
1399                        {
1400                                // inner, outer, fallof, isSpot
1401                                const Light& l = source.getLight(i->data);
1402                                if (l.getType() == Light::LT_SPOTLIGHT)
1403                                {
1404                                        vec4.x = Math::Cos(l.getSpotlightInnerAngle().valueRadians() * 0.5);
1405                                        vec4.y = Math::Cos(l.getSpotlightOuterAngle().valueRadians() * 0.5);
1406                                        vec4.z = l.getSpotlightFalloff();
1407                                        vec4.w = 1.0f;
1408                                }
1409                                else
1410                                {
1411                                        // Use safe values which result in no change to point & dir light calcs
1412                                        // The spot factor applied to the usual lighting calc is
1413                                        // pow((dot(spotDir, lightDir) - y) / (x - y), z)
1414                                        // Therefore if we set z to 0.0f then the factor will always be 1
1415                                        // since pow(anything, 0) == 1
1416                                        // However we also need to ensure we don't overflow because of the division
1417                                        // therefore set x = 1 and y = 0 so divisor doesn't change scale
1418                                        vec4.x = 1.0f;
1419                                        vec4.y = 0.0f;
1420                                        vec4.z = 0.0f; // since the main op is pow(.., vec4.z), this will result in 1.0
1421                                        vec4.w = 1.0f;
1422                                }
1423                                _writeRawConstant(i->physicalIndex, vec4, i->elementCount);
1424                                break;
1425                        }
1426                        case ACT_LIGHT_DIFFUSE_COLOUR_ARRAY:
1427                                for (size_t l = 0; l < i->data; ++l)
1428                                        _writeRawConstant(i->physicalIndex + l*i->elementCount, 
1429                                                source.getLight(l).getDiffuseColour(), i->elementCount);
1430                                break;
1431
1432                        case ACT_LIGHT_SPECULAR_COLOUR_ARRAY:
1433                                for (size_t l = 0; l < i->data; ++l)
1434                                        _writeRawConstant(i->physicalIndex + l*i->elementCount, 
1435                                                source.getLight(l).getSpecularColour(), i->elementCount);
1436                                break;
1437
1438                        case ACT_LIGHT_POSITION_ARRAY:
1439                                // Get as 4D vector, works for directional lights too
1440                                for (size_t l = 0; l < i->data; ++l)
1441                                        _writeRawConstant(i->physicalIndex + l*i->elementCount, 
1442                                                source.getLight(l).getAs4DVector(), i->elementCount);
1443                                break;
1444
1445                        case ACT_LIGHT_DIRECTION_ARRAY:
1446                                for (size_t l = 0; l < i->data; ++l)
1447                                {
1448                                        vec3 = source.getLight(l).getDerivedDirection();
1449                                        // Set as 4D vector for compatibility
1450                                        _writeRawConstant(i->physicalIndex + l*i->elementCount, 
1451                                                Vector4(vec3.x, vec3.y, vec3.z, 0.0f), i->elementCount);
1452                                }
1453                                break;
1454
1455                        case ACT_LIGHT_POSITION_OBJECT_SPACE_ARRAY:
1456                                for (size_t l = 0; l < i->data; ++l)
1457                                        _writeRawConstant(i->physicalIndex + l*i->elementCount, 
1458                                                source.getInverseWorldMatrix().transformAffine(
1459                                                        source.getLight(l).getAs4DVector()), 
1460                                                i->elementCount);
1461                                break;
1462
1463                        case ACT_LIGHT_DIRECTION_OBJECT_SPACE_ARRAY:
1464                                // We need the inverse of the inverse transpose
1465                                source.getInverseTransposeWorldMatrix().inverse().extract3x3Matrix(m3);
1466                                for (size_t l = 0; l < i->data; ++l)
1467                                {
1468                                        vec3 = m3 * source.getLight(l).getDerivedDirection();
1469                                        vec3.normalise();
1470                                        _writeRawConstant(i->physicalIndex + l*i->elementCount, 
1471                                                Vector4(vec3.x, vec3.y, vec3.z, 0.0f), i->elementCount); 
1472                                }
1473                                break;
1474
1475                        case ACT_LIGHT_POSITION_VIEW_SPACE_ARRAY:
1476                                for (size_t l = 0; l < i->data; ++l)
1477                                        _writeRawConstant(i->physicalIndex + l*i->elementCount, 
1478                                                source.getViewMatrix().transformAffine(
1479                                                        source.getLight(l).getAs4DVector()),
1480                                                i->elementCount);
1481                                break;
1482
1483                        case ACT_LIGHT_DIRECTION_VIEW_SPACE_ARRAY:
1484                                source.getInverseTransposeViewMatrix().extract3x3Matrix(m3);
1485                                for (size_t l = 0; l < i->data; ++l)
1486                                {
1487                                        vec3 = m3 * source.getLight(l).getDerivedDirection();
1488                                        vec3.normalise();
1489                                        // Set as 4D vector for compatibility
1490                                        _writeRawConstant(i->physicalIndex + l*i->elementCount, 
1491                                                Vector4(vec3.x, vec3.y, vec3.z, 0.0f), i->elementCount);
1492                                }
1493                                break;
1494
1495                        case ACT_LIGHT_DISTANCE_OBJECT_SPACE_ARRAY:
1496                                for (size_t l = 0; l < i->data; ++l)
1497                                {
1498                                        vec3 = source.getInverseWorldMatrix().transformAffine(source.getLight(l).getDerivedPosition());
1499                                        _writeRawConstant(i->physicalIndex + l*i->elementCount, vec3.length());
1500                                }
1501                                break;
1502
1503                        case ACT_LIGHT_POWER_SCALE_ARRAY:
1504                                for (size_t l = 0; l < i->data; ++l)
1505                                        _writeRawConstant(i->physicalIndex + l*i->elementCount, 
1506                                                source.getLight(l).getPowerScale());
1507                                break;
1508
1509                        case ACT_LIGHT_ATTENUATION_ARRAY:
1510                                for (size_t l = 0; l < i->data; ++l)
1511                                {
1512                                        // range, const, linear, quad
1513                                        const Light& light = source.getLight(l);
1514                                        vec4.x = light.getAttenuationRange();
1515                                        vec4.y = light.getAttenuationConstant();
1516                                        vec4.z = light.getAttenuationLinear();
1517                                        vec4.w = light.getAttenuationQuadric();
1518                                        _writeRawConstant(i->physicalIndex + l*i->elementCount, vec4, 
1519                                                i->elementCount);
1520                                }
1521                                break;
1522                        case ACT_SPOTLIGHT_PARAMS_ARRAY:
1523                                {
1524                                        for (size_t l = 0 ; l < i->data; ++l)
1525                                        {
1526                                                // inner, outer, fallof, isSpot
1527                                                const Light& light = source.getLight(l);
1528                                                if (light.getType() == Light::LT_SPOTLIGHT)
1529                                                {
1530                                                        vec4.x = Math::Cos(light.getSpotlightInnerAngle().valueRadians() * 0.5);
1531                                                        vec4.y = Math::Cos(light.getSpotlightOuterAngle().valueRadians() * 0.5);
1532                                                        vec4.z = light.getSpotlightFalloff();
1533                                                        vec4.w = 1.0f;
1534                                                }
1535                                                else
1536                                                {
1537                                                        // Set angles to full circle for generality
1538                                                        vec4.x = vec4.y = 1.0f;
1539                                                        // reduce outer angle slightly to avoid divide by zero
1540                                                        vec4.y -= 1e-5f;
1541                                                        vec4.z = vec4.w = 0.0f;
1542                                                }
1543                                                _writeRawConstant(i->physicalIndex + l*i->elementCount, vec4, 
1544                                                        i->elementCount);
1545
1546                                        }
1547                                        break;
1548                                }
1549            case ACT_DERIVED_LIGHT_DIFFUSE_COLOUR:
1550                _writeRawConstant(i->physicalIndex,
1551                    source.getLight(i->data).getDiffuseColour() * source.getSurfaceDiffuseColour(),
1552                    i->elementCount);
1553                break;
1554            case ACT_DERIVED_LIGHT_SPECULAR_COLOUR:
1555                _writeRawConstant(i->physicalIndex,
1556                    source.getLight(i->data).getSpecularColour() * source.getSurfaceSpecularColour(),
1557                    i->elementCount);
1558                break;
1559            case ACT_DERIVED_LIGHT_DIFFUSE_COLOUR_ARRAY:
1560                                for (size_t l = 0; l < i->data; ++l)
1561                {
1562                                        _writeRawConstant(i->physicalIndex + l*i->elementCount, 
1563                        source.getLight(l).getDiffuseColour() * source.getSurfaceDiffuseColour(),
1564                        i->elementCount);
1565                }
1566                break;
1567            case ACT_DERIVED_LIGHT_SPECULAR_COLOUR_ARRAY:
1568                                for (size_t l = 0; l < i->data; ++l)
1569                {
1570                                        _writeRawConstant(i->physicalIndex + l*i->elementCount, 
1571                        source.getLight(l).getSpecularColour() * source.getSurfaceSpecularColour(),
1572                        i->elementCount);
1573                }
1574                break;
1575                        case ACT_TEXTURE_VIEWPROJ_MATRIX:
1576                                // can also be updated in lights
1577                                _writeRawConstant(i->physicalIndex, source.getTextureViewProjMatrix(i->data));
1578                                break;
1579            default:
1580                // do nothing
1581                break;
1582            }
1583        }
1584    }
1585    //---------------------------------------------------------------------------
1586    void GpuProgramParameters::setNamedConstant(const String& name, Real val)
1587    {
1588                // look up, and throw an exception if we're not ignoring missing
1589                const GpuConstantDefinition* def = 
1590                        _findNamedConstantDefinition(name, !mIgnoreMissingParams);
1591                if (def)
1592                        _writeRawConstant(def->physicalIndex, val);
1593    }
1594    //---------------------------------------------------------------------------
1595    void GpuProgramParameters::setNamedConstant(const String& name, int val)
1596    {
1597                // look up, and throw an exception if we're not ignoring missing
1598                const GpuConstantDefinition* def = 
1599                        _findNamedConstantDefinition(name, !mIgnoreMissingParams);
1600                if (def)
1601                        _writeRawConstant(def->physicalIndex, val);
1602    }
1603    //---------------------------------------------------------------------------
1604    void GpuProgramParameters::setNamedConstant(const String& name, const Vector4& vec)
1605    {
1606                // look up, and throw an exception if we're not ignoring missing
1607                const GpuConstantDefinition* def = 
1608                        _findNamedConstantDefinition(name, !mIgnoreMissingParams);
1609                if (def)
1610                        _writeRawConstant(def->physicalIndex, vec, def->elementSize);
1611    }
1612    //---------------------------------------------------------------------------
1613    void GpuProgramParameters::setNamedConstant(const String& name, const Vector3& vec)
1614    {
1615                // look up, and throw an exception if we're not ignoring missing
1616                const GpuConstantDefinition* def = 
1617                        _findNamedConstantDefinition(name, !mIgnoreMissingParams);
1618                if (def)
1619                        _writeRawConstant(def->physicalIndex, vec);
1620    }
1621    //---------------------------------------------------------------------------
1622    void GpuProgramParameters::setNamedConstant(const String& name, const Matrix4& m)
1623    {
1624                // look up, and throw an exception if we're not ignoring missing
1625                const GpuConstantDefinition* def = 
1626                        _findNamedConstantDefinition(name, !mIgnoreMissingParams);
1627                if (def)
1628                        _writeRawConstant(def->physicalIndex, m);
1629    }
1630    //---------------------------------------------------------------------------
1631    void GpuProgramParameters::setNamedConstant(const String& name, const Matrix4* m, 
1632        size_t numEntries)
1633    {
1634                // look up, and throw an exception if we're not ignoring missing
1635                const GpuConstantDefinition* def = 
1636                        _findNamedConstantDefinition(name, !mIgnoreMissingParams);
1637                if (def)
1638                        _writeRawConstant(def->physicalIndex, m, numEntries);
1639    }
1640    //---------------------------------------------------------------------------
1641    void GpuProgramParameters::setNamedConstant(const String& name, 
1642                const float *val, size_t count, size_t multiple)
1643    {
1644                size_t rawCount = count * multiple;
1645                // look up, and throw an exception if we're not ignoring missing
1646                const GpuConstantDefinition* def = 
1647                        _findNamedConstantDefinition(name, !mIgnoreMissingParams);
1648                if (def)
1649                        _writeRawConstants(def->physicalIndex, val, rawCount);
1650    }
1651    //---------------------------------------------------------------------------
1652    void GpuProgramParameters::setNamedConstant(const String& name, 
1653                const double *val, size_t count, size_t multiple)
1654    {
1655                size_t rawCount = count * multiple;
1656                // look up, and throw an exception if we're not ignoring missing
1657                const GpuConstantDefinition* def = 
1658                        _findNamedConstantDefinition(name, !mIgnoreMissingParams);
1659                if (def)
1660                        _writeRawConstants(def->physicalIndex, val, rawCount);
1661    }
1662    //---------------------------------------------------------------------------
1663    void GpuProgramParameters::setNamedConstant(const String& name, const ColourValue& colour)
1664    {
1665                // look up, and throw an exception if we're not ignoring missing
1666                const GpuConstantDefinition* def = 
1667                        _findNamedConstantDefinition(name, !mIgnoreMissingParams);
1668                if (def)
1669                        _writeRawConstant(def->physicalIndex, colour, def->elementSize);
1670    }
1671    //---------------------------------------------------------------------------
1672    void GpuProgramParameters::setNamedConstant(const String& name, 
1673                const int *val, size_t count, size_t multiple)
1674    {
1675                size_t rawCount = count * multiple;
1676                // look up, and throw an exception if we're not ignoring missing
1677                const GpuConstantDefinition* def = 
1678                        _findNamedConstantDefinition(name, !mIgnoreMissingParams);
1679                if (def)
1680                        _writeRawConstants(def->physicalIndex, val, rawCount);
1681    }
1682    //---------------------------------------------------------------------------
1683    void GpuProgramParameters::setNamedAutoConstant(const String& name, 
1684                AutoConstantType acType, size_t extraInfo)
1685    {
1686                // look up, and throw an exception if we're not ignoring missing
1687                const GpuConstantDefinition* def = 
1688                        _findNamedConstantDefinition(name, !mIgnoreMissingParams);
1689                if (def)
1690                        _setRawAutoConstant(def->physicalIndex, acType, extraInfo, def->elementSize);
1691
1692    }
1693        //---------------------------------------------------------------------------
1694        void GpuProgramParameters::setNamedAutoConstantReal(const String& name, 
1695                AutoConstantType acType, Real rData)
1696        {
1697                // look up, and throw an exception if we're not ignoring missing
1698                const GpuConstantDefinition* def = 
1699                        _findNamedConstantDefinition(name, !mIgnoreMissingParams);
1700                if (def)
1701                        _setRawAutoConstantReal(def->physicalIndex, acType, rData, def->elementSize);
1702
1703        }
1704    //---------------------------------------------------------------------------
1705    void GpuProgramParameters::setConstantFromTime(size_t index, Real factor)
1706    {
1707        setAutoConstantReal(index, ACT_TIME, factor);
1708    }
1709    //---------------------------------------------------------------------------
1710    void GpuProgramParameters::setNamedConstantFromTime(const String& name, Real factor)
1711    {
1712                setNamedAutoConstantReal(name, ACT_TIME, factor);
1713    }
1714    //---------------------------------------------------------------------------
1715    GpuProgramParameters::AutoConstantEntry* GpuProgramParameters::getAutoConstantEntry(const size_t index)
1716    {
1717        if (index < mAutoConstants.size())
1718        {
1719            return &(mAutoConstants[index]);
1720        }
1721        else
1722        {
1723            return NULL;
1724        }
1725    }
1726        //---------------------------------------------------------------------------
1727        const GpuProgramParameters::AutoConstantEntry* 
1728        GpuProgramParameters::findFloatAutoConstantEntry(size_t logicalIndex)
1729        {
1730                if (!mFloatLogicalToPhysical)
1731                        OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, 
1732                        "This is not a low-level parameter parameter object",
1733                        "GpuProgramParameters::findFloatAutoConstantEntry");
1734
1735                return _findRawAutoConstantEntryFloat(
1736                        _getFloatConstantPhysicalIndex(logicalIndex, 0));
1737
1738        }
1739        //---------------------------------------------------------------------------
1740        const GpuProgramParameters::AutoConstantEntry* 
1741                GpuProgramParameters::findIntAutoConstantEntry(size_t logicalIndex)
1742        {
1743                if (!mIntLogicalToPhysical)
1744                        OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, 
1745                        "This is not a low-level parameter parameter object",
1746                        "GpuProgramParameters::findIntAutoConstantEntry");
1747
1748                return _findRawAutoConstantEntryInt(
1749                        _getIntConstantPhysicalIndex(logicalIndex, 0));
1750
1751
1752        }
1753        //---------------------------------------------------------------------------
1754        const GpuProgramParameters::AutoConstantEntry* 
1755        GpuProgramParameters::findAutoConstantEntry(const String& paramName)
1756        {
1757                if (!mNamedConstants)
1758                        OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, 
1759                        "This params object is not based on a program with named parameters.",
1760                        "GpuProgramParameters::findAutoConstantEntry");
1761
1762                const GpuConstantDefinition& def = getConstantDefinition(paramName);
1763                if (def.isFloat())
1764                {
1765                        return _findRawAutoConstantEntryFloat(def.physicalIndex);
1766                }
1767                else
1768                {
1769                        return _findRawAutoConstantEntryInt(def.physicalIndex);
1770                }
1771        }
1772        //---------------------------------------------------------------------------
1773        const GpuProgramParameters::AutoConstantEntry* 
1774        GpuProgramParameters::_findRawAutoConstantEntryFloat(size_t physicalIndex)
1775        {
1776                for(AutoConstantList::iterator i = mAutoConstants.begin();
1777                        i != mAutoConstants.end(); ++i)
1778                {
1779                        AutoConstantEntry& ac = *i;
1780                        // should check that auto is float and not int so that physicalIndex
1781                        // doesn't have any ambiguity
1782                        // However, all autos are float I think so no need
1783                        if (ac.physicalIndex == physicalIndex)
1784                                return &ac;
1785                }
1786
1787                return 0;
1788
1789        }
1790        //---------------------------------------------------------------------------
1791        const GpuProgramParameters::AutoConstantEntry* 
1792        GpuProgramParameters::_findRawAutoConstantEntryInt(size_t physicalIndex)
1793        {
1794                // No autos are float?
1795                return 0;
1796        }
1797    //---------------------------------------------------------------------------
1798    void GpuProgramParameters::copyConstantsFrom(const GpuProgramParameters& source)
1799    {
1800                // Pull buffers & auto constant list over directly
1801                mFloatConstants = source.getFloatConstantList();
1802                mIntConstants = source.getIntConstantList();
1803                mAutoConstants = source.getAutoConstantList();
1804    }
1805    //-----------------------------------------------------------------------
1806    const GpuProgramParameters::AutoConstantDefinition* 
1807        GpuProgramParameters::getAutoConstantDefinition(const String& name)
1808    {
1809        // find a constant definition that matches name by iterating through the
1810                // constant definition array
1811        bool nameFound = false;
1812        size_t i = 0;
1813        const size_t numDefs = getNumAutoConstantDefinitions();
1814        while (!nameFound && (i < numDefs))
1815        {
1816            if (name == AutoConstantDictionary[i].name) 
1817                nameFound = true;
1818            else
1819                ++i;
1820        }
1821
1822        if (nameFound)
1823            return &AutoConstantDictionary[i];
1824        else
1825            return 0;
1826    }
1827
1828    //-----------------------------------------------------------------------
1829    const GpuProgramParameters::AutoConstantDefinition* 
1830        GpuProgramParameters::getAutoConstantDefinition(const size_t idx) 
1831    {
1832
1833        if (idx < getNumAutoConstantDefinitions())
1834        {
1835            // verify index is equal to acType
1836            // if they are not equal then the dictionary was not setup properly
1837            assert(idx == static_cast<size_t>(AutoConstantDictionary[idx].acType));
1838            return &AutoConstantDictionary[idx];
1839        }
1840        else
1841            return 0;
1842    }
1843    //-----------------------------------------------------------------------
1844    size_t GpuProgramParameters::getNumAutoConstantDefinitions(void)
1845    {
1846        return sizeof(AutoConstantDictionary)/sizeof(AutoConstantDefinition);
1847    }
1848
1849    //-----------------------------------------------------------------------
1850    void GpuProgramParameters::incPassIterationNumber(void)
1851    {
1852                if (mActivePassIterationIndex != std::numeric_limits<size_t>::max())
1853        {
1854                        // This is a physical index
1855                        ++mFloatConstants[mActivePassIterationIndex];
1856        }
1857    }
1858
1859    //-----------------------------------------------------------------------
1860    //-----------------------------------------------------------------------
1861    String GpuProgram::CmdType::doGet(const void* target) const
1862    {
1863        const GpuProgram* t = static_cast<const GpuProgram*>(target);
1864        if (t->getType() == GPT_VERTEX_PROGRAM)
1865        {
1866            return "vertex_program";
1867        }
1868        else
1869        {
1870            return "fragment_program";
1871        }
1872    }
1873    void GpuProgram::CmdType::doSet(void* target, const String& val)
1874    {
1875        GpuProgram* t = static_cast<GpuProgram*>(target);
1876        if (val == "vertex_program")
1877        {
1878            t->setType(GPT_VERTEX_PROGRAM);
1879        }
1880        else
1881        {
1882            t->setType(GPT_FRAGMENT_PROGRAM);
1883        }
1884    }
1885    //-----------------------------------------------------------------------
1886    String GpuProgram::CmdSyntax::doGet(const void* target) const
1887    {
1888        const GpuProgram* t = static_cast<const GpuProgram*>(target);
1889        return t->getSyntaxCode();
1890    }
1891    void GpuProgram::CmdSyntax::doSet(void* target, const String& val)
1892    {
1893        GpuProgram* t = static_cast<GpuProgram*>(target);
1894        t->setSyntaxCode(val);
1895    }
1896    //-----------------------------------------------------------------------
1897    String GpuProgram::CmdSkeletal::doGet(const void* target) const
1898    {
1899        const GpuProgram* t = static_cast<const GpuProgram*>(target);
1900        return StringConverter::toString(t->isSkeletalAnimationIncluded());
1901    }
1902    void GpuProgram::CmdSkeletal::doSet(void* target, const String& val)
1903    {
1904        GpuProgram* t = static_cast<GpuProgram*>(target);
1905        t->setSkeletalAnimationIncluded(StringConverter::parseBool(val));
1906    }
1907        //-----------------------------------------------------------------------
1908        String GpuProgram::CmdMorph::doGet(const void* target) const
1909        {
1910                const GpuProgram* t = static_cast<const GpuProgram*>(target);
1911                return StringConverter::toString(t->isMorphAnimationIncluded());
1912        }
1913        void GpuProgram::CmdMorph::doSet(void* target, const String& val)
1914        {
1915                GpuProgram* t = static_cast<GpuProgram*>(target);
1916                t->setMorphAnimationIncluded(StringConverter::parseBool(val));
1917        }
1918        //-----------------------------------------------------------------------
1919        String GpuProgram::CmdPose::doGet(const void* target) const
1920        {
1921                const GpuProgram* t = static_cast<const GpuProgram*>(target);
1922                return StringConverter::toString(t->getNumberOfPosesIncluded());
1923        }
1924        void GpuProgram::CmdPose::doSet(void* target, const String& val)
1925        {
1926                GpuProgram* t = static_cast<GpuProgram*>(target);
1927                t->setPoseAnimationIncluded(StringConverter::parseUnsignedInt(val));
1928        }
1929        //-----------------------------------------------------------------------
1930        String GpuProgram::CmdVTF::doGet(const void* target) const
1931        {
1932                const GpuProgram* t = static_cast<const GpuProgram*>(target);
1933                return StringConverter::toString(t->isVertexTextureFetchRequired());
1934        }
1935        void GpuProgram::CmdVTF::doSet(void* target, const String& val)
1936        {
1937                GpuProgram* t = static_cast<GpuProgram*>(target);
1938                t->setVertexTextureFetchRequired(StringConverter::parseBool(val));
1939        }
1940    //-----------------------------------------------------------------------
1941    GpuProgramPtr& GpuProgramPtr::operator=(const HighLevelGpuProgramPtr& r)
1942    {
1943        // Can assign direct
1944        if (pRep == r.getPointer())
1945            return *this;
1946        release();
1947                // lock & copy other mutex pointer
1948        OGRE_MUTEX_CONDITIONAL(r.OGRE_AUTO_MUTEX_NAME)
1949        {
1950                    OGRE_LOCK_MUTEX(*r.OGRE_AUTO_MUTEX_NAME)
1951                    OGRE_COPY_AUTO_SHARED_MUTEX(r.OGRE_AUTO_MUTEX_NAME)
1952            pRep = r.getPointer();
1953            pUseCount = r.useCountPointer();
1954            if (pUseCount)
1955            {
1956                ++(*pUseCount);
1957            }
1958        }
1959                else
1960                {
1961                        // RHS must be a null pointer
1962                        assert(r.isNull() && "RHS must be null if it has no mutex!");
1963                        setNull();
1964                }
1965        return *this;
1966    }
1967
1968}
Note: See TracBrowser for help on using the repository browser.