gfxGLCubemap.cpp
Engine/source/gfx/gl/gfxGLCubemap.cpp
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