Esempio n. 1
0
void GFXGLCubemap::fillCubeTextures(GFXTexHandle* faces)
{
   AssertFatal( faces, "");
   AssertFatal( faces[0]->mMipLevels > 0, "");

   PRESERVE_CUBEMAP_TEXTURE();
   glBindTexture(GL_TEXTURE_CUBE_MAP, mCubemap);
   glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, faces[0]->mMipLevels - 1 );
   glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
   glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
   glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
   
   U32 reqWidth = faces[0]->getWidth();
   U32 reqHeight = faces[0]->getHeight();
   GFXFormat regFaceFormat = faces[0]->getFormat();
   const bool isCompressed = isCompressedFormat(regFaceFormat);
   mWidth = reqWidth;
   mHeight = reqHeight;
   mFaceFormat = regFaceFormat;
   mMipLevels = getMax( (U32)1, faces[0]->mMipLevels);
   AssertFatal(reqWidth == reqHeight, "GFXGLCubemap::fillCubeTextures - Width and height must be equal!");
   
   for(U32 i = 0; i < 6; i++)
   {
      AssertFatal(faces[i], avar("GFXGLCubemap::fillCubeFaces - texture %i is NULL!", i));
      AssertFatal((faces[i]->getWidth() == reqWidth) && (faces[i]->getHeight() == reqHeight), "GFXGLCubemap::fillCubeFaces - All textures must have identical dimensions!");
      AssertFatal(faces[i]->getFormat() == regFaceFormat, "GFXGLCubemap::fillCubeFaces - All textures must have identical formats!");
      
      mTextures[i] = faces[i];
      GFXFormat faceFormat = faces[i]->getFormat();

        GFXGLTextureObject* glTex = static_cast<GFXGLTextureObject*>(faces[i].getPointer());
        if( isCompressed )
        {
            for( U32 mip = 0; mip < mMipLevels; ++mip )
            {
                const U32 mipWidth  = getMax( U32(1), faces[i]->getWidth() >> mip );
                const U32 mipHeight = getMax( U32(1), faces[i]->getHeight() >> mip );
                const U32 mipDataSize = getCompressedSurfaceSize( mFaceFormat, mWidth, mHeight, mip );

                U8* buf = glTex->getTextureData( mip );
                glCompressedTexImage2D(faceList[i], mip, GFXGLTextureInternalFormat[mFaceFormat], mipWidth, mipHeight, 0, mipDataSize, buf);
                delete[] buf;
            }
        }
        else
        {
            U8* buf = glTex->getTextureData();
            glTexImage2D(faceList[i], 0, GFXGLTextureInternalFormat[faceFormat], mWidth, mHeight, 
                0, GFXGLTextureFormat[faceFormat], GFXGLTextureType[faceFormat], buf);
            delete[] buf;
        }
   }
//-----------------------------------------------------------------------------
// innerCreateTexture
//-----------------------------------------------------------------------------
// This just creates the texture, no info is actually loaded to it.  We do that later.
void GFXGLTextureManager::innerCreateTexture( GFXGLTextureObject *retTex,
        U32 height,
        U32 width,
        U32 depth,
        GFXFormat format,
        GFXTextureProfile *profile,
        U32 numMipLevels,
        bool forceMips)
{
    // No 24 bit formats.  They trigger various oddities because hardware (and Apple's drivers apparently...) don't natively support them.
    if(format == GFXFormatR8G8B8)
        format = GFXFormatR8G8B8A8;

    retTex->mFormat = format;
    retTex->mIsZombie = false;
    retTex->mIsNPoT2 = false;

    GLenum binding = ( (height == 1 || width == 1) && ( height != width ) ) ? GL_TEXTURE_1D : ( (depth == 0) ? GL_TEXTURE_2D : GL_TEXTURE_3D );
    if((profile->testFlag(GFXTextureProfile::RenderTarget) || profile->testFlag(GFXTextureProfile::ZTarget)) && (!isPow2(width) || !isPow2(height)) && !depth)
        retTex->mIsNPoT2 = true;
    retTex->mBinding = binding;

    // Bind it
    PRESERVE_TEXTURE(binding);
    glBindTexture(retTex->getBinding(), retTex->getHandle());

    // Create it
    // TODO: Reenable mipmaps on render targets when Apple fixes their drivers
    if(forceMips && !retTex->mIsNPoT2)
    {
        retTex->mMipLevels = numMipLevels > 1 ? numMipLevels : 0;
    }
    else if(profile->testFlag(GFXTextureProfile::NoMipmap) || profile->testFlag(GFXTextureProfile::RenderTarget) || numMipLevels == 1 || retTex->mIsNPoT2)
    {
        retTex->mMipLevels = 1;
    }
    else
    {
        retTex->mMipLevels = numMipLevels;
    }

    if(!retTex->mIsNPoT2)
    {
        if(!isPow2(width))
            width = getNextPow2(width);
        if(!isPow2(height))
            height = getNextPow2(height);
        if(depth && !isPow2(depth))
            depth = getNextPow2(depth);
    }

    AssertFatal(GFXGLTextureInternalFormat[format] != GL_ZERO, "GFXGLTextureManager::innerCreateTexture - invalid internal format");
    AssertFatal(GFXGLTextureFormat[format] != GL_ZERO, "GFXGLTextureManager::innerCreateTexture - invalid format");
    AssertFatal(GFXGLTextureType[format] != GL_ZERO, "GFXGLTextureManager::innerCreateTexture - invalid type");

    //calculate num mipmaps
    if(retTex->mMipLevels == 0)
        retTex->mMipLevels = getMaxMipmaps(width, height, 1);

    glTexParameteri(binding, GL_TEXTURE_MAX_LEVEL, retTex->mMipLevels-1 );

    //If it wasn't for problems on amd drivers this next part could be really simplified and we wouldn't need to go through manually creating our
    //mipmap pyramid and instead just use glGenerateMipmap
    if(isCompressedFormat(format))
    {
        AssertFatal(binding == GL_TEXTURE_2D,
                    "GFXGLTextureManager::innerCreateTexture - Only compressed 2D textures are supported");

        U32 tempWidth = width;
        U32 tempHeight = height;
        U32 size = getCompressedSurfaceSize(format,height,width);
        //Fill compressed images with 0's
        U8 *pTemp = (U8*)dMalloc(sizeof(U8)*size);
        dMemset(pTemp,0,size);

        for(U32 i=0; i< retTex->mMipLevels; i++)
        {
            tempWidth = getMax( U32(1), width >> i );
            tempHeight = getMax( U32(1), height >> i );
            size = getCompressedSurfaceSize(format,width,height,i);
            glCompressedTexImage2D(binding,i,GFXGLTextureInternalFormat[format],tempWidth,tempHeight,0,size,pTemp);
        }

        dFree(pTemp);
    }
    else
    {
        if(binding == GL_TEXTURE_2D)