Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/OgreMain/src/OgreTexture.cpp @ 1

Last change on this file since 1 was 1, checked in by landauf, 17 years ago
File size: 13.4 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 "OgreLogManager.h"
31#include "OgreHardwarePixelBuffer.h"
32#include "OgreImage.h"
33#include "OgreTexture.h"
34#include "OgreException.h"
35#include "OgreResourceManager.h"
36#include "OgreTextureManager.h"
37
38namespace Ogre {
39        //--------------------------------------------------------------------------
40    Texture::Texture(ResourceManager* creator, const String& name, 
41        ResourceHandle handle, const String& group, bool isManual, 
42        ManualResourceLoader* loader)
43        : Resource(creator, name, handle, group, isManual, loader),
44            // init defaults; can be overridden before load()
45            mHeight(512),
46            mWidth(512),
47            mDepth(1),
48                        mNumRequestedMipmaps(0),
49            mNumMipmaps(0),
50                        mMipmapsHardwareGenerated(false),
51            mGamma(1.0f),
52            mTextureType(TEX_TYPE_2D),           
53            mFormat(PF_UNKNOWN),
54            mUsage(TU_DEFAULT),
55            mSrcFormat(PF_UNKNOWN),
56            mSrcWidth(0),
57            mSrcHeight(0), 
58            mSrcDepth(0),
59            mDesiredFormat(PF_UNKNOWN),
60            mDesiredIntegerBitDepth(0),
61            mDesiredFloatBitDepth(0),
62            mTreatLuminanceAsAlpha(false),
63            mInternalResourcesCreated(false)
64    {
65        if (createParamDictionary("Texture"))
66        {
67            // Define the parameters that have to be present to load
68            // from a generic source; actually there are none, since when
69            // predeclaring, you use a texture file which includes all the
70            // information required.
71        }
72
73                // Set some defaults for default load path
74                if (TextureManager::getSingletonPtr())
75                {
76                        TextureManager& tmgr = TextureManager::getSingleton();
77                        setNumMipmaps(tmgr.getDefaultNumMipmaps());
78                        setDesiredBitDepths(tmgr.getPreferredIntegerBitDepth(), tmgr.getPreferredFloatBitDepth());
79                }
80
81       
82    }
83        //--------------------------------------------------------------------------
84        void Texture::loadRawData( DataStreamPtr& stream, 
85                ushort uWidth, ushort uHeight, PixelFormat eFormat)
86        {
87                Image img;
88                img.loadRawData(stream, uWidth, uHeight, eFormat);
89                loadImage(img);
90        }
91        //--------------------------------------------------------------------------   
92        void Texture::loadImage( const Image &img )
93        {
94                // Scope lock over load status
95                {
96                        OGRE_LOCK_MUTEX(mLoadingStatusMutex)
97                        if (mLoadingState != LOADSTATE_UNLOADED)
98                        {
99                                // no loading to be done
100                                return;
101                        }
102                        mLoadingState = LOADSTATE_LOADING;
103                }
104
105                // Scope lock for actual loading
106                try
107                {
108                        OGRE_LOCK_AUTO_MUTEX
109                        std::vector<const Image*> imagePtrs;
110                        imagePtrs.push_back(&img);
111                        _loadImages( imagePtrs );
112
113                }
114                catch (...)
115                {
116                        // Reset loading in-progress flag in case failed for some reason
117                        OGRE_LOCK_MUTEX(mLoadingStatusMutex)
118                        mLoadingState = LOADSTATE_UNLOADED;
119                        // Re-throw
120                        throw;
121                }
122
123                // Scope lock for loading progress
124                {
125                        OGRE_LOCK_MUTEX(mLoadingStatusMutex)
126
127                        // Now loaded
128                        mLoadingState = LOADSTATE_LOADED;
129                }
130
131                // Notify manager
132                if(mCreator)
133                        mCreator->_notifyResourceLoaded(this);
134
135                // No deferred loading events since this method is not called in background
136
137
138        }
139    //--------------------------------------------------------------------------
140    void Texture::setFormat(PixelFormat pf)
141    {
142        mFormat = pf;
143        mDesiredFormat = pf;
144        mSrcFormat = pf;
145    }
146    //--------------------------------------------------------------------------
147    bool Texture::hasAlpha(void) const
148    {
149        return PixelUtil::hasAlpha(mFormat);
150    }
151    //--------------------------------------------------------------------------
152    void Texture::setDesiredIntegerBitDepth(ushort bits)
153    {
154        mDesiredIntegerBitDepth = bits;
155    }
156    //--------------------------------------------------------------------------
157    ushort Texture::getDesiredIntegerBitDepth(void) const
158    {
159        return mDesiredIntegerBitDepth;
160    }
161    //--------------------------------------------------------------------------
162    void Texture::setDesiredFloatBitDepth(ushort bits)
163    {
164        mDesiredFloatBitDepth = bits;
165    }
166    //--------------------------------------------------------------------------
167    ushort Texture::getDesiredFloatBitDepth(void) const
168    {
169        return mDesiredFloatBitDepth;
170    }
171    //--------------------------------------------------------------------------
172    void Texture::setDesiredBitDepths(ushort integerBits, ushort floatBits)
173    {
174        mDesiredIntegerBitDepth = integerBits;
175        mDesiredFloatBitDepth = floatBits;
176    }
177    //--------------------------------------------------------------------------
178    void Texture::setTreatLuminanceAsAlpha(bool asAlpha)
179    {
180        mTreatLuminanceAsAlpha = asAlpha;
181    }
182    //--------------------------------------------------------------------------
183    bool Texture::getTreatLuminanceAsAlpha(void) const
184    {
185        return mTreatLuminanceAsAlpha;
186    }
187    //--------------------------------------------------------------------------
188        size_t Texture::calculateSize(void) const
189        {
190        return getNumFaces() * PixelUtil::getMemorySize(mWidth, mHeight, mDepth, mFormat);
191        }
192        //--------------------------------------------------------------------------
193        size_t Texture::getNumFaces(void) const
194        {
195                return getTextureType() == TEX_TYPE_CUBE_MAP ? 6 : 1;
196        }
197        //--------------------------------------------------------------------------
198    void Texture::_loadImages( const ConstImagePtrList& images )
199    {
200                if(images.size() < 1)
201                        OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Cannot load empty vector of images",
202                         "Texture::loadImages");
203       
204                // Set desired texture size and properties from images[0]
205                mSrcWidth = mWidth = images[0]->getWidth();
206                mSrcHeight = mHeight = images[0]->getHeight();
207                mSrcDepth = mDepth = images[0]->getDepth();
208
209        // Get source image format and adjust if required
210        mSrcFormat = images[0]->getFormat();
211        if (mTreatLuminanceAsAlpha && mSrcFormat == PF_L8)
212        {
213            mSrcFormat = PF_A8;
214        }
215
216        if (mDesiredFormat != PF_UNKNOWN)
217        {
218            // If have desired format, use it
219            mFormat = mDesiredFormat;
220        }
221        else
222        {
223            // Get the format according with desired bit depth
224            mFormat = PixelUtil::getFormatForBitDepths(mSrcFormat, mDesiredIntegerBitDepth, mDesiredFloatBitDepth);
225        }
226
227                // The custom mipmaps in the image have priority over everything
228        size_t imageMips = images[0]->getNumMipmaps();
229
230                if(imageMips > 0) {
231                        mNumMipmaps = mNumRequestedMipmaps = images[0]->getNumMipmaps();
232                        // Disable flag for auto mip generation
233                        mUsage &= ~TU_AUTOMIPMAP;
234                }
235               
236        // Create the texture
237        createInternalResources();
238                // Check if we're loading one image with multiple faces
239                // or a vector of images representing the faces
240                size_t faces;
241                bool multiImage; // Load from multiple images?
242                if(images.size() > 1)
243                {
244                        faces = images.size();
245                        multiImage = true;
246                }
247                else
248                {
249                        faces = images[0]->getNumFaces();
250                        multiImage = false;
251                }
252               
253                // Check wether number of faces in images exceeds number of faces
254                // in this texture. If so, clamp it.
255                if(faces > getNumFaces())
256                        faces = getNumFaces();
257               
258                // Say what we're doing
259                StringUtil::StrStreamType str;
260                str << "Texture: " << mName << ": Loading " << faces << " faces"
261                        << "(" << PixelUtil::getFormatName(images[0]->getFormat()) << "," <<
262                        images[0]->getWidth() << "x" << images[0]->getHeight() << "x" << images[0]->getDepth() <<
263                        ") with ";
264                if (!(mMipmapsHardwareGenerated && mNumMipmaps == 0))
265                        str << mNumMipmaps;
266                if(mUsage & TU_AUTOMIPMAP)
267                {
268                        if (mMipmapsHardwareGenerated)
269                                str << " hardware";
270
271                        str << " generated mipmaps";
272                }
273                else
274                {
275                        str << " custom mipmaps";
276                }
277                if(multiImage)
278                        str << " from multiple Images.";
279                else
280                        str << " from Image.";
281                // Scoped
282                {
283                        // Print data about first destination surface
284                        HardwarePixelBufferSharedPtr buf = getBuffer(0, 0); 
285                        str << " Internal format is " << PixelUtil::getFormatName(buf->getFormat()) << 
286                        "," << buf->getWidth() << "x" << buf->getHeight() << "x" << buf->getDepth() << ".";
287                }
288                LogManager::getSingleton().logMessage( 
289                                LML_NORMAL, str.str());
290               
291                // Main loading loop
292        // imageMips == 0 if the image has no custom mipmaps, otherwise contains the number of custom mips
293        for(size_t mip = 0; mip<=imageMips; ++mip)
294        {
295            for(size_t i = 0; i < faces; ++i)
296            {
297                PixelBox src;
298                if(multiImage)
299                {
300                    // Load from multiple images
301                    src = images[i]->getPixelBox(0, mip);
302                }
303                else
304                {
305                    // Load from faces of images[0]
306                    src = images[0]->getPixelBox(i, mip);
307                }
308   
309                // Sets to treated format in case is difference
310                src.format = mSrcFormat;
311
312                if(mGamma != 1.0f) {
313                    // Apply gamma correction
314                    // Do not overwrite original image but do gamma correction in temporary buffer
315                    MemoryDataStreamPtr buf; // for scoped deletion of conversion buffer
316                    buf.bind(new MemoryDataStream(
317                        PixelUtil::getMemorySize(
318                            src.getWidth(), src.getHeight(), src.getDepth(), src.format)));
319                   
320                    PixelBox corrected = PixelBox(src.getWidth(), src.getHeight(), src.getDepth(), src.format, buf->getPtr());
321                    PixelUtil::bulkPixelConversion(src, corrected);
322                   
323                    Image::applyGamma(static_cast<uint8*>(corrected.data), mGamma, corrected.getConsecutiveSize(), 
324                        static_cast<uchar>(PixelUtil::getNumElemBits(src.format)));
325   
326                    // Destination: entire texture. blitFromMemory does the scaling to
327                    // a power of two for us when needed
328                    getBuffer(i, mip)->blitFromMemory(corrected);
329                }
330                else 
331                {
332                    // Destination: entire texture. blitFromMemory does the scaling to
333                    // a power of two for us when needed
334                    getBuffer(i, mip)->blitFromMemory(src);
335                }
336               
337            }
338        }
339        // Update size (the final size, not including temp space)
340        mSize = getNumFaces() * PixelUtil::getMemorySize(mWidth, mHeight, mDepth, mFormat);
341
342    }
343        //-----------------------------------------------------------------------------
344        void Texture::createInternalResources(void)
345        {
346                if (!mInternalResourcesCreated)
347                {
348                        createInternalResourcesImpl();
349                        mInternalResourcesCreated = true;
350                }
351        }
352        //-----------------------------------------------------------------------------
353        void Texture::freeInternalResources(void)
354        {
355                if (mInternalResourcesCreated)
356                {
357                        freeInternalResourcesImpl();
358                        mInternalResourcesCreated = false;
359                }
360        }
361        //-----------------------------------------------------------------------------
362        void Texture::unloadImpl(void)
363        {
364                freeInternalResources();
365        }
366    //-----------------------------------------------------------------------------   
367    void Texture::copyToTexture( TexturePtr& target )
368    {
369        if(target->getNumFaces() != getNumFaces())
370        {
371            OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, 
372                "Texture types must match",
373                "Texture::copyToTexture");
374        }
375        size_t numMips = std::min(getNumMipmaps(), target->getNumMipmaps());
376        if((mUsage & TU_AUTOMIPMAP) || (target->getUsage()&TU_AUTOMIPMAP))
377            numMips = 0;
378        for(unsigned int face=0; face<getNumFaces(); face++)
379        {
380            for(unsigned int mip=0; mip<=numMips; mip++)
381            {
382                target->getBuffer(face, mip)->blit(getBuffer(face, mip));
383            }
384        }
385    }
386
387
388}
Note: See TracBrowser for help on using the repository browser.