Torque3D Documentation / _generateds / gfxGLCubemap.cpp

gfxGLCubemap.cpp

Engine/source/gfx/gl/gfxGLCubemap.cpp

More...

Detailed Description

  1
  2//-----------------------------------------------------------------------------
  3// Copyright (c) 2012 GarageGames, LLC
  4//
  5// Permission is hereby granted, free of charge, to any person obtaining a copy
  6// of this software and associated documentation files (the "Software"), to
  7// deal in the Software without restriction, including without limitation the
  8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  9// sell copies of the Software, and to permit persons to whom the Software is
 10// furnished to do so, subject to the following conditions:
 11//
 12// The above copyright notice and this permission notice shall be included in
 13// all copies or substantial portions of the Software.
 14//
 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 21// IN THE SOFTWARE.
 22//-----------------------------------------------------------------------------
 23
 24#include "gfx/gl/gfxGLDevice.h"
 25#include "gfx/gl/gfxGLTextureObject.h"
 26#include "gfx/gl/gfxGLEnumTranslate.h"
 27#include "gfx/gl/gfxGLUtils.h"
 28#include "gfx/gl/gfxGLCubemap.h"
 29#include "gfx/gfxTextureManager.h"
 30#include "gfx/gfxCardProfile.h"
 31#include "gfx/bitmap/ddsFile.h"
 32#include "gfx/bitmap/imageUtils.h"
 33
 34
 35GFXGLCubemap::GFXGLCubemap() :
 36      mCubemap(0), 
 37      mDynamicTexSize(0),
 38      mWidth(0),
 39      mHeight(0),
 40      mFaceFormat( GFXFormatR8G8B8A8 )
 41{
 42   for(U32 i = 0; i < 6; i++)
 43      mTextures[i] = NULL;
 44   
 45   GFXTextureManager::addEventDelegate( this, &GFXGLCubemap::_onTextureEvent );
 46}
 47
 48GFXGLCubemap::~GFXGLCubemap()
 49{
 50   glDeleteTextures(1, &mCubemap);
 51   GFXTextureManager::removeEventDelegate( this, &GFXGLCubemap::_onTextureEvent );
 52}
 53
 54GLenum GFXGLCubemap::getEnumForFaceNumber(U32 face)
 55{ 
 56   return GFXGLFaceType[face];
 57}
 58
 59void GFXGLCubemap::fillCubeTextures(GFXTexHandle* faces)
 60{
 61   AssertFatal( faces, "");
 62   AssertFatal( faces[0]->mMipLevels > 0, "");
 63
 64   PRESERVE_CUBEMAP_TEXTURE();
 65   glBindTexture(GL_TEXTURE_CUBE_MAP, mCubemap);
 66   glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, faces[0]->mMipLevels - 1 );
 67   glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 68   glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 69   glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
 70   glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 71   glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
 72   
 73   U32 reqWidth = faces[0]->getWidth();
 74   U32 reqHeight = faces[0]->getHeight();
 75   GFXFormat regFaceFormat = faces[0]->getFormat();
 76   const bool isCompressed = ImageUtil::isCompressedFormat(regFaceFormat);
 77   mWidth = reqWidth;
 78   mHeight = reqHeight;
 79   mFaceFormat = regFaceFormat;
 80   mMipMapLevels = getMax( (U32)1, faces[0]->mMipLevels);
 81   AssertFatal(reqWidth == reqHeight, "GFXGLCubemap::fillCubeTextures - Width and height must be equal!");
 82   
 83   for(U32 i = 0; i < 6; i++)
 84   {
 85      AssertFatal(faces[i], avar("GFXGLCubemap::fillCubeFaces - texture %i is NULL!", i));
 86      AssertFatal((faces[i]->getWidth() == reqWidth) && (faces[i]->getHeight() == reqHeight), "GFXGLCubemap::fillCubeFaces - All textures must have identical dimensions!");
 87      AssertFatal(faces[i]->getFormat() == regFaceFormat, "GFXGLCubemap::fillCubeFaces - All textures must have identical formats!");
 88      
 89      mTextures[i] = faces[i];
 90      GFXFormat faceFormat = faces[i]->getFormat();
 91
 92        GFXGLTextureObject* glTex = static_cast<GFXGLTextureObject*>(faces[i].getPointer());
 93        if( isCompressed )
 94        {
 95            for( U32 mip = 0; mip < mMipMapLevels; ++mip )
 96            {
 97                const U32 mipWidth  = getMax( U32(1), faces[i]->getWidth() >> mip );
 98                const U32 mipHeight = getMax( U32(1), faces[i]->getHeight() >> mip );
 99                const U32 mipDataSize = getCompressedSurfaceSize( mFaceFormat, mWidth, mHeight, mip );
100
101                U8* buf = glTex->getTextureData( mip );
102                glCompressedTexImage2D(GFXGLFaceType[i], mip, GFXGLTextureInternalFormat[mFaceFormat], mipWidth, mipHeight, 0, mipDataSize, buf);
103                delete[] buf;
104            }
105        }
106        else
107        {
108            U8* buf = glTex->getTextureData();
109            glTexImage2D(GFXGLFaceType[i], 0, GFXGLTextureInternalFormat[faceFormat], mWidth, mHeight,
110                0, GFXGLTextureFormat[faceFormat], GFXGLTextureType[faceFormat], buf);
111            delete[] buf;
112        }
113   }
114   
115    if( !isCompressed )
116        glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
117}
118
119void GFXGLCubemap::initStatic(GFXTexHandle* faces)
120{
121   if(mCubemap)
122      return;
123      
124   if(faces)
125   {
126      AssertFatal(faces[0], "GFXGLCubemap::initStatic - empty texture passed");
127      glGenTextures(1, &mCubemap);
128      fillCubeTextures(faces);
129   }
130   mInitialized = true;
131}
132
133void GFXGLCubemap::initStatic( DDSFile *dds )
134{
135   if(mCubemap)
136      return;
137      
138   AssertFatal( dds, "GFXGLCubemap::initStatic - Got null DDS file!" );
139   AssertFatal( dds->isCubemap(), "GFXGLCubemap::initStatic - Got non-cubemap DDS file!" );
140   AssertFatal( dds->mSurfaces.size() == 6, "GFXGLCubemap::initStatic - DDS has less than 6 surfaces!" );
141
142   mWidth = dds->getWidth();
143   mHeight = dds->getHeight();
144   mFaceFormat = dds->getFormat();
145   mMipMapLevels = dds->getMipLevels();
146   const bool isCompressed = ImageUtil::isCompressedFormat(mFaceFormat);
147   glGenTextures(1, &mCubemap);
148
149   PRESERVE_CUBEMAP_TEXTURE();
150   glBindTexture(GL_TEXTURE_CUBE_MAP, mCubemap);
151   glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, mMipMapLevels - 1);
152   glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
153   glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
154   glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
155   glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
156   glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
157
158   AssertFatal(mWidth == mHeight, "GFXGLCubemap::initStatic - Width and height must be equal!");
159   
160   for(U32 i = 0; i < 6; i++)
161   {
162      if ( !dds->mSurfaces[i] )
163      {
164         // TODO: The DDS can skip surfaces, but i'm unsure what i should
165         // do here when creating the cubemap.  Ignore it for now.
166         continue;
167      }
168
169      // convert to Z up
170      const U32 faceIndex = zUpFaceIndex(i);
171
172      // Now loop thru the mip levels!
173      for (U32 mip = 0; mip < mMipMapLevels; ++mip)
174      {
175         const U32 mipWidth  = getMax( U32(1), mWidth >> mip );
176         const U32 mipHeight = getMax( U32(1), mHeight >> mip );
177         if (isCompressed)
178            glCompressedTexImage2D(GFXGLFaceType[faceIndex], mip, GFXGLTextureInternalFormat[mFaceFormat], mipWidth, mipHeight, 0, dds->getSurfaceSize(mip), dds->mSurfaces[i]->mMips[mip]);
179         else
180            glTexImage2D(GFXGLFaceType[faceIndex], mip, GFXGLTextureInternalFormat[mFaceFormat], mipWidth, mipHeight, 0,
181               GFXGLTextureFormat[mFaceFormat], GFXGLTextureType[mFaceFormat], dds->mSurfaces[i]->mMips[mip]);
182      }
183   }
184   mInitialized = true;
185}
186
187void GFXGLCubemap::initDynamic(U32 texSize, GFXFormat faceFormat, U32 mipLevels)
188{
189   mDynamicTexSize = texSize;
190   mFaceFormat = faceFormat;
191   const bool isCompressed = ImageUtil::isCompressedFormat(faceFormat);
192   mMipMapLevels = ImageUtil::getMaxMipCount( texSize, texSize);
193
194   glGenTextures(1, &mCubemap);
195   PRESERVE_CUBEMAP_TEXTURE();
196   glBindTexture(GL_TEXTURE_CUBE_MAP, mCubemap);
197   glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, mMipMapLevels - 1);
198   glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
199   glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
200   glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
201   glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
202   glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
203   mWidth = texSize;
204   mHeight = texSize;
205
206    for(U32 i = 0; i < 6; i++)
207    {
208        if( ImageUtil::isCompressedFormat(faceFormat) )
209        {
210            for( U32 mip = 0; mip < mMipMapLevels; ++mip )
211            {
212                const U32 mipSize = getMax( U32(1), texSize >> mip );
213                const U32 mipDataSize = getCompressedSurfaceSize( mFaceFormat, texSize, texSize, mip );
214                glCompressedTexImage2D(GFXGLFaceType[i], mip, GFXGLTextureInternalFormat[mFaceFormat], mipSize, mipSize, 0, mipDataSize, NULL);
215            }
216        }
217        else
218        {
219            glTexImage2D( GFXGLFaceType[i], 0, GFXGLTextureInternalFormat[faceFormat], texSize, texSize, 
220                0, GFXGLTextureFormat[faceFormat], GFXGLTextureType[faceFormat], NULL);
221        }
222    }
223
224    if( !isCompressed && !mipLevels)
225        glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
226    mInitialized = true;
227}
228
229void GFXGLCubemap::zombify()
230{
231   glDeleteTextures(1, &mCubemap);
232   mCubemap = 0;
233}
234
235void GFXGLCubemap::resurrect()
236{
237   // Handled in tmResurrect
238}
239
240void GFXGLCubemap::tmResurrect()
241{
242   if(mDynamicTexSize)
243      initDynamic(mDynamicTexSize,mFaceFormat);
244   else
245   {
246      if ( mDDSFile )
247         initStatic( mDDSFile );
248      else
249         initStatic( mTextures );
250   }
251}
252
253void GFXGLCubemap::setToTexUnit(U32 tuNum)
254{
255   static_cast<GFXGLDevice*>(getOwningDevice())->setCubemapInternal(tuNum, this);
256}
257
258void GFXGLCubemap::bind(U32 textureUnit) const
259{
260   glActiveTexture(GL_TEXTURE0 + textureUnit);
261   glBindTexture(GL_TEXTURE_CUBE_MAP, mCubemap);
262   static_cast<GFXGLDevice*>(getOwningDevice())->getOpenglCache()->setCacheBindedTex(textureUnit, GL_TEXTURE_CUBE_MAP, mCubemap);
263   
264   GFXGLStateBlockRef sb = static_cast<GFXGLDevice*>(GFX)->getCurrentStateBlock();
265   AssertFatal(sb, "GFXGLCubemap::bind - No active stateblock!");
266   if (!sb)
267      return;   
268      
269   const GFXSamplerStateDesc& ssd = sb->getDesc().samplers[textureUnit];
270   glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, minificationFilter(ssd.minFilter, ssd.mipFilter, 0));   
271   glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GFXGLTextureFilter[ssd.magFilter]);   
272   glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GFXGLTextureAddress[ssd.addressModeU]);
273   glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GFXGLTextureAddress[ssd.addressModeV]);
274   glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GFXGLTextureAddress[ssd.addressModeW]);
275}
276
277void GFXGLCubemap::_onTextureEvent( GFXTexCallbackCode code )
278{
279   if ( code == GFXZombify )
280      zombify();
281   else
282      tmResurrect();
283}
284
285U8* GFXGLCubemap::getTextureData(U32 face, U32 mip)
286{
287   AssertFatal(mMipMapLevels, "");
288   mip = (mip < mMipMapLevels) ? mip : 0;
289   const U32 bytesPerTexel = 8; //TODO make work with more formats!!!!!
290   const U32 dataSize = ImageUtil::isCompressedFormat(mFaceFormat)
291      ? getCompressedSurfaceSize(mFaceFormat, mWidth, mHeight, mip)
292      : (mWidth >> mip) * (mHeight >> mip) * bytesPerTexel;
293
294   U8* data = new U8[dataSize];
295   PRESERVE_TEXTURE(GL_TEXTURE_CUBE_MAP);
296   glBindTexture(GL_TEXTURE_CUBE_MAP, mCubemap);
297
298   if (ImageUtil::isCompressedFormat(mFaceFormat))
299      glGetCompressedTexImage(GFXGLFaceType[face], mip, data);
300   else
301      glGetTexImage(GFXGLFaceType[face], mip, GFXGLTextureFormat[mFaceFormat], GFXGLTextureType[mFaceFormat], data);
302
303   return data;
304}
305
306//-----------------------------------------------------------------------------
307// Cubemap Array
308//-----------------------------------------------------------------------------
309
310GFXGLCubemapArray::GFXGLCubemapArray()
311{
312   mCubemap = NULL;
313}
314
315GFXGLCubemapArray::~GFXGLCubemapArray()
316{
317   glDeleteTextures(1, &mCubemap);
318}
319
320//TODO: really need a common private 'init' function to avoid code double up with these init* functions
321void GFXGLCubemapArray::init(GFXCubemapHandle *cubemaps, const U32 cubemapCount)
322{
323   AssertFatal(cubemaps, "GFXGLCubemapArray- Got null GFXCubemapHandle!");
324   AssertFatal(*cubemaps, "GFXGLCubemapArray - Got empty cubemap!");
325
326   U32 downscalePower = GFXTextureManager::smTextureReductionLevel;
327   U32 scaledSize = cubemaps[0]->getSize();
328
329   if (downscalePower != 0)
330   {
331      // Otherwise apply the appropriate scale...
332      scaledSize >>= downscalePower;
333   }
334
335   //all cubemaps must be the same size,format and number of mipmaps. Grab the details from the first cubemap
336   mSize = scaledSize;
337   mFormat = cubemaps[0]->getFormat();
338   mMipMapLevels = cubemaps[0]->getMipMapLevels() - downscalePower;
339   mNumCubemaps = cubemapCount;
340   const bool isCompressed = ImageUtil::isCompressedFormat(mFormat);
341
342   glGenTextures(1, &mCubemap);
343   PRESERVE_CUBEMAP_ARRAY_TEXTURE();
344   glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, mCubemap);
345   glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAX_LEVEL, mMin(mMipMapLevels - 1, 1));
346   glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
347   glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
348   glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
349   glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
350   glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
351
352   for (U32 i = 0; i < cubemapCount; i++)
353   {
354      GFXGLCubemap* glTex = static_cast<GFXGLCubemap*>(cubemaps[i].getPointer());
355      for (U32 face = 0; face < 6; face++)
356      {
357         for (U32 currentMip = 0; currentMip < mMipMapLevels; currentMip++)
358         {
359            U8 *pixelData = glTex->getTextureData(face, currentMip);
360
361            glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, mCubemap);
362            const U32 mipSize = getMax(U32(1), mSize >> currentMip);
363            if (isCompressed)
364            {
365               const U32 mipDataSize = getCompressedSurfaceSize(mFormat, mSize, mSize, currentMip);
366               glCompressedTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, currentMip, 0, 0, i * 6 + face, mipSize, mipSize, 1, GFXGLTextureFormat[mFormat], GFXGLTextureType[mFormat], pixelData);
367            }
368            else
369            {
370               glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, currentMip, 0, 0, i * 6 + face, mipSize, mipSize, 1, GFXGLTextureFormat[mFormat], GFXGLTextureType[mFormat], pixelData);
371            }
372            glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, 0);
373
374            delete[] pixelData;
375         }
376      }
377   }
378}
379
380//Just allocate the cubemap array but we don't upload any data
381void GFXGLCubemapArray::init(const U32 cubemapCount, const U32 cubemapFaceSize, const GFXFormat format)
382{
383   U32 downscalePower = GFXTextureManager::smTextureReductionLevel;
384   U32 scaledSize = cubemapFaceSize;
385
386   if (downscalePower != 0)
387   {
388      // Otherwise apply the appropriate scale...
389      scaledSize >>= downscalePower;
390   }
391
392   //all cubemaps must be the same size,format and number of mipmaps. Grab the details from the first cubemap
393   mSize = scaledSize;
394   mFormat = format;
395   mMipMapLevels = ImageUtil::getMaxMipCount(scaledSize, scaledSize);
396   mNumCubemaps = cubemapCount;
397   const bool isCompressed = ImageUtil::isCompressedFormat(mFormat);
398
399   glGenTextures(1, &mCubemap);
400   PRESERVE_CUBEMAP_ARRAY_TEXTURE();
401   glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, mCubemap);
402
403   for (U32 i = 0; i < mMipMapLevels; i++)
404   {
405      const U32 mipSize = getMax(U32(1), mSize >> i);
406      glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, i, GFXGLTextureInternalFormat[mFormat], mipSize, mipSize, cubemapCount * 6, 0, GFXGLTextureFormat[mFormat], GFXGLTextureType[mFormat], NULL);
407   }
408
409   glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAX_LEVEL, mMipMapLevels - 1);
410   glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
411   glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
412   glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
413   glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
414   glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
415}
416
417void GFXGLCubemapArray::updateTexture(const GFXCubemapHandle &cubemap, const U32 slot)
418{
419   AssertFatal(slot <= mNumCubemaps, "GFXD3D11CubemapArray::updateTexture - trying to update a cubemap texture that is out of bounds!");
420   if (!cubemap->isInitialized())
421      return;
422   const bool isCompressed = ImageUtil::isCompressedFormat(mFormat);
423
424   GFXGLCubemap* glTex = static_cast<GFXGLCubemap*>(cubemap.getPointer());
425   for (U32 face = 0; face < 6; face++)
426   {
427      for (U32 currentMip = 0; currentMip < mMipMapLevels; currentMip++)
428      {
429         U8 *pixelData = glTex->getTextureData(face, currentMip);
430
431         glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, mCubemap);
432         const U32 mipSize = getMax(U32(1), mSize >> currentMip);
433         if (isCompressed)
434         {
435            const U32 mipDataSize = getCompressedSurfaceSize(mFormat, mSize, mSize, currentMip);
436            glCompressedTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, currentMip, 0, 0, slot * 6 + face, mipSize, mipSize, 1, GFXGLTextureFormat[mFormat], GFXGLTextureType[mFormat], pixelData);
437         }
438         else
439         {                                          
440            glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, currentMip, 0, 0, slot * 6 + face, mipSize, mipSize, 1, GFXGLTextureFormat[mFormat], GFXGLTextureType[mFormat], pixelData);
441         }
442         glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, 0);
443
444         delete[] pixelData;
445      }
446   }
447}
448
449void GFXGLCubemapArray::copyTo(GFXCubemapArray *pDstCubemap)
450{
451   AssertFatal(pDstCubemap, "GFXGLCubemapArray::copyTo - Got null GFXCubemapArray");
452
453   const U32 dstCount = pDstCubemap->getNumCubemaps();
454   const GFXFormat dstFmt = pDstCubemap->getFormat();
455   const U32 dstSize = pDstCubemap->getSize();
456   const U32 dstMips = pDstCubemap->getMipMapLevels();
457
458   AssertFatal(dstCount > mNumCubemaps, "GFXGLCubemapArray::copyTo - Destination too small");
459   AssertFatal(dstFmt == mFormat, "GFXGLCubemapArray::copyTo - Destination format doesn't match");
460   AssertFatal(dstSize == mSize, "GFXGLCubemapArray::copyTo - Destination size doesn't match");
461   AssertFatal(dstMips == mMipMapLevels, "GFXGLCubemapArray::copyTo - Destination mip levels doesn't match");
462
463   GFXGLCubemapArray* pDstCube = static_cast<GFXGLCubemapArray*>(pDstCubemap);
464
465   for (U32 cubeMap = 0; cubeMap < mNumCubemaps; cubeMap++)
466   {
467      for (U32 face = 0; face < CubeFaces; face++)
468      {
469         for (U32 currentMip = 0; currentMip < mMipMapLevels; currentMip++)
470         //U32 currentMip = 0;
471         {
472            //U8 *pixelData = pDstCube->get->getTextureData(face, currentMip);
473            const U32 mipSize = getMax(U32(1), mSize >> currentMip);
474            /*if (isCompressed)
475            {
476               const U32 mipDataSize = getCompressedSurfaceSize(mFormat, mSize, mSize, currentMip);
477               glCompressedTexImage2D(GFXGLFaceType[face], currentMip, GFXGLTextureInternalFormat[mFormat], mipSize, mipSize, 0, mipDataSize, pixelData);
478            }
479            else
480            {*/                                                      //TODO figure out xyzOffsets
481            glCopyImageSubData(mCubemap, GL_TEXTURE_CUBE_MAP_ARRAY, currentMip, 0, 0, cubeMap * face, pDstCube->mCubemap, GL_TEXTURE_CUBE_MAP_ARRAY, currentMip, 0, 0, cubeMap * face, mipSize, mipSize, 6);
482            //glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, mCubemap);
483            //glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, currentMip, 0, 0, 0, mipSize, mipSize, CubeFaces, GFXGLTextureFormat[mFormat], GFXGLTextureType[mFormat], pixelData);
484            //}
485            //delete[] pixelData;
486         }
487      }
488   }
489}
490
491
492void GFXGLCubemapArray::setToTexUnit(U32 tuNum)
493{
494   static_cast<GFXGLDevice*>(getOwningDevice())->setCubemapArrayInternal(tuNum, this);
495}
496
497void GFXGLCubemapArray::bind(U32 textureUnit) const
498{
499   glActiveTexture(GL_TEXTURE0 + textureUnit);
500   glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, mCubemap);
501   static_cast<GFXGLDevice*>(getOwningDevice())->getOpenglCache()->setCacheBindedTex(textureUnit, GL_TEXTURE_CUBE_MAP_ARRAY, mCubemap);
502
503   GFXGLStateBlockRef sb = static_cast<GFXGLDevice*>(GFX)->getCurrentStateBlock();
504   AssertFatal(sb, "GFXGLCubemap::bind - No active stateblock!");
505   if (!sb)
506      return;
507
508   const GFXSamplerStateDesc& ssd = sb->getDesc().samplers[textureUnit];
509   glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MIN_FILTER, minificationFilter(ssd.minFilter, ssd.mipFilter, 0));
510   glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAG_FILTER, GFXGLTextureFilter[ssd.magFilter]);
511   glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_S, GFXGLTextureAddress[ssd.addressModeU]);
512   glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_T, GFXGLTextureAddress[ssd.addressModeV]);
513   glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_R, GFXGLTextureAddress[ssd.addressModeW]);
514}
515