Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/OgreMain/src/OgreILUtil.cpp @ 6

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

=hoffentlich gehts jetzt

File size: 11.6 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 "OgreILUtil.h"
31#include <OgrePixelFormat.h>
32#include <OgreBitwise.h>
33#include <OgreColourValue.h>
34#include <OgreException.h>
35
36#include <IL/il.h>
37#include <IL/ilu.h>
38   
39namespace Ogre {
40       
41        /*************************************************************************
42    * IL specific functions
43    */
44    PixelFormat ILUtil::ilFormat2OgreFormat( int ImageFormat, int ImageType ) 
45        {
46        PixelFormat fmt = PF_UNKNOWN;
47        switch( ImageFormat )
48        {
49                /* Compressed formats -- ignore type */
50                case IL_DXT1:   fmt = PF_DXT1; break;
51                case IL_DXT2:   fmt = PF_DXT2; break;
52                case IL_DXT3:   fmt = PF_DXT3; break;
53                case IL_DXT4:   fmt = PF_DXT4; break;
54                case IL_DXT5:   fmt = PF_DXT5; break;
55                /* Normal formats */
56        case IL_RGB:
57                        switch(ImageType)
58            {
59                        case IL_FLOAT:  fmt = PF_FLOAT32_RGB; break;
60                        case IL_UNSIGNED_SHORT: 
61                        case IL_SHORT:  fmt = PF_SHORT_RGBA; break;
62                        default:        fmt = PF_BYTE_RGB; break;
63                        }
64            break;
65        case IL_BGR:
66                        switch(ImageType)
67            {
68                        case IL_FLOAT:  fmt = PF_FLOAT32_RGB; break;
69                        case IL_UNSIGNED_SHORT: 
70                        case IL_SHORT:  fmt = PF_SHORT_RGBA; break;
71                        default:        fmt = PF_BYTE_BGR; break;
72                        }
73            break;           
74        case IL_RGBA:
75                        switch(ImageType)
76            {
77                        case IL_FLOAT:  fmt = PF_FLOAT32_RGBA; break;
78                        case IL_UNSIGNED_SHORT: 
79                        case IL_SHORT:  fmt = PF_SHORT_RGBA; break;
80                        default:        fmt = PF_BYTE_RGBA; break;
81                        }
82            break;
83        case IL_BGRA:
84                        switch(ImageType)
85            {
86                        case IL_FLOAT:  fmt = PF_FLOAT32_RGBA; break;
87                        case IL_UNSIGNED_SHORT: 
88                        case IL_SHORT:  fmt = PF_SHORT_RGBA; break;
89                        default:        fmt = PF_BYTE_BGRA; break;
90                        }
91            break;
92        case IL_LUMINANCE:
93            switch(ImageType)
94            {
95            case IL_BYTE:
96            case IL_UNSIGNED_BYTE:
97                fmt = PF_L8;
98                break;
99            default:
100                fmt = PF_L16;
101            }
102            break;           
103        case IL_LUMINANCE_ALPHA:
104                        fmt = PF_BYTE_LA;
105            break;
106        } 
107        return fmt;
108    }
109
110    //-----------------------------------------------------------------------
111
112    ILUtil::ILFormat ILUtil::OgreFormat2ilFormat( PixelFormat format )
113    {
114                switch(format) {
115            case PF_BYTE_L: return ILFormat(1, IL_LUMINANCE, IL_UNSIGNED_BYTE);
116                        case PF_BYTE_A: return ILFormat(1, IL_LUMINANCE, IL_UNSIGNED_BYTE);
117                        case PF_SHORT_L: return ILFormat(1, IL_LUMINANCE, IL_UNSIGNED_SHORT);
118                        case PF_BYTE_LA: return ILFormat(2, IL_LUMINANCE_ALPHA, IL_UNSIGNED_BYTE);
119                        case PF_BYTE_RGB: return ILFormat(3, IL_RGB, IL_UNSIGNED_BYTE);
120                        case PF_BYTE_RGBA: return ILFormat(4, IL_RGBA, IL_UNSIGNED_BYTE);
121            case PF_BYTE_BGR: return ILFormat(3, IL_BGR, IL_UNSIGNED_BYTE);
122            case PF_BYTE_BGRA: return ILFormat(4, IL_BGRA, IL_UNSIGNED_BYTE);
123                        case PF_SHORT_RGBA: return ILFormat(4, IL_RGBA, IL_UNSIGNED_SHORT);
124                        case PF_FLOAT32_RGB: return ILFormat(3, IL_RGB, IL_FLOAT);
125                        case PF_FLOAT32_RGBA: return ILFormat(4, IL_RGBA, IL_FLOAT);
126                        case PF_DXT1: return ILFormat(0, IL_DXT1);
127                        case PF_DXT2: return ILFormat(0, IL_DXT2);
128                        case PF_DXT3: return ILFormat(0, IL_DXT3);
129                        case PF_DXT4: return ILFormat(0, IL_DXT4);
130                        case PF_DXT5: return ILFormat(0, IL_DXT5);
131                        default: return ILFormat();
132                }
133        }
134
135    //-----------------------------------------------------------------------
136        /// Helper functions for DevIL to Ogre conversion
137        inline void packI(uint8 r, uint8 g, uint8 b, uint8 a, PixelFormat pf,  void* dest)
138        {
139                PixelUtil::packColour(r, g, b, a, pf, dest);
140        }
141        inline void packI(uint16 r, uint16 g, uint16 b, uint16 a, PixelFormat pf,  void* dest)
142        {
143                PixelUtil::packColour((float)r/65535.0f, (float)g/65535.0f, 
144                        (float)b/65535.0f, (float)a/65535.0f, pf, dest);
145        }
146        inline void packI(float r, float g, float b, float a, PixelFormat pf,  void* dest)
147        {
148                PixelUtil::packColour(r, g, b, a, pf, dest);
149        }
150    template <typename T> void ilToOgreInternal(uint8 *tar, PixelFormat ogrefmt, 
151        T r, T g, T b, T a)
152    {
153        const int ilfmt = ilGetInteger( IL_IMAGE_FORMAT );
154        T *src = (T*)ilGetData();
155        T *srcend = (T*)((uint8*)ilGetData() + ilGetInteger( IL_IMAGE_SIZE_OF_DATA ));
156        const size_t elemSize = PixelUtil::getNumElemBytes(ogrefmt);
157        while(src < srcend) {
158            switch(ilfmt) {
159                        case IL_RGB:
160                                r = src[0];     g = src[1];     b = src[2];
161                                src += 3;
162                                break;
163                        case IL_BGR:
164                                b = src[0];     g = src[1];     r = src[2];
165                                src += 3;
166                                break;
167                        case IL_LUMINANCE:
168                                r = src[0];     g = src[0];     b = src[0];
169                                src += 1;
170                                break;
171                        case IL_LUMINANCE_ALPHA:
172                                r = src[0];     g = src[0];     b = src[0];     a = src[1];
173                                src += 2;
174                                break;
175                        case IL_RGBA:
176                                r = src[0];     g = src[1];     b = src[2];     a = src[3];
177                                src += 4;
178                                break;
179                        case IL_BGRA:
180                                b = src[0];     g = src[1];     r = src[2];     a = src[3];
181                                src += 4;
182                                break;
183                        default:
184                                return;
185            }
186            packI(r, g, b, a, ogrefmt, tar);
187            tar += elemSize;
188        }
189
190    }   
191    //-----------------------------------------------------------------------
192        /// Utility function to convert IL data types to UNSIGNED_
193        ILenum ILabs(ILenum in) {
194                switch(in) {
195                case IL_INT: return IL_UNSIGNED_INT;
196                case IL_BYTE: return IL_UNSIGNED_BYTE;
197                case IL_SHORT: return IL_UNSIGNED_SHORT;
198                default: return in;
199                }
200        }
201    //-----------------------------------------------------------------------
202    void ILUtil::toOgre(const PixelBox &dst) 
203    {
204                if(!dst.isConsecutive())
205                        OGRE_EXCEPT( Exception::ERR_NOT_IMPLEMENTED,
206                "Destination must currently be consecutive",
207                "ILUtil::ilToOgre" ) ;
208                if(dst.getWidth() != static_cast<size_t>(ilGetInteger( IL_IMAGE_WIDTH )) ||
209                dst.getHeight() != static_cast<size_t>(ilGetInteger( IL_IMAGE_HEIGHT )) ||
210                dst.getDepth() != static_cast<size_t>(ilGetInteger( IL_IMAGE_DEPTH )))
211                        OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS,
212                "Destination dimensions must equal IL dimension",
213                "ILUtil::ilToOgre" ) ;
214       
215        int ilfmt = ilGetInteger( IL_IMAGE_FORMAT );
216        int iltp = ilGetInteger( IL_IMAGE_TYPE );
217
218                // Check if in-memory format just matches
219                // If yes, we can just copy it and save conversion
220                ILFormat ifmt = OgreFormat2ilFormat( dst.format );
221                if(ifmt.format == ilfmt && ILabs(ifmt.type) == ILabs(iltp)) {
222            memcpy(dst.data, ilGetData(), ilGetInteger( IL_IMAGE_SIZE_OF_DATA )); 
223            return;
224        }
225                // Try if buffer is in a known OGRE format so we can use OGRE its
226                // conversion routines
227                PixelFormat bufFmt = ilFormat2OgreFormat((int)ilfmt, (int)iltp);
228               
229                ifmt = OgreFormat2ilFormat( bufFmt );
230                if(ifmt.format == ilfmt && ILabs(ifmt.type) == ILabs(iltp))
231                {
232                        // IL format matches another OGRE format
233                        PixelBox src(dst.getWidth(), dst.getHeight(), dst.getDepth(), bufFmt, ilGetData());
234                        PixelUtil::bulkPixelConversion(src, dst);
235                        return;
236                }
237               
238        // Thee extremely slow method
239        if(iltp == IL_UNSIGNED_BYTE || iltp == IL_BYTE) 
240        {
241            ilToOgreInternal(static_cast<uint8*>(dst.data), dst.format, (uint8)0x00,(uint8)0x00,(uint8)0x00,(uint8)0xFF);
242        } 
243        else if(iltp == IL_FLOAT)
244        {
245            ilToOgreInternal(static_cast<uint8*>(dst.data), dst.format, 0.0f,0.0f,0.0f,1.0f);         
246        }
247                else if(iltp == IL_SHORT || iltp == IL_UNSIGNED_SHORT)
248        {
249                        ilToOgreInternal(static_cast<uint8*>(dst.data), dst.format, 
250                                (uint16)0x0000,(uint16)0x0000,(uint16)0x0000,(uint16)0xFFFF); 
251        }
252        else 
253        {
254            OGRE_EXCEPT( Exception::ERR_NOT_IMPLEMENTED,
255                "Cannot convert this DevIL type",
256                "ILUtil::ilToOgre" ) ;
257        }
258    }
259    //-----------------------------------------------------------------------
260    void ILUtil::fromOgre(const PixelBox &src)
261    {
262                // ilTexImage http://openil.sourceforge.net/docs/il/f00059.htm
263                ILFormat ifmt = OgreFormat2ilFormat( src.format );
264                if(src.isConsecutive() && ifmt.isValid()) 
265                {
266                        // The easy case, the buffer is laid out in memory just like
267                        // we want it to be and is in a format DevIL can understand directly
268                        // We could even save the copy if DevIL would let us
269                        ilTexImage(static_cast<ILuint>(src.getWidth()), 
270                                static_cast<ILuint>(src.getHeight()), 
271                                static_cast<ILuint>(src.getDepth()), ifmt.numberOfChannels,
272                                ifmt.format, ifmt.type, src.data);
273                } 
274                else if(ifmt.isValid()) 
275                {
276                        // The format can be understood directly by DevIL. The only
277                        // problem is that ilTexImage expects our image data consecutively
278                        // so we cannot use that directly.
279                       
280                        // Let DevIL allocate the memory for us, and copy the data consecutively
281                        // to its memory
282                        ilTexImage(static_cast<ILuint>(src.getWidth()), 
283                                static_cast<ILuint>(src.getHeight()), 
284                                static_cast<ILuint>(src.getDepth()), ifmt.numberOfChannels,
285                                ifmt.format, ifmt.type, 0);
286                        PixelBox dst(src.getWidth(), src.getHeight(), src.getDepth(), src.format, ilGetData());
287                        PixelUtil::bulkPixelConversion(src, dst);
288                } 
289                else 
290                {
291                        // Here it gets ugly. We're stuck with a pixel format that DevIL
292                        // can't do anything with. We will do a bulk pixel conversion and
293                        // then feed it to DevIL anyway. The problem is finding the best
294                        // format to convert to.
295                       
296                        // most general format supported by OGRE and DevIL
297                        PixelFormat fmt = PixelUtil::hasAlpha(src.format)?PF_FLOAT32_RGBA:PF_FLOAT32_RGB; 
298
299                        // Make up a pixel format
300                        // We don't have to consider luminance formats as they have
301                        // straight conversions to DevIL, just weird permutations of RGBA an LA
302                        int depths[4];
303                        PixelUtil::getBitDepths(src.format, depths);
304                       
305                        // Native endian format with all bit depths<8 can safely and quickly be
306                        // converted to 24/32 bit
307                        if(PixelUtil::isNativeEndian(src.format) && 
308                                depths[0]<=8 && depths[1]<=8 && depths[2]<=8 && depths[3]<=8) {
309                                if(PixelUtil::hasAlpha(src.format)) {
310                                        fmt = PF_A8R8G8B8;
311                                } else {
312                                        fmt = PF_R8G8B8;
313                                }
314                        }
315                       
316                        // Let DevIL allocate the memory for us, then do the conversion ourselves
317                        ifmt = OgreFormat2ilFormat( fmt );
318                        ilTexImage(static_cast<ILuint>(src.getWidth()), 
319                                static_cast<ILuint>(src.getHeight()), 
320                                static_cast<ILuint>(src.getDepth()), ifmt.numberOfChannels,
321                                ifmt.format, ifmt.type, 0);
322                        PixelBox dst(src.getWidth(), src.getHeight(), src.getDepth(), fmt, ilGetData());
323                        PixelUtil::bulkPixelConversion(src, dst);
324                }
325    }
326
327}
Note: See TracBrowser for help on using the repository browser.