source: OGRE/trunk/ogrenew/OgreMain/src/OgreTexture.cpp @ 692

Revision 692, 10.8 KB checked in by mattausch, 18 years ago (diff)

adding ogre 1.2 and dependencies

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-2005 The OGRE Team
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-----------------------------------------------------------------------------
24*/
25#include "OgreStableHeaders.h"
26#include "OgreLogManager.h"
27#include "OgreHardwarePixelBuffer.h"
28#include "OgreImage.h"
29#include "OgreTexture.h"
30#include "OgreException.h"
31#include "OgreResourceManager.h"
32
33namespace Ogre {
34        //--------------------------------------------------------------------------
35    Texture::Texture(ResourceManager* creator, const String& name,
36        ResourceHandle handle, const String& group, bool isManual,
37        ManualResourceLoader* loader)
38        : Resource(creator, name, handle, group, isManual, loader),
39            // init defaults; can be overridden before load()
40            mHeight(512),
41            mWidth(512),
42            mDepth(1),
43                        mNumRequestedMipmaps(0),
44            mNumMipmaps(0),
45                        mMipmapsHardwareGenerated(false),
46            mGamma(1.0f),
47            mTextureType(TEX_TYPE_2D),           
48            mFormat(PF_A8R8G8B8),
49            mUsage(TU_DEFAULT),
50            // mSrcBpp inited later on
51            mSrcWidth(0),
52            mSrcHeight(0),
53            mSrcDepth(0), mInternalResourcesCreated(false),
54            // mFinalBpp inited later on by enable32bit
55            mHasAlpha(false)       
56    {
57
58        enable32Bit(false);
59
60        if (createParamDictionary("Texture"))
61        {
62            // Define the parameters that have to be present to load
63            // from a generic source; actually there are none, since when
64            // predeclaring, you use a texture file which includes all the
65            // information required.
66        }
67
68       
69    }
70        //--------------------------------------------------------------------------    //--------------------------------------------------------------------------
71        void Texture::loadRawData( DataStreamPtr& stream,
72                ushort uWidth, ushort uHeight, PixelFormat eFormat)
73        {
74                Image img;
75                img.loadRawData(stream, uWidth, uHeight, eFormat);
76                loadImage(img);
77        }
78    //--------------------------------------------------------------------------
79    void Texture::setFormat(PixelFormat pf)
80    {
81        mFormat = pf;
82        // This should probably change with new texture access methods, but
83        // no changes made for now
84        mSrcBpp = PixelUtil::getNumElemBytes(mFormat);
85        mHasAlpha = PixelUtil::getFlags(mFormat) & PFF_HASALPHA;
86    }
87    //--------------------------------------------------------------------------
88        size_t Texture::calculateSize(void) const
89        {
90        return getNumFaces() * PixelUtil::getMemorySize(mWidth, mHeight, mDepth, mFormat);
91        }
92        //--------------------------------------------------------------------------
93        size_t Texture::getNumFaces(void) const
94        {
95                return getTextureType() == TEX_TYPE_CUBE_MAP ? 6 : 1;
96        }
97        //--------------------------------------------------------------------------
98    void Texture::_loadImages( const std::vector<const Image*>& images )
99    {
100                if(images.size() < 1)
101                        OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Cannot load empty vector of images",
102                         "Texture::loadImages");
103       
104        if( mIsLoaded )
105        {
106                        LogManager::getSingleton().logMessage(
107                                LML_NORMAL, "Texture: "+mName+": Unloading Image");
108            unload();
109        }
110
111                // Set desired texture size and properties from images[0]
112                mSrcWidth = mWidth = images[0]->getWidth();
113                mSrcHeight = mHeight = images[0]->getHeight();
114                mSrcDepth = mDepth = images[0]->getDepth();
115        if (mHasAlpha && images[0]->getFormat() == PF_L8)
116        {
117            mFormat = PF_A8;
118            mSrcBpp = 8;
119        }
120        else
121        {
122            mFormat = images[0]->getFormat();
123            mSrcBpp = PixelUtil::getNumElemBits(mFormat);
124            mHasAlpha = PixelUtil::hasAlpha(mFormat);
125        }
126
127                if (mFinalBpp == 16)
128                {
129                        // Drop down texture internal format
130                        switch (mFormat)
131                        {
132                        case PF_R8G8B8:
133                        case PF_X8R8G8B8:
134                                mFormat = PF_R5G6B5;
135                                break;
136                       
137                        case PF_B8G8R8:
138                        case PF_X8B8G8R8:
139                                mFormat = PF_B5G6R5;
140                                break;
141                               
142                        case PF_A8R8G8B8:
143                        case PF_R8G8B8A8:
144                        case PF_A8B8G8R8:
145                        case PF_B8G8R8A8:
146                                mFormat = PF_A4R4G4B4;
147                                break;
148                        }
149                }
150               
151                // The custom mipmaps in the image have priority over everything
152        size_t imageMips = images[0]->getNumMipmaps();
153
154                if(imageMips > 0) {
155                        mNumMipmaps = images[0]->getNumMipmaps();
156                        // Disable flag for auto mip generation
157                        mUsage &= ~TU_AUTOMIPMAP;
158                }
159               
160        // Create the texture
161        createInternalResources();
162                // Check if we're loading one image with multiple faces
163                // or a vector of images representing the faces
164                size_t faces;
165                bool multiImage; // Load from multiple images?
166                if(images.size() > 1)
167                {
168                        faces = images.size();
169                        multiImage = true;
170                }
171                else
172                {
173                        faces = images[0]->getNumFaces();
174                        multiImage = false;
175                }
176               
177                // Check wether number of faces in images exceeds number of faces
178                // in this texture. If so, clamp it.
179                if(faces > getNumFaces())
180                        faces = getNumFaces();
181               
182                // Say what we're doing
183                StringUtil::StrStreamType str;
184                str << "Texture: " << mName << ": Loading " << faces << " faces"
185                        << "(" << PixelUtil::getFormatName(images[0]->getFormat()) << "," <<
186                        images[0]->getWidth() << "x" << images[0]->getHeight() << "x" << images[0]->getDepth() <<
187                        ") with ";
188                if (!(mMipmapsHardwareGenerated && mNumMipmaps == 0))
189                        str << mNumMipmaps;
190                if(mUsage & TU_AUTOMIPMAP)
191                {
192                        if (mMipmapsHardwareGenerated)
193                                str << " hardware";
194
195                        str << " generated mipmaps";
196                }
197                else
198                {
199                        str << " custom mipmaps";
200                }
201                if(multiImage)
202                        str << " from multiple Images.";
203                else
204                        str << " from Image.";
205                // Scoped
206                {
207                        // Print data about first destination surface
208                        HardwarePixelBufferSharedPtr buf = getBuffer(0, 0);
209                        str << " Internal format is " << PixelUtil::getFormatName(buf->getFormat()) <<
210                        "," << buf->getWidth() << "x" << buf->getHeight() << "x" << buf->getDepth() << ".";
211                }
212                LogManager::getSingleton().logMessage(
213                                LML_NORMAL, str.str());
214               
215                // Main loading loop
216        // imageMips == 0 if the image has no custom mipmaps, otherwise contains the number of custom mips
217        for(size_t mip = 0; mip<=imageMips; ++mip)
218        {
219            for(size_t i = 0; i < faces; ++i)
220            {
221                PixelBox src;
222                if(multiImage)
223                {
224                    // Load from multiple images
225                    src = images[i]->getPixelBox(0, mip);
226                }
227                else
228                {
229                    // Load from faces of images[0]
230                    src = images[0]->getPixelBox(i, mip);
231
232                    if (mHasAlpha && src.format == PF_L8)
233                        src.format = PF_A8;
234                }
235   
236                if(mGamma != 1.0f) {
237                    // Apply gamma correction
238                    // Do not overwrite original image but do gamma correction in temporary buffer
239                    MemoryDataStreamPtr buf; // for scoped deletion of conversion buffer
240                    buf.bind(new MemoryDataStream(
241                        PixelUtil::getMemorySize(
242                            src.getWidth(), src.getHeight(), src.getDepth(), src.format)));
243                   
244                    PixelBox corrected = PixelBox(src.getWidth(), src.getHeight(), src.getDepth(), src.format, buf->getPtr());
245                    PixelUtil::bulkPixelConversion(src, corrected);
246                   
247                    Image::applyGamma(static_cast<uint8*>(corrected.data), mGamma, corrected.getConsecutiveSize(),
248                        PixelUtil::getNumElemBits(src.format));
249   
250                    // Destination: entire texture. blitFromMemory does the scaling to
251                    // a power of two for us when needed
252                    getBuffer(i, mip)->blitFromMemory(corrected);
253                }
254                else
255                {
256                    // Destination: entire texture. blitFromMemory does the scaling to
257                    // a power of two for us when needed
258                    getBuffer(i, mip)->blitFromMemory(src);
259                }
260               
261            }
262        }
263        // Update size (the final size, not including temp space)
264        mSize = getNumFaces() * PixelUtil::getMemorySize(mWidth, mHeight, mDepth, mFormat);
265
266        mIsLoaded = true;
267    }
268        //-----------------------------------------------------------------------------
269        void Texture::createInternalResources(void)
270        {
271                if (!mInternalResourcesCreated)
272                {
273                        createInternalResourcesImpl();
274                        mInternalResourcesCreated = true;
275                }
276        }
277        //-----------------------------------------------------------------------------
278        void Texture::freeInternalResources(void)
279        {
280                if (mInternalResourcesCreated)
281                {
282                        freeInternalResourcesImpl();
283                        mInternalResourcesCreated = false;
284                }
285        }
286        //-----------------------------------------------------------------------------
287        void Texture::unloadImpl(void)
288        {
289                freeInternalResources();
290        }
291    //-----------------------------------------------------------------------------   
292    void Texture::copyToTexture( TexturePtr& target )
293    {
294        if(target->getNumFaces() != getNumFaces())
295        {
296            OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
297                "Texture types must match",
298                "Texture::copyToTexture");
299        }
300        size_t numMips = std::min(getNumMipmaps(), target->getNumMipmaps());
301        if((mUsage & TU_AUTOMIPMAP) || (target->getUsage()&TU_AUTOMIPMAP))
302            numMips = 0;
303        for(int face=0; face<getNumFaces(); face++)
304        {
305            for(int mip=0; mip<=numMips; mip++)
306            {
307                target->getBuffer(face, mip)->blit(getBuffer(face, mip));
308            }
309        }
310    }
311
312
313}
Note: See TracBrowser for help on using the repository browser.