diff --git a/gl/Timmy Note.txt b/gl/Timmy Note.txt deleted file mode 100644 index 2b023404e..000000000 --- a/gl/Timmy Note.txt +++ /dev/null @@ -1 +0,0 @@ -idiot me used glTexImage2D for the cubemap array code, obviously should be glTexImage3D \ No newline at end of file diff --git a/gl/gfxGLCubemap.cpp b/gl/gfxGLCubemap.cpp deleted file mode 100644 index 493a508c7..000000000 --- a/gl/gfxGLCubemap.cpp +++ /dev/null @@ -1,389 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#include "gfx/gl/gfxGLDevice.h" -#include "gfx/gl/gfxGLTextureObject.h" -#include "gfx/gl/gfxGLEnumTranslate.h" -#include "gfx/gl/gfxGLUtils.h" -#include "gfx/gl/gfxGLCubemap.h" -#include "gfx/gfxTextureManager.h" -#include "gfx/gfxCardProfile.h" -#include "gfx/bitmap/ddsFile.h" -#include "gfx/bitmap/imageUtils.h" - - -static GLenum faceList[6] = -{ - GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, - GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, - GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z -}; - -GFXGLCubemap::GFXGLCubemap() : - mCubemap(0), - mDynamicTexSize(0), - mFaceFormat( GFXFormatR8G8B8A8 ) -{ - for(U32 i = 0; i < 6; i++) - mTextures[i] = NULL; - - GFXTextureManager::addEventDelegate( this, &GFXGLCubemap::_onTextureEvent ); -} - -GFXGLCubemap::~GFXGLCubemap() -{ - glDeleteTextures(1, &mCubemap); - GFXTextureManager::removeEventDelegate( this, &GFXGLCubemap::_onTextureEvent ); -} - -GLenum GFXGLCubemap::getEnumForFaceNumber(U32 face) -{ - return faceList[face]; -} - -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 = ImageUtil::isCompressedFormat(regFaceFormat); - mWidth = reqWidth; - mHeight = reqHeight; - mFaceFormat = regFaceFormat; - mMipMapLevels = 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(faces[i].getPointer()); - if( isCompressed ) - { - for( U32 mip = 0; mip < mMipMapLevels; ++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; - } - } - - if( !isCompressed ) - glGenerateMipmap(GL_TEXTURE_CUBE_MAP); -} - -void GFXGLCubemap::initStatic(GFXTexHandle* faces) -{ - if(mCubemap) - return; - - if(faces) - { - AssertFatal(faces[0], "GFXGLCubemap::initStatic - empty texture passed"); - glGenTextures(1, &mCubemap); - fillCubeTextures(faces); - } -} - -void GFXGLCubemap::initStatic( DDSFile *dds ) -{ - if(mCubemap) - return; - - AssertFatal( dds, "GFXGLCubemap::initStatic - Got null DDS file!" ); - AssertFatal( dds->isCubemap(), "GFXGLCubemap::initStatic - Got non-cubemap DDS file!" ); - AssertFatal( dds->mSurfaces.size() == 6, "GFXGLCubemap::initStatic - DDS has less than 6 surfaces!" ); - - mWidth = dds->getWidth(); - mHeight = dds->getHeight(); - mFaceFormat = dds->getFormat(); - mMipMapLevels = dds->getMipLevels(); - const bool isCompressed = ImageUtil::isCompressedFormat(mFaceFormat); - glGenTextures(1, &mCubemap); - - PRESERVE_CUBEMAP_TEXTURE(); - glBindTexture(GL_TEXTURE_CUBE_MAP, mCubemap); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, mMipMapLevels - 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); - - AssertFatal(mWidth == mHeight, "GFXGLCubemap::initStatic - Width and height must be equal!"); - - for(U32 i = 0; i < 6; i++) - { - if ( !dds->mSurfaces[i] ) - { - // TODO: The DDS can skip surfaces, but i'm unsure what i should - // do here when creating the cubemap. Ignore it for now. - continue; - } - - // convert to Z up - const U32 faceIndex = _zUpFaceIndex(i); - - // Now loop thru the mip levels! - for (U32 mip = 0; mip < mMipMapLevels; ++mip) - { - const U32 mipWidth = getMax( U32(1), mWidth >> mip ); - const U32 mipHeight = getMax( U32(1), mHeight >> mip ); - if (isCompressed) - glCompressedTexImage2D(faceList[faceIndex], mip, GFXGLTextureInternalFormat[mFaceFormat], mipWidth, mipHeight, 0, dds->getSurfaceSize(mip), dds->mSurfaces[i]->mMips[mip]); - else - glTexImage2D(faceList[faceIndex], mip, GFXGLTextureInternalFormat[mFaceFormat], mipWidth, mipHeight, 0, - GFXGLTextureFormat[mFaceFormat], GFXGLTextureType[mFaceFormat], dds->mSurfaces[i]->mMips[mip]); - } - } -} - -void GFXGLCubemap::initDynamic(U32 texSize, GFXFormat faceFormat, U32 mipLevels) -{ - mDynamicTexSize = texSize; - mFaceFormat = faceFormat; - const bool isCompressed = ImageUtil::isCompressedFormat(faceFormat); - mMipMapLevels = getMax( (U32)1, getMaxMipmaps( texSize, texSize, 1 ) ); - - glGenTextures(1, &mCubemap); - PRESERVE_CUBEMAP_TEXTURE(); - glBindTexture(GL_TEXTURE_CUBE_MAP, mCubemap); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, mMipMapLevels - 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); - mWidth = texSize; - mHeight = texSize; - - for(U32 i = 0; i < 6; i++) - { - if( ImageUtil::isCompressedFormat(faceFormat) ) - { - for( U32 mip = 0; mip < mMipMapLevels; ++mip ) - { - const U32 mipSize = getMax( U32(1), texSize >> mip ); - const U32 mipDataSize = getCompressedSurfaceSize( mFaceFormat, texSize, texSize, mip ); - glCompressedTexImage2D(faceList[i], mip, GFXGLTextureInternalFormat[mFaceFormat], mipSize, mipSize, 0, mipDataSize, NULL); - } - } - else - { - glTexImage2D( faceList[i], 0, GFXGLTextureInternalFormat[faceFormat], texSize, texSize, - 0, GFXGLTextureFormat[faceFormat], GFXGLTextureType[faceFormat], NULL); - } - } - - if( !isCompressed ) - glGenerateMipmap(GL_TEXTURE_CUBE_MAP); -} - -void GFXGLCubemap::zombify() -{ - glDeleteTextures(1, &mCubemap); - mCubemap = 0; -} - -void GFXGLCubemap::resurrect() -{ - // Handled in tmResurrect -} - -void GFXGLCubemap::tmResurrect() -{ - if(mDynamicTexSize) - initDynamic(mDynamicTexSize,mFaceFormat); - else - { - if ( mDDSFile ) - initStatic( mDDSFile ); - else - initStatic( mTextures ); - } -} - -void GFXGLCubemap::setToTexUnit(U32 tuNum) -{ - static_cast(getOwningDevice())->setCubemapInternal(tuNum, this); -} - -void GFXGLCubemap::bind(U32 textureUnit) const -{ - glActiveTexture(GL_TEXTURE0 + textureUnit); - glBindTexture(GL_TEXTURE_CUBE_MAP, mCubemap); - static_cast(getOwningDevice())->getOpenglCache()->setCacheBindedTex(textureUnit, GL_TEXTURE_CUBE_MAP, mCubemap); - - GFXGLStateBlockRef sb = static_cast(GFX)->getCurrentStateBlock(); - AssertFatal(sb, "GFXGLCubemap::bind - No active stateblock!"); - if (!sb) - return; - - const GFXSamplerStateDesc& ssd = sb->getDesc().samplers[textureUnit]; - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, minificationFilter(ssd.minFilter, ssd.mipFilter, 0)); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GFXGLTextureFilter[ssd.magFilter]); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GFXGLTextureAddress[ssd.addressModeU]); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GFXGLTextureAddress[ssd.addressModeV]); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GFXGLTextureAddress[ssd.addressModeW]); -} - -void GFXGLCubemap::_onTextureEvent( GFXTexCallbackCode code ) -{ - if ( code == GFXZombify ) - zombify(); - else - tmResurrect(); -} - -U8* GFXGLCubemap::getTextureData(U32 face, U32 mip) -{ - AssertFatal(mMipMapLevels, ""); - mip = (mip < mMipMapLevels) ? mip : 0; - const U32 bytesPerTexel = 4; //TODO make work with more formats!!!!! - const U32 dataSize = ImageUtil::isCompressedFormat(mFaceFormat) - ? getCompressedSurfaceSize(mFaceFormat, mWidth, mHeight, mip) - : (mWidth >> mip) * (mHeight >> mip) * bytesPerTexel; - - U8* data = new U8[dataSize]; - PRESERVE_TEXTURE(GL_TEXTURE_CUBE_MAP); - glBindTexture(GL_TEXTURE_CUBE_MAP, mCubemap); - - if (ImageUtil::isCompressedFormat(mFaceFormat)) - glGetCompressedTexImage(faceList[face], mip, data); - else - glGetTexImage(faceList[face], mip, GFXGLTextureFormat[mFaceFormat], GFXGLTextureType[mFaceFormat], data); - - return data; -} - -//----------------------------------------------------------------------------- -// Cubemap Array -//----------------------------------------------------------------------------- - -GFXGLCubemapArray::GFXGLCubemapArray() -{ -} - -GFXGLCubemapArray::~GFXGLCubemapArray() -{ - glDeleteTextures(1, &mCubemap); -} - -void GFXGLCubemapArray::initStatic(GFXCubemapHandle *cubemaps, const U32 cubemapCount) -{ - AssertFatal(cubemaps, "GFXGLCubemapArray- Got null GFXCubemapHandle!"); - AssertFatal(*cubemaps, "GFXGLCubemapArray - Got empty cubemap!"); - - //all cubemaps must be the same size,format and number of mipmaps. Grab the details from the first cubemap - mSize = cubemaps[0]->getSize(); - mFormat = cubemaps[0]->getFormat(); - mMipMapLevels = cubemaps[0]->getMipMapLevels(); - mNumCubemaps = cubemapCount; - const bool isCompressed = ImageUtil::isCompressedFormat(mFormat); - - glGenTextures(1, &mCubemap); - PRESERVE_CUBEMAP_ARRAY_TEXTURE(); - glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, mCubemap); - glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAX_LEVEL, mMipMapLevels - 1); - glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); - - for (U32 i = 0; i < cubemapCount; i++) - { - GFXGLCubemap* glTex = static_cast(cubemaps[i].getPointer()); - for (U32 face = 0; face < 6; face++) - { - for (U32 currentMip = 0; currentMip < mMipMapLevels; currentMip++) - { - U8 *pixelData = glTex->getTextureData(face, currentMip); - const U32 mipSize = getMax(U32(1), mSize >> currentMip); - if (isCompressed) - { - const U32 mipDataSize = getCompressedSurfaceSize(mFormat, mSize, mSize, currentMip); - glCompressedTexImage2D(faceList[face], currentMip, GFXGLTextureInternalFormat[mFormat], mipSize, mipSize, 0, mipDataSize, pixelData); - } - else - { - glTexImage2D(faceList[face], currentMip, GFXGLTextureInternalFormat[mFormat], mipSize, mipSize, - 0, GFXGLTextureFormat[mFormat], GFXGLTextureType[mFormat], pixelData); - } - delete[] pixelData; - } - } - } -} - -void GFXGLCubemapArray::setToTexUnit(U32 tuNum) -{ - static_cast(getOwningDevice())->setCubemapArrayInternal(tuNum, this); -} - -void GFXGLCubemapArray::bind(U32 textureUnit) const -{ - glActiveTexture(GL_TEXTURE0 + textureUnit); - glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, mCubemap); - static_cast(getOwningDevice())->getOpenglCache()->setCacheBindedTex(textureUnit, GL_TEXTURE_CUBE_MAP_ARRAY, mCubemap); - - GFXGLStateBlockRef sb = static_cast(GFX)->getCurrentStateBlock(); - AssertFatal(sb, "GFXGLCubemap::bind - No active stateblock!"); - if (!sb) - return; - - const GFXSamplerStateDesc& ssd = sb->getDesc().samplers[textureUnit]; - glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MIN_FILTER, minificationFilter(ssd.minFilter, ssd.mipFilter, 0)); - glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAG_FILTER, GFXGLTextureFilter[ssd.magFilter]); - glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_S, GFXGLTextureAddress[ssd.addressModeU]); - glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_T, GFXGLTextureAddress[ssd.addressModeV]); - glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_R, GFXGLTextureAddress[ssd.addressModeW]); -} diff --git a/gl/gfxGLCubemap.h b/gl/gfxGLCubemap.h deleted file mode 100644 index 6fa7f0cd3..000000000 --- a/gl/gfxGLCubemap.h +++ /dev/null @@ -1,113 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#ifndef _GFXGLCUBEMAP_H_ -#define _GFXGLCUBEMAP_H_ - -#ifndef _GFXCUBEMAP_H_ -#include "gfx/gfxCubemap.h" -#endif -#ifndef __RESOURCE_H__ -#include "core/resource.h" -#endif - - -class GFXGLCubemap : public GFXCubemap -{ -public: - GFXGLCubemap(); - virtual ~GFXGLCubemap(); - - virtual void initStatic( GFXTexHandle *faces ); - virtual void initStatic( DDSFile *dds ); - virtual void initDynamic( U32 texSize, GFXFormat faceFormat = GFXFormatR8G8B8A8, U32 mipLevels = 0); - virtual U32 getSize() const { return mWidth; } - virtual GFXFormat getFormat() const { return mFaceFormat; } - - // Convenience methods for GFXGLTextureTarget - U32 getWidth() { return mWidth; } - U32 getHeight() { return mHeight; } - U32 getHandle() { return mCubemap; } - - // GFXResource interface - virtual void zombify(); - virtual void resurrect(); - - /// Called by texCB; this is to ensure that all textures have been resurrected before we attempt to res the cubemap. - void tmResurrect(); - - static GLenum getEnumForFaceNumber(U32 face);///< Performs lookup to get a GLenum for the given face number - - /// @return An array containing the texture data - /// @note You are responsible for deleting the returned data! (Use delete[]) - U8* getTextureData(U32 face, U32 mip = 0); - -protected: - - friend class GFXDevice; - friend class GFXGLDevice; - - /// The callback used to get texture events. - /// @see GFXTextureManager::addEventDelegate - void _onTextureEvent( GFXTexCallbackCode code ); - - GLuint mCubemap; ///< Internal GL handle - U32 mDynamicTexSize; ///< Size of faces for a dynamic texture (used in resurrect) - - // Self explanatory - U32 mWidth; - U32 mHeight; - GFXFormat mFaceFormat; - - GFXTexHandle mTextures[6]; ///< Keep refs to our textures for resurrection of static cubemaps - - /// The backing DDSFile uses to restore the faces - /// when the surface is lost. - Resource mDDSFile; - - // should only be called by GFXDevice - virtual void setToTexUnit( U32 tuNum ); ///< Binds the cubemap to the given texture unit - virtual void bind(U32 textureUnit) const; ///< Notifies our owning device that we want to be set to the given texture unit (used for GL internal state tracking) - void fillCubeTextures(GFXTexHandle* faces); ///< Copies the textures in faces into the cubemap - -}; - -class GFXGLCubemapArray : public GFXCubemapArray -{ -public: - GFXGLCubemapArray(); - virtual ~GFXGLCubemapArray(); - virtual void initStatic(GFXCubemapHandle *cubemaps, const U32 cubemapCount); - virtual void setToTexUnit(U32 tuNum); - - // GFXResource interface - virtual void zombify() {} - virtual void resurrect() {} - -protected: - friend class GFXGLDevice; - void bind(U32 textureUnit) const; - GLuint mCubemap; ///< Internal GL handle - -}; - -#endif diff --git a/gl/gfxGLDevice.cpp b/gl/gfxGLDevice.cpp deleted file mode 100644 index 7c968dd57..000000000 --- a/gl/gfxGLDevice.cpp +++ /dev/null @@ -1,1029 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#include "platform/platform.h" -#include "gfx/gl/gfxGLDevice.h" -#include "platform/platformGL.h" - -#include "gfx/gfxCubemap.h" -#include "gfx/screenshot.h" -#include "gfx/gfxDrawUtil.h" - -#include "gfx/gl/gfxGLEnumTranslate.h" -#include "gfx/gl/gfxGLVertexBuffer.h" -#include "gfx/gl/gfxGLPrimitiveBuffer.h" -#include "gfx/gl/gfxGLTextureTarget.h" -#include "gfx/gl/gfxGLTextureManager.h" -#include "gfx/gl/gfxGLTextureObject.h" -#include "gfx/gl/gfxGLCubemap.h" -#include "gfx/gl/gfxGLCardProfiler.h" -#include "gfx/gl/gfxGLWindowTarget.h" -#include "platform/platformDlibrary.h" -#include "gfx/gl/gfxGLShader.h" -#include "gfx/primBuilder.h" -#include "console/console.h" -#include "gfx/gl/gfxGLOcclusionQuery.h" -#include "materials/shaderData.h" -#include "gfx/gl/gfxGLStateCache.h" -#include "gfx/gl/gfxGLVertexAttribLocation.h" -#include "gfx/gl/gfxGLVertexDecl.h" -#include "shaderGen/shaderGen.h" - -GFXAdapter::CreateDeviceInstanceDelegate GFXGLDevice::mCreateDeviceInstance(GFXGLDevice::createInstance); - -GFXDevice *GFXGLDevice::createInstance( U32 adapterIndex ) -{ - return new GFXGLDevice(adapterIndex); -} - -namespace GL -{ - extern void gglPerformBinds(); - extern void gglPerformExtensionBinds(void *context); -} - -void loadGLCore() -{ - static bool coreLoaded = false; // Guess what this is for. - if(coreLoaded) - return; - coreLoaded = true; - - // Make sure we've got our GL bindings. - GL::gglPerformBinds(); -} - -void loadGLExtensions(void *context) -{ - static bool extensionsLoaded = false; - if(extensionsLoaded) - return; - extensionsLoaded = true; - - GL::gglPerformExtensionBinds(context); -} - -void STDCALL glDebugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, - const GLchar *message, const void *userParam) -{ - // JTH [11/24/2016]: This is a temporary fix so that we do not get spammed for redundant fbo changes. - // This only happens on Intel cards. This should be looked into sometime in the near future. - if (dStrStartsWith(message, "API_ID_REDUNDANT_FBO")) - return; - if (severity == GL_DEBUG_SEVERITY_HIGH) - Con::errorf("OPENGL: %s", message); - else if (severity == GL_DEBUG_SEVERITY_MEDIUM) - Con::warnf("OPENGL: %s", message); - else if (severity == GL_DEBUG_SEVERITY_LOW) - Con::printf("OPENGL: %s", message); -} - -void STDCALL glAmdDebugCallback(GLuint id, GLenum category, GLenum severity, GLsizei length, - const GLchar* message, GLvoid* userParam) -{ - if (severity == GL_DEBUG_SEVERITY_HIGH) - Con::errorf("AMDOPENGL: %s", message); - else if (severity == GL_DEBUG_SEVERITY_MEDIUM) - Con::warnf("AMDOPENGL: %s", message); - else if (severity == GL_DEBUG_SEVERITY_LOW) - Con::printf("AMDOPENGL: %s", message); -} - -void GFXGLDevice::initGLState() -{ - // We don't currently need to sync device state with a known good place because we are - // going to set everything in GFXGLStateBlock, but if we change our GFXGLStateBlock strategy, this may - // need to happen. - - // Deal with the card profiler here when we know we have a valid context. - mCardProfiler = new GFXGLCardProfiler(); - mCardProfiler->init(); - glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, (GLint*)&mMaxShaderTextures); - // JTH: Needs removed, ffp - //glGetIntegerv(GL_MAX_TEXTURE_UNITS, (GLint*)&mMaxFFTextures); - glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, (GLint*)&mMaxTRColors); - mMaxTRColors = getMin( mMaxTRColors, (U32)(GFXTextureTarget::MaxRenderSlotId-1) ); - - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - - // [JTH 5/6/2016] GLSL 1.50 is really SM 4.0 - // Setting mPixelShaderVersion to 3.0 will allow Advanced Lighting to run. - mPixelShaderVersion = 3.0; - - // Set capability extensions. - mCapabilities.anisotropicFiltering = mCardProfiler->queryProfile("GL_EXT_texture_filter_anisotropic"); - mCapabilities.bufferStorage = mCardProfiler->queryProfile("GL_ARB_buffer_storage"); - mCapabilities.shaderModel5 = mCardProfiler->queryProfile("GL_ARB_gpu_shader5"); - mCapabilities.textureStorage = mCardProfiler->queryProfile("GL_ARB_texture_storage"); - mCapabilities.samplerObjects = mCardProfiler->queryProfile("GL_ARB_sampler_objects"); - mCapabilities.copyImage = mCardProfiler->queryProfile("GL_ARB_copy_image"); - mCapabilities.vertexAttributeBinding = mCardProfiler->queryProfile("GL_ARB_vertex_attrib_binding"); - - String vendorStr = (const char*)glGetString( GL_VENDOR ); - if( vendorStr.find("NVIDIA", 0, String::NoCase | String::Left) != String::NPos) - mUseGlMap = false; - - // Workaround for all Mac's, has a problem using glMap* with volatile buffers -#ifdef TORQUE_OS_MAC - mUseGlMap = false; -#endif - -#if TORQUE_DEBUG - if( gglHasExtension(ARB_debug_output) ) - { - glEnable(GL_DEBUG_OUTPUT); - glDebugMessageCallbackARB(glDebugCallback, NULL); - glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB); - GLuint unusedIds = 0; - glDebugMessageControlARB(GL_DONT_CARE, - GL_DONT_CARE, - GL_DONT_CARE, - 0, - &unusedIds, - GL_TRUE); - } - else if(gglHasExtension(AMD_debug_output)) - { - glEnable(GL_DEBUG_OUTPUT); - glDebugMessageCallbackAMD(glAmdDebugCallback, NULL); - //glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB); - GLuint unusedIds = 0; - glDebugMessageEnableAMD(GL_DONT_CARE, GL_DONT_CARE, 0,&unusedIds, GL_TRUE); - } -#endif - - PlatformGL::setVSync(smDisableVSync ? 0 : 1); - - //install vsync callback - Con::NotifyDelegate clbk( this, &GFXGLDevice::vsyncCallback ); - Con::addVariableNotify( "$pref::Video::disableVerticalSync", clbk ); - - //OpenGL 3 need a binded VAO for render - GLuint vao; - glGenVertexArrays(1, &vao); - glBindVertexArray(vao); - - //enable sRGB - glEnable(GL_FRAMEBUFFER_SRGB); -} - -void GFXGLDevice::vsyncCallback() -{ - PlatformGL::setVSync(smDisableVSync ? 0 : 1); -} - -GFXGLDevice::GFXGLDevice(U32 adapterIndex) : - mAdapterIndex(adapterIndex), - mNeedUpdateVertexAttrib(false), - mCurrentPB(NULL), - mDrawInstancesCount(0), - mCurrentShader( NULL ), - m_mCurrentWorld(true), - m_mCurrentView(true), - mContext(NULL), - mPixelFormat(NULL), - mPixelShaderVersion(0.0f), - mMaxShaderTextures(2), - mMaxFFTextures(2), - mMaxTRColors(1), - mClip(0, 0, 0, 0), - mWindowRT(NULL), - mUseGlMap(true) -{ - for(int i = 0; i < VERTEX_STREAM_COUNT; ++i) - { - mCurrentVB[i] = NULL; - mCurrentVB_Divisor[i] = 0; - } - - // Initiailize capabilities to false. - memset(&mCapabilities, 0, sizeof(GLCapabilities)); - - loadGLCore(); - - GFXGLEnumTranslate::init(); - - GFXVertexColor::setSwizzle( &Swizzles::rgba ); - - // OpenGL have native RGB, no need swizzle - mDeviceSwizzle32 = &Swizzles::rgba; - mDeviceSwizzle24 = &Swizzles::rgb; - - mTextureManager = new GFXGLTextureManager(); - gScreenShot = new ScreenShot(); - - for(U32 i = 0; i < TEXTURE_STAGE_COUNT; i++) - mActiveTextureType[i] = GL_ZERO; - - mNumVertexStream = 2; - - for(int i = 0; i < GS_COUNT; ++i) - mModelViewProjSC[i] = NULL; - - mOpenglStateCache = new GFXGLStateCache; - -} - -GFXGLDevice::~GFXGLDevice() -{ - mCurrentStateBlock = NULL; - - for(int i = 0; i < VERTEX_STREAM_COUNT; ++i) - mCurrentVB[i] = NULL; - mCurrentPB = NULL; - - for(U32 i = 0; i < mVolatileVBs.size(); i++) - mVolatileVBs[i] = NULL; - for(U32 i = 0; i < mVolatilePBs.size(); i++) - mVolatilePBs[i] = NULL; - - // Clear out our current texture references - for (U32 i = 0; i < TEXTURE_STAGE_COUNT; i++) - { - mCurrentTexture[i] = NULL; - mNewTexture[i] = NULL; - mCurrentCubemap[i] = NULL; - mNewCubemap[i] = NULL; - } - - mRTStack.clear(); - mCurrentRT = NULL; - - if( mTextureManager ) - { - mTextureManager->zombify(); - mTextureManager->kill(); - } - - GFXResource* walk = mResourceListHead; - while(walk) - { - walk->zombify(); - walk = walk->getNextResource(); - } - - if( mCardProfiler ) - SAFE_DELETE( mCardProfiler ); - - SAFE_DELETE( gScreenShot ); - - SAFE_DELETE( mOpenglStateCache ); -} - -void GFXGLDevice::zombify() -{ - mTextureManager->zombify(); - - for(int i = 0; i < VERTEX_STREAM_COUNT; ++i) - if(mCurrentVB[i]) - mCurrentVB[i]->finish(); - if(mCurrentPB) - mCurrentPB->finish(); - - //mVolatileVBs.clear(); - //mVolatilePBs.clear(); - GFXResource* walk = mResourceListHead; - while(walk) - { - walk->zombify(); - walk = walk->getNextResource(); - } -} - -void GFXGLDevice::resurrect() -{ - GFXResource* walk = mResourceListHead; - while(walk) - { - walk->resurrect(); - walk = walk->getNextResource(); - } - for(int i = 0; i < VERTEX_STREAM_COUNT; ++i) - if(mCurrentVB[i]) - mCurrentVB[i]->prepare(); - if(mCurrentPB) - mCurrentPB->prepare(); - - mTextureManager->resurrect(); -} - -GFXVertexBuffer* GFXGLDevice::findVolatileVBO(U32 numVerts, const GFXVertexFormat *vertexFormat, U32 vertSize) -{ - PROFILE_SCOPE(GFXGLDevice_findVBPool); - for(U32 i = 0; i < mVolatileVBs.size(); i++) - if ( mVolatileVBs[i]->mNumVerts >= numVerts && - mVolatileVBs[i]->mVertexFormat.isEqual( *vertexFormat ) && - mVolatileVBs[i]->mVertexSize == vertSize && - mVolatileVBs[i]->getRefCount() == 1 ) - return mVolatileVBs[i]; - - // No existing VB, so create one - PROFILE_SCOPE(GFXGLDevice_createVBPool); - StrongRefPtr buf(new GFXGLVertexBuffer(GFX, numVerts, vertexFormat, vertSize, GFXBufferTypeVolatile)); - buf->registerResourceWithDevice(this); - mVolatileVBs.push_back(buf); - return buf.getPointer(); -} - -GFXPrimitiveBuffer* GFXGLDevice::findVolatilePBO(U32 numIndices, U32 numPrimitives) -{ - for(U32 i = 0; i < mVolatilePBs.size(); i++) - if((mVolatilePBs[i]->mIndexCount >= numIndices) && (mVolatilePBs[i]->getRefCount() == 1)) - return mVolatilePBs[i]; - - // No existing PB, so create one - StrongRefPtr buf(new GFXGLPrimitiveBuffer(GFX, numIndices, numPrimitives, GFXBufferTypeVolatile)); - buf->registerResourceWithDevice(this); - mVolatilePBs.push_back(buf); - return buf.getPointer(); -} - -GFXVertexBuffer *GFXGLDevice::allocVertexBuffer( U32 numVerts, - const GFXVertexFormat *vertexFormat, - U32 vertSize, - GFXBufferType bufferType, - void* data ) -{ - PROFILE_SCOPE(GFXGLDevice_allocVertexBuffer); - if(bufferType == GFXBufferTypeVolatile) - return findVolatileVBO(numVerts, vertexFormat, vertSize); - - GFXGLVertexBuffer* buf = new GFXGLVertexBuffer( GFX, numVerts, vertexFormat, vertSize, bufferType ); - buf->registerResourceWithDevice(this); - - if(data) - { - void* dest; - buf->lock(0, numVerts, &dest); - dMemcpy(dest, data, vertSize * numVerts); - buf->unlock(); - } - - return buf; -} - -GFXPrimitiveBuffer *GFXGLDevice::allocPrimitiveBuffer( U32 numIndices, U32 numPrimitives, GFXBufferType bufferType, void* data ) -{ - GFXPrimitiveBuffer* buf; - - if(bufferType == GFXBufferTypeVolatile) - { - buf = findVolatilePBO(numIndices, numPrimitives); - } - else - { - buf = new GFXGLPrimitiveBuffer(GFX, numIndices, numPrimitives, bufferType); - buf->registerResourceWithDevice(this); - } - - if(data) - { - void* dest; - buf->lock(0, numIndices, &dest); - dMemcpy(dest, data, sizeof(U16) * numIndices); - buf->unlock(); - } - return buf; -} - -void GFXGLDevice::setVertexStream( U32 stream, GFXVertexBuffer *buffer ) -{ - AssertFatal(stream <= 1, "GFXGLDevice::setVertexStream only support 2 stream (0: data, 1: instancing)"); - - //if(mCurrentVB[stream] != buffer) - { - // Reset the state the old VB required, then set the state the new VB requires. - if( mCurrentVB[stream] ) - { - mCurrentVB[stream]->finish(); - } - - mCurrentVB[stream] = static_cast( buffer ); - - mNeedUpdateVertexAttrib = true; - } -} - -void GFXGLDevice::setVertexStreamFrequency( U32 stream, U32 frequency ) -{ - if( stream == 0 ) - { - mCurrentVB_Divisor[stream] = 0; // non instanced, is vertex buffer - mDrawInstancesCount = frequency; // instances count - } - else - { - AssertFatal(frequency <= 1, "GFXGLDevice::setVertexStreamFrequency only support 0/1 for this stream" ); - if( stream == 1 && frequency == 1 ) - mCurrentVB_Divisor[stream] = 1; // instances data need a frequency of 1 - else - mCurrentVB_Divisor[stream] = 0; - } - - mNeedUpdateVertexAttrib = true; -} - -GFXCubemap* GFXGLDevice::createCubemap() -{ - GFXGLCubemap* cube = new GFXGLCubemap(); - cube->registerResourceWithDevice(this); - return cube; -}; - -GFXCubemapArray *GFXGLDevice::createCubemapArray() -{ - GFXGLCubemapArray* cubeArray = new GFXGLCubemapArray(); - cubeArray->registerResourceWithDevice(this); - return cubeArray; -} - -void GFXGLDevice::endSceneInternal() -{ - // nothing to do for opengl - mCanCurrentlyRender = false; -} - -void GFXGLDevice::clear(U32 flags, const LinearColorF& color, F32 z, U32 stencil) -{ - // Make sure we have flushed our render target state. - _updateRenderTargets(); - - bool writeAllColors = true; - bool zwrite = true; - bool writeAllStencil = true; - const GFXStateBlockDesc *desc = NULL; - if (mCurrentGLStateBlock) - { - desc = &mCurrentGLStateBlock->getDesc(); - zwrite = desc->zWriteEnable; - writeAllColors = desc->colorWriteRed && desc->colorWriteGreen && desc->colorWriteBlue && desc->colorWriteAlpha; - writeAllStencil = desc->stencilWriteMask == 0xFFFFFFFF; - } - - glColorMask(true, true, true, true); - glDepthMask(true); - glStencilMask(0xFFFFFFFF); - glClearColor(color.red, color.green, color.blue, color.alpha); - glClearDepth(z); - glClearStencil(stencil); - - GLbitfield clearflags = 0; - clearflags |= (flags & GFXClearTarget) ? GL_COLOR_BUFFER_BIT : 0; - clearflags |= (flags & GFXClearZBuffer) ? GL_DEPTH_BUFFER_BIT : 0; - clearflags |= (flags & GFXClearStencil) ? GL_STENCIL_BUFFER_BIT : 0; - - glClear(clearflags); - - if(!writeAllColors) - glColorMask(desc->colorWriteRed, desc->colorWriteGreen, desc->colorWriteBlue, desc->colorWriteAlpha); - - if(!zwrite) - glDepthMask(false); - - if(!writeAllStencil) - glStencilMask(desc->stencilWriteMask); -} - -void GFXGLDevice::clearColorAttachment(const U32 attachment, const LinearColorF& color) -{ - const GLfloat clearColor[4] = { color.red, color.green, color.blue, color.alpha }; - glClearBufferfv(GL_COLOR, attachment, clearColor); -} - -// Given a primitive type and a number of primitives, return the number of indexes/vertexes used. -inline GLsizei GFXGLDevice::primCountToIndexCount(GFXPrimitiveType primType, U32 primitiveCount) -{ - switch (primType) - { - case GFXPointList : - return primitiveCount; - break; - case GFXLineList : - return primitiveCount * 2; - break; - case GFXLineStrip : - return primitiveCount + 1; - break; - case GFXTriangleList : - return primitiveCount * 3; - break; - case GFXTriangleStrip : - return 2 + primitiveCount; - break; - default: - AssertFatal(false, "GFXGLDevice::primCountToIndexCount - unrecognized prim type"); - break; - } - - return 0; -} - -GFXVertexDecl* GFXGLDevice::allocVertexDecl( const GFXVertexFormat *vertexFormat ) -{ - PROFILE_SCOPE(GFXGLDevice_allocVertexDecl); - typedef Map GFXGLVertexDeclMap; - static GFXGLVertexDeclMap declMap; - GFXGLVertexDeclMap::Iterator itr = declMap.find( (void*)vertexFormat->getDescription().c_str() ); // description string are interned, safe to use c_str() - if(itr != declMap.end()) - return &itr->value; - - GFXGLVertexDecl &decl = declMap[(void*)vertexFormat->getDescription().c_str()]; - decl.init(vertexFormat); - return &decl; -} - -void GFXGLDevice::setVertexDecl( const GFXVertexDecl *decl ) -{ - static_cast(decl)->prepareVertexFormat(); -} - -inline void GFXGLDevice::preDrawPrimitive() -{ - if( mStateDirty ) - { - updateStates(); - } - - if(mCurrentShaderConstBuffer) - setShaderConstBufferInternal(mCurrentShaderConstBuffer); - - if( mNeedUpdateVertexAttrib ) - { - AssertFatal(mCurrVertexDecl, ""); - const GFXGLVertexDecl* decl = static_cast(mCurrVertexDecl); - - for(int i = 0; i < getNumVertexStreams(); ++i) - { - if(mCurrentVB[i]) - { - mCurrentVB[i]->prepare(i, mCurrentVB_Divisor[i]); // GL_ARB_vertex_attrib_binding - decl->prepareBuffer_old( i, mCurrentVB[i]->mBuffer, mCurrentVB_Divisor[i] ); // old vertex buffer/format - } - } - - decl->updateActiveVertexAttrib( GFXGL->getOpenglCache()->getCacheVertexAttribActive() ); - } - - mNeedUpdateVertexAttrib = false; -} - -inline void GFXGLDevice::postDrawPrimitive(U32 primitiveCount) -{ - mDeviceStatistics.mDrawCalls++; - mDeviceStatistics.mPolyCount += primitiveCount; -} - -void GFXGLDevice::drawPrimitive( GFXPrimitiveType primType, U32 vertexStart, U32 primitiveCount ) -{ - preDrawPrimitive(); - - if(mCurrentVB[0]) - vertexStart += mCurrentVB[0]->mBufferVertexOffset; - - if(mDrawInstancesCount) - glDrawArraysInstanced(GFXGLPrimType[primType], vertexStart, primCountToIndexCount(primType, primitiveCount), mDrawInstancesCount); - else - glDrawArrays(GFXGLPrimType[primType], vertexStart, primCountToIndexCount(primType, primitiveCount)); - - postDrawPrimitive(primitiveCount); -} - -void GFXGLDevice::drawIndexedPrimitive( GFXPrimitiveType primType, - U32 startVertex, - U32 minIndex, - U32 numVerts, - U32 startIndex, - U32 primitiveCount ) -{ - preDrawPrimitive(); - - U16* buf = (U16*)static_cast(mCurrentPrimitiveBuffer.getPointer())->getBuffer() + startIndex + mCurrentPrimitiveBuffer->mVolatileStart; - - const U32 baseVertex = mCurrentVB[0]->mBufferVertexOffset + startVertex; - - if(mDrawInstancesCount) - glDrawElementsInstancedBaseVertex(GFXGLPrimType[primType], primCountToIndexCount(primType, primitiveCount), GL_UNSIGNED_SHORT, buf, mDrawInstancesCount, baseVertex); - else - glDrawElementsBaseVertex(GFXGLPrimType[primType], primCountToIndexCount(primType, primitiveCount), GL_UNSIGNED_SHORT, buf, baseVertex); - - postDrawPrimitive(primitiveCount); -} - -void GFXGLDevice::setPB(GFXGLPrimitiveBuffer* pb) -{ - if(mCurrentPB) - mCurrentPB->finish(); - mCurrentPB = pb; -} - -void GFXGLDevice::setLightInternal(U32 lightStage, const GFXLightInfo light, bool lightEnable) -{ - // ONLY NEEDED ON FFP -} - -void GFXGLDevice::setLightMaterialInternal(const GFXLightMaterial mat) -{ - // ONLY NEEDED ON FFP -} - -void GFXGLDevice::setGlobalAmbientInternal(LinearColorF color) -{ - // ONLY NEEDED ON FFP -} - -void GFXGLDevice::setTextureInternal(U32 textureUnit, const GFXTextureObject*texture) -{ - GFXGLTextureObject *tex = static_cast(const_cast(texture)); - if (tex) - { - mActiveTextureType[textureUnit] = tex->getBinding(); - tex->bind(textureUnit); - } - else if(mActiveTextureType[textureUnit] != GL_ZERO) - { - glActiveTexture(GL_TEXTURE0 + textureUnit); - glBindTexture(mActiveTextureType[textureUnit], 0); - getOpenglCache()->setCacheBindedTex(textureUnit, mActiveTextureType[textureUnit], 0); - mActiveTextureType[textureUnit] = GL_ZERO; - } -} - -void GFXGLDevice::setCubemapInternal(U32 textureUnit, const GFXGLCubemap* texture) -{ - if(texture) - { - mActiveTextureType[textureUnit] = GL_TEXTURE_CUBE_MAP; - texture->bind(textureUnit); - } - else if(mActiveTextureType[textureUnit] != GL_ZERO) - { - glActiveTexture(GL_TEXTURE0 + textureUnit); - glBindTexture(mActiveTextureType[textureUnit], 0); - getOpenglCache()->setCacheBindedTex(textureUnit, mActiveTextureType[textureUnit], 0); - mActiveTextureType[textureUnit] = GL_ZERO; - } -} - -void GFXGLDevice::setCubemapArrayInternal(U32 textureUnit, const GFXGLCubemapArray* texture) -{ - if (texture) - { - mActiveTextureType[textureUnit] = GL_TEXTURE_CUBE_MAP_ARRAY; - texture->bind(textureUnit); - } - else if (mActiveTextureType[textureUnit] != GL_ZERO) - { - glActiveTexture(GL_TEXTURE0 + textureUnit); - glBindTexture(mActiveTextureType[textureUnit], 0); - getOpenglCache()->setCacheBindedTex(textureUnit, mActiveTextureType[textureUnit], 0); - mActiveTextureType[textureUnit] = GL_ZERO; - } -} - -void GFXGLDevice::setMatrix( GFXMatrixType mtype, const MatrixF &mat ) -{ - // ONLY NEEDED ON FFP -} - -void GFXGLDevice::setClipRect( const RectI &inRect ) -{ - AssertFatal(mCurrentRT.isValid(), "GFXGLDevice::setClipRect - must have a render target set to do any rendering operations!"); - - // Clip the rect against the renderable size. - Point2I size = mCurrentRT->getSize(); - RectI maxRect(Point2I(0,0), size); - mClip = inRect; - mClip.intersect(maxRect); - - // Create projection matrix. See http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/ortho.html - const F32 left = mClip.point.x; - const F32 right = mClip.point.x + mClip.extent.x; - const F32 bottom = mClip.extent.y; - const F32 top = 0.0f; - const F32 nearPlane = 0.0f; - const F32 farPlane = 1.0f; - - const F32 tx = -(right + left)/(right - left); - const F32 ty = -(top + bottom)/(top - bottom); - const F32 tz = -(farPlane + nearPlane)/(farPlane - nearPlane); - - static Point4F pt; - pt.set(2.0f / (right - left), 0.0f, 0.0f, 0.0f); - mProjectionMatrix.setColumn(0, pt); - - pt.set(0.0f, 2.0f/(top - bottom), 0.0f, 0.0f); - mProjectionMatrix.setColumn(1, pt); - - pt.set(0.0f, 0.0f, -2.0f/(farPlane - nearPlane), 0.0f); - mProjectionMatrix.setColumn(2, pt); - - pt.set(tx, ty, tz, 1.0f); - mProjectionMatrix.setColumn(3, pt); - - // Translate projection matrix. - static MatrixF translate(true); - pt.set(0.0f, -mClip.point.y, 0.0f, 1.0f); - translate.setColumn(3, pt); - - mProjectionMatrix *= translate; - - setMatrix(GFXMatrixProjection, mProjectionMatrix); - - MatrixF mTempMatrix(true); - setViewMatrix( mTempMatrix ); - setWorldMatrix( mTempMatrix ); - - // Set the viewport to the clip rect - RectI viewport(mClip.point.x, mClip.point.y, mClip.extent.x, mClip.extent.y); - setViewport(viewport); -} - -/// Creates a state block object based on the desc passed in. This object -/// represents an immutable state. -GFXStateBlockRef GFXGLDevice::createStateBlockInternal(const GFXStateBlockDesc& desc) -{ - return GFXStateBlockRef(new GFXGLStateBlock(desc)); -} - -/// Activates a stateblock -void GFXGLDevice::setStateBlockInternal(GFXStateBlock* block, bool force) -{ - AssertFatal(dynamic_cast(block), "GFXGLDevice::setStateBlockInternal - Incorrect stateblock type for this device!"); - GFXGLStateBlock* glBlock = static_cast(block); - GFXGLStateBlock* glCurrent = static_cast(mCurrentStateBlock.getPointer()); - if (force) - glCurrent = NULL; - - glBlock->activate(glCurrent); // Doesn't use current yet. - mCurrentGLStateBlock = glBlock; -} - -//------------------------------------------------------------------------------ - -GFXTextureTarget * GFXGLDevice::allocRenderToTextureTarget(bool genMips) -{ - GFXGLTextureTarget *targ = new GFXGLTextureTarget(genMips); - targ->registerResourceWithDevice(this); - return targ; -} - -GFXFence * GFXGLDevice::createFence() -{ - GFXFence* fence = _createPlatformSpecificFence(); - if(!fence) - fence = new GFXGeneralFence( this ); - - fence->registerResourceWithDevice(this); - return fence; -} - -GFXOcclusionQuery* GFXGLDevice::createOcclusionQuery() -{ - GFXOcclusionQuery *query = new GFXGLOcclusionQuery( this ); - query->registerResourceWithDevice(this); - return query; -} - -void GFXGLDevice::setupGenericShaders( GenericShaderType type ) -{ - AssertFatal(type != GSTargetRestore, ""); - - if( mGenericShader[GSColor] == NULL ) - { - ShaderData *shaderData; - - shaderData = new ShaderData(); - shaderData->setField("OGLVertexShaderFile", ShaderGen::smCommonShaderPath + String("/fixedFunction/gl/colorV.glsl")); - shaderData->setField("OGLPixelShaderFile", ShaderGen::smCommonShaderPath + String("/fixedFunction/gl/colorP.glsl")); - shaderData->setField("pixVersion", "2.0"); - shaderData->registerObject(); - mGenericShader[GSColor] = shaderData->getShader(); - mGenericShaderBuffer[GSColor] = mGenericShader[GSColor]->allocConstBuffer(); - mModelViewProjSC[GSColor] = mGenericShader[GSColor]->getShaderConstHandle( "$modelView" ); - Sim::getRootGroup()->addObject(shaderData); - - shaderData = new ShaderData(); - shaderData->setField("OGLVertexShaderFile", ShaderGen::smCommonShaderPath + String("/fixedFunction/gl/modColorTextureV.glsl")); - shaderData->setField("OGLPixelShaderFile", ShaderGen::smCommonShaderPath + String("/fixedFunction/gl/modColorTextureP.glsl")); - shaderData->setSamplerName("$diffuseMap", 0); - shaderData->setField("pixVersion", "2.0"); - shaderData->registerObject(); - mGenericShader[GSModColorTexture] = shaderData->getShader(); - mGenericShaderBuffer[GSModColorTexture] = mGenericShader[GSModColorTexture]->allocConstBuffer(); - mModelViewProjSC[GSModColorTexture] = mGenericShader[GSModColorTexture]->getShaderConstHandle( "$modelView" ); - Sim::getRootGroup()->addObject(shaderData); - - shaderData = new ShaderData(); - shaderData->setField("OGLVertexShaderFile", ShaderGen::smCommonShaderPath + String("/fixedFunction/gl/addColorTextureV.glsl")); - shaderData->setField("OGLPixelShaderFile", ShaderGen::smCommonShaderPath + String("/fixedFunction/gl/addColorTextureP.glsl")); - shaderData->setSamplerName("$diffuseMap", 0); - shaderData->setField("pixVersion", "2.0"); - shaderData->registerObject(); - mGenericShader[GSAddColorTexture] = shaderData->getShader(); - mGenericShaderBuffer[GSAddColorTexture] = mGenericShader[GSAddColorTexture]->allocConstBuffer(); - mModelViewProjSC[GSAddColorTexture] = mGenericShader[GSAddColorTexture]->getShaderConstHandle( "$modelView" ); - Sim::getRootGroup()->addObject(shaderData); - - shaderData = new ShaderData(); - shaderData->setField("OGLVertexShaderFile", ShaderGen::smCommonShaderPath + String("/fixedFunction/gl/textureV.glsl")); - shaderData->setField("OGLPixelShaderFile", ShaderGen::smCommonShaderPath + String("/fixedFunction/gl/textureP.glsl")); - shaderData->setSamplerName("$diffuseMap", 0); - shaderData->setField("pixVersion", "2.0"); - shaderData->registerObject(); - mGenericShader[GSTexture] = shaderData->getShader(); - mGenericShaderBuffer[GSTexture] = mGenericShader[GSTexture]->allocConstBuffer(); - mModelViewProjSC[GSTexture] = mGenericShader[GSTexture]->getShaderConstHandle( "$modelView" ); - Sim::getRootGroup()->addObject(shaderData); - } - - MatrixF tempMatrix = mProjectionMatrix * mViewMatrix * mWorldMatrix[mWorldStackSize]; - mGenericShaderBuffer[type]->setSafe(mModelViewProjSC[type], tempMatrix); - - setShader( mGenericShader[type] ); - setShaderConstBuffer( mGenericShaderBuffer[type] ); -} -GFXShader* GFXGLDevice::createShader() -{ - GFXGLShader* shader = new GFXGLShader(); - shader->registerResourceWithDevice( this ); - return shader; -} - -void GFXGLDevice::setShader(GFXShader *shader, bool force) -{ - if(mCurrentShader == shader && !force) - return; - - if ( shader ) - { - GFXGLShader *glShader = static_cast( shader ); - glShader->useProgram(); - mCurrentShader = shader; - } - else - { - setupGenericShaders(); - } -} - -void GFXGLDevice::setShaderConstBufferInternal(GFXShaderConstBuffer* buffer) -{ - PROFILE_SCOPE(GFXGLDevice_setShaderConstBufferInternal); - static_cast(buffer)->activate(); -} - -U32 GFXGLDevice::getNumSamplers() const -{ - return getMin((U32)TEXTURE_STAGE_COUNT,mPixelShaderVersion > 0.001f ? mMaxShaderTextures : mMaxFFTextures); -} - -GFXTextureObject* GFXGLDevice::getDefaultDepthTex() const -{ - if(mWindowRT && mWindowRT->getPointer()) - return static_cast( mWindowRT->getPointer() )->mBackBufferDepthTex.getPointer(); - - return NULL; -} - -U32 GFXGLDevice::getNumRenderTargets() const -{ - return mMaxTRColors; -} - -void GFXGLDevice::_updateRenderTargets() -{ - if ( mRTDirty || mCurrentRT->isPendingState() ) - { - if ( mRTDeactivate ) - { - mRTDeactivate->deactivate(); - mRTDeactivate = NULL; - } - - // NOTE: The render target changes is not really accurate - // as the GFXTextureTarget supports MRT internally. So when - // we activate a GFXTarget it could result in multiple calls - // to SetRenderTarget on the actual device. - mDeviceStatistics.mRenderTargetChanges++; - - GFXGLTextureTarget *tex = dynamic_cast( mCurrentRT.getPointer() ); - if ( tex ) - { - tex->applyState(); - tex->makeActive(); - } - else - { - GFXGLWindowTarget *win = dynamic_cast( mCurrentRT.getPointer() ); - AssertFatal( win != NULL, - "GFXGLDevice::_updateRenderTargets() - invalid target subclass passed!" ); - - win->makeActive(); - - if( win->mContext != static_cast(GFX)->mContext ) - { - mRTDirty = false; - GFX->updateStates(true); - } - } - - mRTDirty = false; - } - - if ( mViewportDirty ) - { - glViewport( mViewport.point.x, mViewport.point.y, mViewport.extent.x, mViewport.extent.y ); - mViewportDirty = false; - } -} - -GFXFormat GFXGLDevice::selectSupportedFormat( GFXTextureProfile* profile, - const Vector& formats, - bool texture, - bool mustblend, - bool mustfilter ) -{ - for(U32 i = 0; i < formats.size(); i++) - { - // Single channel textures are not supported by FBOs. - if(profile->testFlag(GFXTextureProfile::RenderTarget) && (formats[i] == GFXFormatA8 || formats[i] == GFXFormatL8 || formats[i] == GFXFormatL16)) - continue; - if(GFXGLTextureInternalFormat[formats[i]] == GL_ZERO) - continue; - - return formats[i]; - } - - return GFXFormatR8G8B8A8; -} - -U32 GFXGLDevice::getTotalVideoMemory_GL_EXT() -{ - // Source: http://www.opengl.org/registry/specs/ATI/meminfo.txt - if( gglHasExtension(ATI_meminfo) ) - { - GLint mem[4] = {0}; - glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, mem); // Retrieve the texture pool - - /* With mem[0] i get only the total memory free in the pool in KB - * - * mem[0] - total memory free in the pool - * mem[1] - largest available free block in the pool - * mem[2] - total auxiliary memory free - * mem[3] - largest auxiliary free block - */ - - return mem[0] / 1024; - } - - //source http://www.opengl.org/registry/specs/NVX/gpu_memory_info.txt - else if( gglHasExtension(NVX_gpu_memory_info) ) - { - GLint mem = 0; - glGetIntegerv(GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX, &mem); - return mem / 1024; - } - - // TODO OPENGL, add supprt for INTEL cards. - - return 0; -} - -// -// Register this device with GFXInit -// -class GFXGLRegisterDevice -{ -public: - GFXGLRegisterDevice() - { - GFXInit::getRegisterDeviceSignal().notify(&GFXGLDevice::enumerateAdapters); - } -}; - -static GFXGLRegisterDevice pGLRegisterDevice; - -ConsoleFunction(cycleResources, void, 1, 1, "") -{ - static_cast(GFX)->zombify(); - static_cast(GFX)->resurrect(); -} diff --git a/gl/gfxGLDevice.h b/gl/gfxGLDevice.h deleted file mode 100644 index a93ae8a7b..000000000 --- a/gl/gfxGLDevice.h +++ /dev/null @@ -1,281 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#ifndef _GFXGLDEVICE_H_ -#define _GFXGLDEVICE_H_ - -#include "platform/platform.h" - -#include "gfx/gfxDevice.h" -#include "gfx/gfxInit.h" - -#include "gfx/gl/tGL/tGL.h" - -#include "windowManager/platformWindow.h" -#include "gfx/gfxFence.h" -#include "gfx/gfxResource.h" -#include "gfx/gl/gfxGLStateBlock.h" - -class GFXGLVertexBuffer; -class GFXGLPrimitiveBuffer; -class GFXGLTextureTarget; -class GFXGLCubemap; -class GFXGLCubemapArray; -class GFXGLStateCache; -class GFXGLVertexDecl; - -class GFXGLDevice : public GFXDevice -{ -public: - struct GLCapabilities - { - bool anisotropicFiltering; - bool bufferStorage; - bool shaderModel5; - bool textureStorage; - bool samplerObjects; - bool copyImage; - bool vertexAttributeBinding; - }; - GLCapabilities mCapabilities; - - void zombify(); - void resurrect(); - GFXGLDevice(U32 adapterIndex); - virtual ~GFXGLDevice(); - - static void enumerateAdapters( Vector &adapterList ); - static GFXDevice *createInstance( U32 adapterIndex ); - - virtual void init( const GFXVideoMode &mode, PlatformWindow *window = NULL ); - - virtual void activate() { } - virtual void deactivate() { } - virtual GFXAdapterType getAdapterType() { return OpenGL; } - - virtual void enterDebugEvent(ColorI color, const char *name); - virtual void leaveDebugEvent(); - virtual void setDebugMarker(ColorI color, const char *name); - - virtual void enumerateVideoModes(); - - virtual U32 getTotalVideoMemory_GL_EXT(); - virtual U32 getTotalVideoMemory(); - - virtual GFXCubemap * createCubemap(); - virtual GFXCubemapArray *createCubemapArray(); - - virtual F32 getFillConventionOffset() const { return 0.0f; } - - - ///@} - - /// @name Render Target functions - /// @{ - - /// - virtual GFXTextureTarget *allocRenderToTextureTarget(bool genMips = true); - virtual GFXWindowTarget *allocWindowTarget(PlatformWindow *window); - virtual void _updateRenderTargets(); - - ///@} - - /// @name Shader functions - /// @{ - virtual F32 getPixelShaderVersion() const { return mPixelShaderVersion; } - virtual void setPixelShaderVersion( F32 version ) { mPixelShaderVersion = version; } - - virtual void setShader(GFXShader *shader, bool force = false); - - /// @attention GL cannot check if the given format supports blending or filtering! - virtual GFXFormat selectSupportedFormat(GFXTextureProfile *profile, - const Vector &formats, bool texture, bool mustblend, bool mustfilter); - - /// Returns the number of texture samplers that can be used in a shader rendering pass - virtual U32 getNumSamplers() const; - - /// Returns the number of simultaneous render targets supported by the device. - virtual U32 getNumRenderTargets() const; - - virtual GFXShader* createShader(); - - virtual void clear( U32 flags, const LinearColorF& color, F32 z, U32 stencil ); - virtual void clearColorAttachment(const U32 attachment, const LinearColorF& color); - virtual bool beginSceneInternal(); - virtual void endSceneInternal(); - - virtual void drawPrimitive( GFXPrimitiveType primType, U32 vertexStart, U32 primitiveCount ); - - virtual void drawIndexedPrimitive( GFXPrimitiveType primType, - U32 startVertex, - U32 minIndex, - U32 numVerts, - U32 startIndex, - U32 primitiveCount ); - - virtual void setClipRect( const RectI &rect ); - virtual const RectI &getClipRect() const { return mClip; } - - virtual void preDestroy() { Parent::preDestroy(); } - - virtual U32 getMaxDynamicVerts() { return MAX_DYNAMIC_VERTS; } - virtual U32 getMaxDynamicIndices() { return MAX_DYNAMIC_INDICES; } - - GFXFence *createFence(); - - GFXOcclusionQuery* createOcclusionQuery(); - - GFXGLStateBlockRef getCurrentStateBlock() { return mCurrentGLStateBlock; } - - virtual void setupGenericShaders( GenericShaderType type = GSColor ); - - /// - bool supportsAnisotropic() const { return mSupportsAnisotropic; } - - GFXGLStateCache* getOpenglCache() { return mOpenglStateCache; } - - GFXTextureObject* getDefaultDepthTex() const; - - /// Returns the number of vertex streams supported by the device. - const U32 getNumVertexStreams() const { return mNumVertexStream; } - - bool glUseMap() const { return mUseGlMap; } - -protected: - /// Called by GFXDevice to create a device specific stateblock - virtual GFXStateBlockRef createStateBlockInternal(const GFXStateBlockDesc& desc); - /// Called by GFXDevice to actually set a stateblock. - virtual void setStateBlockInternal(GFXStateBlock* block, bool force); - - /// Called by base GFXDevice to actually set a const buffer - virtual void setShaderConstBufferInternal(GFXShaderConstBuffer* buffer); - - virtual void setTextureInternal(U32 textureUnit, const GFXTextureObject*texture); - virtual void setCubemapInternal(U32 textureUnit, const GFXGLCubemap* texture); - virtual void setCubemapArrayInternal(U32 textureUnit, const GFXGLCubemapArray* texture); - - virtual void setLightInternal(U32 lightStage, const GFXLightInfo light, bool lightEnable); - virtual void setLightMaterialInternal(const GFXLightMaterial mat); - virtual void setGlobalAmbientInternal(LinearColorF color); - - /// @name State Initalization. - /// @{ - - /// State initalization. This MUST BE CALLED in setVideoMode after the device - /// is created. - virtual void initStates() { } - - virtual void setMatrix( GFXMatrixType mtype, const MatrixF &mat ); - - virtual GFXVertexBuffer *allocVertexBuffer( U32 numVerts, - const GFXVertexFormat *vertexFormat, - U32 vertSize, - GFXBufferType bufferType, - void* data = NULL); - virtual GFXPrimitiveBuffer *allocPrimitiveBuffer( U32 numIndices, U32 numPrimitives, GFXBufferType bufferType, void* data = NULL ); - - // NOTE: The GL device doesn't need a vertex declaration at - // this time, but we need to return something to keep the system - // from retrying to allocate one on every call. - virtual GFXVertexDecl* allocVertexDecl( const GFXVertexFormat *vertexFormat ); - - virtual void setVertexDecl( const GFXVertexDecl *decl ); - - virtual void setVertexStream( U32 stream, GFXVertexBuffer *buffer ); - virtual void setVertexStreamFrequency( U32 stream, U32 frequency ); - -private: - typedef GFXDevice Parent; - - friend class GFXGLTextureObject; - friend class GFXGLCubemap; - friend class GFXGLCubemapArray; - friend class GFXGLWindowTarget; - friend class GFXGLPrimitiveBuffer; - friend class GFXGLVertexBuffer; - - static GFXAdapter::CreateDeviceInstanceDelegate mCreateDeviceInstance; - - U32 mAdapterIndex; - - StrongRefPtr mCurrentVB[VERTEX_STREAM_COUNT]; - U32 mCurrentVB_Divisor[VERTEX_STREAM_COUNT]; - bool mNeedUpdateVertexAttrib; - StrongRefPtr mCurrentPB; - U32 mDrawInstancesCount; - - GFXShader* mCurrentShader; - GFXShaderRef mGenericShader[GS_COUNT]; - GFXShaderConstBufferRef mGenericShaderBuffer[GS_COUNT]; - GFXShaderConstHandle *mModelViewProjSC[GS_COUNT]; - - /// Since GL does not have separate world and view matrices we need to track them - MatrixF m_mCurrentWorld; - MatrixF m_mCurrentView; - - void* mContext; - void* mPixelFormat; - - F32 mPixelShaderVersion; - - bool mSupportsAnisotropic; - - U32 mNumVertexStream; - - U32 mMaxShaderTextures; - U32 mMaxFFTextures; - - U32 mMaxTRColors; - - RectI mClip; - - GFXGLStateBlockRef mCurrentGLStateBlock; - - GLenum mActiveTextureType[TEXTURE_STAGE_COUNT]; - - Vector< StrongRefPtr > mVolatileVBs; ///< Pool of existing volatile VBs so we can reuse previously created ones - Vector< StrongRefPtr > mVolatilePBs; ///< Pool of existing volatile PBs so we can reuse previously created ones - - GLsizei primCountToIndexCount(GFXPrimitiveType primType, U32 primitiveCount); - void preDrawPrimitive(); - void postDrawPrimitive(U32 primitiveCount); - - GFXVertexBuffer* findVolatileVBO(U32 numVerts, const GFXVertexFormat *vertexFormat, U32 vertSize); ///< Returns an existing volatile VB which has >= numVerts and the same vert flags/size, or creates a new VB if necessary - GFXPrimitiveBuffer* findVolatilePBO(U32 numIndices, U32 numPrimitives); ///< Returns an existing volatile PB which has >= numIndices, or creates a new PB if necessary - - void vsyncCallback(); ///< Vsync callback - - void initGLState(); ///< Guaranteed to be called after all extensions have been loaded, use to init card profiler, shader version, max samplers, etc. - - GFXFence* _createPlatformSpecificFence(); ///< If our platform (e.g. OS X) supports a fence extenstion (e.g. GL_APPLE_fence) this will create one, otherwise returns NULL - - void setPB(GFXGLPrimitiveBuffer* pb); ///< Sets mCurrentPB - - GFXGLStateCache *mOpenglStateCache; - - GFXWindowTargetRef *mWindowRT; - - bool mUseGlMap; -}; - -#define GFXGL static_cast(GFXDevice::get()) -#endif diff --git a/gl/gfxGLShader.cpp b/gl/gfxGLShader.cpp deleted file mode 100644 index a5079756f..000000000 --- a/gl/gfxGLShader.cpp +++ /dev/null @@ -1,1151 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#include "platform/platform.h" -#include "gfx/gl/gfxGLShader.h" -#include "gfx/gl/gfxGLVertexAttribLocation.h" -#include "gfx/gl/gfxGLDevice.h" - -#include "core/frameAllocator.h" -#include "core/stream/fileStream.h" -#include "core/strings/stringFunctions.h" -#include "math/mPoint2.h" -#include "gfx/gfxStructs.h" -#include "console/console.h" - -#define CHECK_AARG(pos, name) static StringTableEntry attr_##name = StringTable->insert(#name); if (argName == attr_##name) { glBindAttribLocation(mProgram, pos, attr_##name); continue; } - -class GFXGLShaderConstHandle : public GFXShaderConstHandle -{ - friend class GFXGLShader; - -public: - - GFXGLShaderConstHandle( GFXGLShader *shader ); - GFXGLShaderConstHandle( GFXGLShader *shader, const GFXShaderConstDesc &desc, GLuint loc, S32 samplerNum ); - virtual ~GFXGLShaderConstHandle(); - - void reinit( const GFXShaderConstDesc &desc, GLuint loc, S32 samplerNum ); - - const String& getName() const { return mDesc.name; } - GFXShaderConstType getType() const { return mDesc.constType; } - U32 getArraySize() const { return mDesc.arraySize; } - - U32 getSize() const; - void setValid( bool valid ) { mValid = valid; } - /// @warning This will always return the value assigned when the shader was - /// initialized. If the value is later changed this method won't reflect that. - S32 getSamplerRegister() const { return mSamplerNum; } - - GFXShaderConstDesc mDesc; - GFXGLShader* mShader; - GLuint mLocation; - U32 mOffset; - U32 mSize; - S32 mSamplerNum; - bool mInstancingConstant; -}; - -GFXGLShaderConstHandle::GFXGLShaderConstHandle( GFXGLShader *shader ) - : mShader( shader ), mLocation(0), mOffset(0), mSize(0), mSamplerNum(-1), mInstancingConstant(false) -{ - mValid = false; -} - -static U32 shaderConstTypeSize(GFXShaderConstType type) -{ - switch(type) - { - case GFXSCT_Float: - case GFXSCT_Int: - case GFXSCT_Sampler: - case GFXSCT_SamplerCube: - case GFXSCT_SamplerCubeArray: - return 4; - case GFXSCT_Float2: - case GFXSCT_Int2: - return 8; - case GFXSCT_Float3: - case GFXSCT_Int3: - return 12; - case GFXSCT_Float4: - case GFXSCT_Int4: - return 16; - case GFXSCT_Float2x2: - return 16; - case GFXSCT_Float3x3: - return 36; - case GFXSCT_Float4x3: - return 48; - case GFXSCT_Float4x4: - return 64; - default: - AssertFatal(false,"shaderConstTypeSize - Unrecognized constant type"); - return 0; - } -} - -GFXGLShaderConstHandle::GFXGLShaderConstHandle( GFXGLShader *shader, const GFXShaderConstDesc &desc, GLuint loc, S32 samplerNum ) - : mShader(shader), mInstancingConstant(false) -{ - reinit(desc, loc, samplerNum); -} - -void GFXGLShaderConstHandle::reinit( const GFXShaderConstDesc& desc, GLuint loc, S32 samplerNum ) -{ - mDesc = desc; - mLocation = loc; - mSamplerNum = samplerNum; - mOffset = 0; - mInstancingConstant = false; - - U32 elemSize = shaderConstTypeSize(mDesc.constType); - AssertFatal(elemSize, "GFXGLShaderConst::GFXGLShaderConst - elemSize is 0"); - mSize = mDesc.arraySize * elemSize; - mValid = true; -} - - -U32 GFXGLShaderConstHandle::getSize() const -{ - return mSize; -} - -GFXGLShaderConstHandle::~GFXGLShaderConstHandle() -{ -} - -GFXGLShaderConstBuffer::GFXGLShaderConstBuffer(GFXGLShader* shader, U32 bufSize, U8* existingConstants) -{ - mShader = shader; - mBuffer = new U8[bufSize]; - mWasLost = true; - - // Copy the existing constant buffer to preserve sampler numbers - /// @warning This preserves a lot more than sampler numbers, obviously. If there - /// is any code that assumes a new constant buffer will have everything set to - /// 0, it will break. - dMemcpy(mBuffer, existingConstants, bufSize); -} - -GFXGLShaderConstBuffer::~GFXGLShaderConstBuffer() -{ - delete[] mBuffer; - - if ( mShader ) - mShader->_unlinkBuffer( this ); -} - -template -void GFXGLShaderConstBuffer::internalSet(GFXShaderConstHandle* handle, const ConstType& param) -{ - AssertFatal(handle, "GFXGLShaderConstBuffer::internalSet - Handle is NULL!" ); - AssertFatal(handle->isValid(), "GFXGLShaderConstBuffer::internalSet - Handle is not valid!" ); - AssertFatal(dynamic_cast(handle), "GFXGLShaderConstBuffer::set - Incorrect const buffer type"); - - GFXGLShaderConstHandle* _glHandle = static_cast(handle); - AssertFatal(mShader == _glHandle->mShader, "GFXGLShaderConstBuffer::set - Should only set handles which are owned by our shader"); - U8 *buf = mBuffer + _glHandle->mOffset; - - if(_glHandle->mInstancingConstant) - buf = mInstPtr + _glHandle->mOffset; - - dMemcpy(buf, ¶m, sizeof(ConstType)); -} - -void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const F32 fv) -{ - internalSet(handle, fv); -} - -void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const Point2F& fv) -{ - internalSet(handle, fv); -} - -void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const Point3F& fv) -{ - internalSet(handle, fv); -} - -void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const Point4F& fv) -{ - internalSet(handle, fv); -} - -void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const PlaneF& fv) -{ - internalSet(handle, fv); -} - -void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const LinearColorF& fv) -{ - internalSet(handle, fv); -} - -void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const S32 fv) -{ - internalSet(handle, fv); -} - -void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const Point2I& fv) -{ - internalSet(handle, fv); -} - -void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const Point3I& fv) -{ - internalSet(handle, fv); -} - -void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const Point4I& fv) -{ - internalSet(handle, fv); -} - -template -void GFXGLShaderConstBuffer::internalSet(GFXShaderConstHandle* handle, const AlignedArray& fv) -{ - AssertFatal(handle, "GFXGLShaderConstBuffer::internalSet - Handle is NULL!" ); - AssertFatal(handle->isValid(), "GFXGLShaderConstBuffer::internalSet - Handle is not valid!" ); - AssertFatal(dynamic_cast(handle), "GFXGLShaderConstBuffer::set - Incorrect const buffer type"); - - GFXGLShaderConstHandle* _glHandle = static_cast(handle); - AssertFatal(mShader == _glHandle->mShader, "GFXGLShaderConstBuffer::set - Should only set handles which are owned by our shader"); - AssertFatal(!_glHandle->mInstancingConstant, "GFXGLShaderConstBuffer::set - Instancing not supported for array"); - const U8* fvBuffer = static_cast(fv.getBuffer()); - for(U32 i = 0; i < fv.size(); ++i) - { - dMemcpy(mBuffer + _glHandle->mOffset + i * sizeof(ConstType), fvBuffer, sizeof(ConstType)); - fvBuffer += fv.getElementSize(); - } -} - -void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const AlignedArray& fv) -{ - internalSet(handle, fv); -} - -void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const AlignedArray& fv) -{ - internalSet(handle, fv); -} - -void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const AlignedArray& fv) -{ - internalSet(handle, fv); -} - -void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const AlignedArray& fv) -{ - internalSet(handle, fv); -} - -void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const AlignedArray& fv) -{ - internalSet(handle, fv); -} - -void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const AlignedArray& fv) -{ - internalSet(handle, fv); -} - -void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const AlignedArray& fv) -{ - internalSet(handle, fv); -} - -void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const AlignedArray& fv) -{ - internalSet(handle, fv); -} - -void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const MatrixF& mat, const GFXShaderConstType matType) -{ - AssertFatal(handle, "GFXGLShaderConstBuffer::set - Handle is NULL!" ); - AssertFatal(handle->isValid(), "GFXGLShaderConstBuffer::set - Handle is not valid!" ); - AssertFatal(dynamic_cast(handle), "GFXGLShaderConstBuffer::set - Incorrect const buffer type"); - - GFXGLShaderConstHandle* _glHandle = static_cast(handle); - AssertFatal(mShader == _glHandle->mShader, "GFXGLShaderConstBuffer::set - Should only set handles which are owned by our shader"); - AssertFatal(!_glHandle->mInstancingConstant || matType == GFXSCT_Float4x4, "GFXGLShaderConstBuffer::set - Only support GFXSCT_Float4x4 for instancing"); - - switch(matType) - { - case GFXSCT_Float2x2: - reinterpret_cast(mBuffer + _glHandle->mOffset)[0] = mat[0]; - reinterpret_cast(mBuffer + _glHandle->mOffset)[1] = mat[1]; - reinterpret_cast(mBuffer + _glHandle->mOffset)[2] = mat[4]; - reinterpret_cast(mBuffer + _glHandle->mOffset)[3] = mat[5]; - break; - case GFXSCT_Float3x3: - reinterpret_cast(mBuffer + _glHandle->mOffset)[0] = mat[0]; - reinterpret_cast(mBuffer + _glHandle->mOffset)[1] = mat[1]; - reinterpret_cast(mBuffer + _glHandle->mOffset)[2] = mat[2]; - reinterpret_cast(mBuffer + _glHandle->mOffset)[3] = mat[4]; - reinterpret_cast(mBuffer + _glHandle->mOffset)[4] = mat[5]; - reinterpret_cast(mBuffer + _glHandle->mOffset)[5] = mat[6]; - reinterpret_cast(mBuffer + _glHandle->mOffset)[6] = mat[8]; - reinterpret_cast(mBuffer + _glHandle->mOffset)[7] = mat[9]; - reinterpret_cast(mBuffer + _glHandle->mOffset)[8] = mat[10]; - break; - case GFXSCT_Float4x3: - dMemcpy(mBuffer + _glHandle->mOffset, (const F32*)mat, (sizeof(F32) * 12));// matrix with end row chopped off - break; - case GFXSCT_Float4x4: - { - if(_glHandle->mInstancingConstant) - { - MatrixF transposed; - mat.transposeTo(transposed); - dMemcpy( mInstPtr + _glHandle->mOffset, (const F32*)transposed, sizeof(MatrixF) ); - return; - } - - dMemcpy(mBuffer + _glHandle->mOffset, (const F32*)mat, sizeof(MatrixF)); - break; - } - default: - AssertFatal(false, "GFXGLShaderConstBuffer::set - Invalid matrix type"); - break; - } -} - -void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const MatrixF* mat, const U32 arraySize, const GFXShaderConstType matrixType) -{ - AssertFatal(handle, "GFXGLShaderConstBuffer::set - Handle is NULL!" ); - AssertFatal(handle->isValid(), "GFXGLShaderConstBuffer::set - Handle is not valid!" ); - - GFXGLShaderConstHandle* _glHandle = static_cast(handle); - AssertFatal(mShader == _glHandle->mShader, "GFXGLShaderConstBuffer::set - Should only set handles which are owned by our shader"); - AssertFatal(!_glHandle->mInstancingConstant, "GFXGLShaderConstBuffer::set - Instancing not supported for matrix arrays"); - - switch (matrixType) { - case GFXSCT_Float4x3: - // Copy each item with the last row chopped off - for (int i = 0; imOffset + (i*(sizeof(F32) * 12)), (F32*)(mat + i), sizeof(F32) * 12); - } - break; - case GFXSCT_Float4x4: - dMemcpy(mBuffer + _glHandle->mOffset, (F32*)mat, _glHandle->getSize()); - break; - default: - AssertFatal(false, "GFXGLShaderConstBuffer::set - setting array of non 4x4 matrices!"); - break; - } -} - -void GFXGLShaderConstBuffer::activate() -{ - PROFILE_SCOPE(GFXGLShaderConstBuffer_activate); - mShader->setConstantsFromBuffer(this); - mWasLost = false; -} - -const String GFXGLShaderConstBuffer::describeSelf() const -{ - return String(); -} - -void GFXGLShaderConstBuffer::onShaderReload( GFXGLShader *shader ) -{ - AssertFatal( shader == mShader, "GFXGLShaderConstBuffer::onShaderReload, mismatched shaders!" ); - - delete[] mBuffer; - mBuffer = new U8[mShader->mConstBufferSize]; - dMemset(mBuffer, 0, mShader->mConstBufferSize); - mWasLost = true; -} - -GFXGLShader::GFXGLShader() : - mVertexShader(0), - mPixelShader(0), - mProgram(0), - mConstBufferSize(0), - mConstBuffer(NULL) -{ -} - -GFXGLShader::~GFXGLShader() -{ - clearShaders(); - for(HandleMap::Iterator i = mHandles.begin(); i != mHandles.end(); i++) - delete i->value; - - delete[] mConstBuffer; -} - -void GFXGLShader::clearShaders() -{ - glDeleteProgram(mProgram); - glDeleteShader(mVertexShader); - glDeleteShader(mPixelShader); - - mProgram = 0; - mVertexShader = 0; - mPixelShader = 0; -} - -bool GFXGLShader::_init() -{ - PROFILE_SCOPE(GFXGLShader_Init); - // Don't initialize empty shaders. - if ( mVertexFile.isEmpty() && mPixelFile.isEmpty() ) - return false; - - clearShaders(); - - mProgram = glCreateProgram(); - - // Set the macros and add the global ones. - Vector macros; - macros.merge( mMacros ); - macros.merge( smGlobalMacros ); - - macros.increment(); - macros.last().name = "TORQUE_SM"; - macros.last().value = 40; - macros.increment(); - macros.last().name = "TORQUE_VERTEX_SHADER"; - macros.last().value = ""; - - // Default to true so we're "successful" if a vertex/pixel shader wasn't specified. - bool compiledVertexShader = true; - bool compiledPixelShader = true; - - // Compile the vertex and pixel shaders if specified. - if(!mVertexFile.isEmpty()) - compiledVertexShader = initShader(mVertexFile, true, macros); - - macros.last().name = "TORQUE_PIXEL_SHADER"; - if(!mPixelFile.isEmpty()) - compiledPixelShader = initShader(mPixelFile, false, macros); - - // If either shader was present and failed to compile, bail. - if(!compiledVertexShader || !compiledPixelShader) - return false; - - // Link it! - glLinkProgram( mProgram ); - - GLint activeAttribs = 0; - glGetProgramiv(mProgram, GL_ACTIVE_ATTRIBUTES, &activeAttribs ); - - GLint maxLength; - glGetProgramiv(mProgram, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxLength); - - FrameTemp tempData(maxLength+1); - *tempData.address() = '\0'; - // Check atributes - for (U32 i=0; iinsert(tempData.address()); - - CHECK_AARG(Torque::GL_VertexAttrib_Position, vPosition); - CHECK_AARG(Torque::GL_VertexAttrib_Normal, vNormal); - CHECK_AARG(Torque::GL_VertexAttrib_Color, vColor); - CHECK_AARG(Torque::GL_VertexAttrib_Tangent, vTangent); - CHECK_AARG(Torque::GL_VertexAttrib_TangentW, vTangentW); - CHECK_AARG(Torque::GL_VertexAttrib_Binormal, vBinormal); - CHECK_AARG(Torque::GL_VertexAttrib_TexCoord0, vTexCoord0); - CHECK_AARG(Torque::GL_VertexAttrib_TexCoord1, vTexCoord1); - CHECK_AARG(Torque::GL_VertexAttrib_TexCoord2, vTexCoord2); - CHECK_AARG(Torque::GL_VertexAttrib_TexCoord3, vTexCoord3); - CHECK_AARG(Torque::GL_VertexAttrib_TexCoord4, vTexCoord4); - CHECK_AARG(Torque::GL_VertexAttrib_TexCoord5, vTexCoord5); - CHECK_AARG(Torque::GL_VertexAttrib_TexCoord6, vTexCoord6); - CHECK_AARG(Torque::GL_VertexAttrib_TexCoord7, vTexCoord7); - CHECK_AARG(Torque::GL_VertexAttrib_TexCoord8, vTexCoord8); - CHECK_AARG(Torque::GL_VertexAttrib_TexCoord9, vTexCoord9); - } - - //always have OUT_col - glBindFragDataLocation(mProgram, 0, "OUT_col"); - // Check OUT_colN - for(U32 i=1;i<4;i++) - { - char buffer[10]; - dSprintf(buffer, sizeof(buffer), "OUT_col%u",i); - GLint location = glGetFragDataLocation(mProgram, buffer); - if(location>0) - glBindFragDataLocation(mProgram, i, buffer); - - } - - // Link it again! - glLinkProgram( mProgram ); - - GLint linkStatus; - glGetProgramiv( mProgram, GL_LINK_STATUS, &linkStatus ); - - // Dump the info log to the console - U32 logLength = 0; - glGetProgramiv(mProgram, GL_INFO_LOG_LENGTH, (GLint*)&logLength); - if ( logLength ) - { - FrameAllocatorMarker fam; - char* log = (char*)fam.alloc( logLength ); - glGetProgramInfoLog( mProgram, logLength, NULL, log ); - - if ( linkStatus == GL_FALSE ) - { - if ( smLogErrors ) - { - Con::errorf( "GFXGLShader::init - Error linking shader!" ); - Con::errorf( "Program %s / %s: %s", - mVertexFile.getFullPath().c_str(), mPixelFile.getFullPath().c_str(), log); - } - } - else if ( smLogWarnings ) - { - Con::warnf( "Program %s / %s: %s", - mVertexFile.getFullPath().c_str(), mPixelFile.getFullPath().c_str(), log); - } - } - - - // If we failed to link, bail. - if ( linkStatus == GL_FALSE ) - return false; - - initConstantDescs(); - initHandles(); - - // Notify Buffers we might have changed in size. - // If this was our first init then we won't have any activeBuffers - // to worry about unnecessarily calling. - Vector::iterator biter = mActiveBuffers.begin(); - for ( ; biter != mActiveBuffers.end(); biter++ ) - ((GFXGLShaderConstBuffer*)(*biter))->onShaderReload( this ); - - return true; -} - - -void GFXGLShader::initConstantDescs() -{ - mConstants.clear(); - GLint numUniforms; - glGetProgramiv(mProgram, GL_ACTIVE_UNIFORMS, &numUniforms); - GLint maxNameLength; - glGetProgramiv(mProgram, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxNameLength); - - if(!maxNameLength) - return; - - FrameTemp uniformName(maxNameLength); - - for(U32 i = 0; i < numUniforms; i++) - { - GLint size; - GLenum type; - glGetActiveUniform(mProgram, i, maxNameLength, NULL, &size, &type, uniformName); - GFXShaderConstDesc desc; - - desc.name = String((char*)uniformName); - - // Remove array brackets from the name - desc.name = desc.name.substr(0, desc.name.find('[')); - - // Insert $ to match D3D behavior of having a $ prepended to parameters to main. - desc.name.insert(0, '$'); - desc.arraySize = size; - - switch(type) - { - case GL_FLOAT: - desc.constType = GFXSCT_Float; - break; - case GL_FLOAT_VEC2: - desc.constType = GFXSCT_Float2; - break; - case GL_FLOAT_VEC3: - desc.constType = GFXSCT_Float3; - break; - case GL_FLOAT_VEC4: - desc.constType = GFXSCT_Float4; - break; - case GL_INT: - desc.constType = GFXSCT_Int; - break; - case GL_INT_VEC2: - desc.constType = GFXSCT_Int2; - break; - case GL_INT_VEC3: - desc.constType = GFXSCT_Int3; - break; - case GL_INT_VEC4: - desc.constType = GFXSCT_Int4; - break; - case GL_FLOAT_MAT2: - desc.constType = GFXSCT_Float2x2; - break; - case GL_FLOAT_MAT3: - desc.constType = GFXSCT_Float3x3; - break; - case GL_FLOAT_MAT4: - desc.constType = GFXSCT_Float4x4; - break; - case GL_FLOAT_MAT4x3: // jamesu - columns, rows - desc.constType = GFXSCT_Float4x3; - break; - case GL_SAMPLER_1D: - case GL_SAMPLER_2D: - case GL_SAMPLER_3D: - case GL_SAMPLER_1D_SHADOW: - case GL_SAMPLER_2D_SHADOW: - desc.constType = GFXSCT_Sampler; - break; - case GL_SAMPLER_CUBE: - desc.constType = GFXSCT_SamplerCube; - break; - case GL_SAMPLER_CUBE_MAP_ARRAY: - desc.constType = GFXSCT_SamplerCubeArray; - break; - default: - AssertFatal(false, "GFXGLShader::initConstantDescs - unrecognized uniform type"); - // If we don't recognize the constant don't add its description. - continue; - } - - mConstants.push_back(desc); - } -} - -void GFXGLShader::initHandles() -{ - // Mark all existing handles as invalid. - // Those that are found when parsing the descriptions will then be marked valid again. - for ( HandleMap::Iterator iter = mHandles.begin(); iter != mHandles.end(); ++iter ) - (iter->value)->setValid( false ); - mValidHandles.clear(); - - // Loop through all ConstantDescriptions, - // if they aren't in the HandleMap add them, if they are reinitialize them. - for ( U32 i = 0; i < mConstants.size(); i++ ) - { - GFXShaderConstDesc &desc = mConstants[i]; - - // Index element 1 of the name to skip the '$' we inserted earier. - GLint loc = glGetUniformLocation(mProgram, &desc.name.c_str()[1]); - - AssertFatal(loc != -1, ""); - - HandleMap::Iterator handle = mHandles.find(desc.name); - S32 sampler = -1; - if(desc.constType == GFXSCT_Sampler || desc.constType == GFXSCT_SamplerCube || desc.constType == GFXSCT_SamplerCubeArray) - { - S32 idx = mSamplerNamesOrdered.find_next(desc.name); - AssertFatal(idx != -1, ""); - sampler = idx; //assignedSamplerNum++; - } - if ( handle != mHandles.end() ) - { - handle->value->reinit( desc, loc, sampler ); - } - else - { - mHandles[desc.name] = new GFXGLShaderConstHandle( this, desc, loc, sampler ); - } - } - - // Loop through handles once more to set their offset and calculate our - // constBuffer size. - - if ( mConstBuffer ) - delete[] mConstBuffer; - mConstBufferSize = 0; - - for ( HandleMap::Iterator iter = mHandles.begin(); iter != mHandles.end(); ++iter ) - { - GFXGLShaderConstHandle* handle = iter->value; - if ( handle->isValid() ) - { - mValidHandles.push_back(handle); - handle->mOffset = mConstBufferSize; - mConstBufferSize += handle->getSize(); - } - } - - mConstBuffer = new U8[mConstBufferSize]; - dMemset(mConstBuffer, 0, mConstBufferSize); - - // Set our program so uniforms are assigned properly. - glUseProgram(mProgram); - // Iterate through uniforms to set sampler numbers. - for (HandleMap::Iterator iter = mHandles.begin(); iter != mHandles.end(); ++iter) - { - GFXGLShaderConstHandle* handle = iter->value; - if(handle->isValid() && (handle->getType() == GFXSCT_Sampler || handle->getType() == GFXSCT_SamplerCube || handle->getType() == GFXSCT_SamplerCubeArray)) - { - // Set sampler number on our program. - glUniform1i(handle->mLocation, handle->mSamplerNum); - // Set sampler in constant buffer so it does not get unset later. - dMemcpy(mConstBuffer + handle->mOffset, &handle->mSamplerNum, handle->getSize()); - } - } - glUseProgram(0); - - //instancing - if (!mInstancingFormat) - return; - - U32 offset = 0; - - for ( U32 i=0; i < mInstancingFormat->getElementCount(); i++ ) - { - const GFXVertexElement &element = mInstancingFormat->getElement( i ); - - String constName = String::ToString( "$%s", element.getSemantic().c_str() ); - - HandleMap::Iterator handle = mHandles.find(constName); - if ( handle != mHandles.end() ) - { - AssertFatal(0, ""); - } - else - { - GFXShaderConstDesc desc; - desc.name = constName; - desc.arraySize = 1; - switch(element.getType()) - { - case GFXDeclType_Float4: - desc.constType = GFXSCT_Float4; - break; - - default: - desc.constType = GFXSCT_Float; - break; - } - - GFXGLShaderConstHandle *h = new GFXGLShaderConstHandle( this, desc, -1, -1 ); - h->mInstancingConstant = true; - h->mOffset = offset; - mHandles[constName] = h; - - offset += element.getSizeInBytes(); - ++i; - - // If this is a matrix we will have 2 or 3 more of these - // semantics with the same name after it. - for ( ; i < mInstancingFormat->getElementCount(); i++ ) - { - const GFXVertexElement &nextElement = mInstancingFormat->getElement( i ); - if ( nextElement.getSemantic() != element.getSemantic() ) - { - i--; - break; - } - ++desc.arraySize; - if(desc.arraySize == 4 && desc.constType == GFXSCT_Float4) - { - desc.arraySize = 1; - desc.constType = GFXSCT_Float4x4; - } - offset += nextElement.getSizeInBytes(); - } - } - - } -} - -GFXShaderConstHandle* GFXGLShader::getShaderConstHandle(const String& name) -{ - HandleMap::Iterator i = mHandles.find(name); - if(i != mHandles.end()) - return i->value; - else - { - GFXGLShaderConstHandle* handle = new GFXGLShaderConstHandle( this ); - mHandles[ name ] = handle; - - return handle; - } -} - -GFXShaderConstHandle* GFXGLShader::findShaderConstHandle(const String& name) -{ - HandleMap::Iterator i = mHandles.find(name); - if(i != mHandles.end()) - return i->value; - else - { - return NULL; - } -} - -void GFXGLShader::setConstantsFromBuffer(GFXGLShaderConstBuffer* buffer) -{ - for(Vector::iterator i = mValidHandles.begin(); i != mValidHandles.end(); ++i) - { - GFXGLShaderConstHandle* handle = *i; - AssertFatal(handle, "GFXGLShader::setConstantsFromBuffer - Null handle"); - - if(handle->mInstancingConstant) - continue; - - // Don't set if the value has not be changed. - if(dMemcmp(mConstBuffer + handle->mOffset, buffer->mBuffer + handle->mOffset, handle->getSize()) == 0) - continue; - - // Copy new value into our const buffer and set in GL. - dMemcpy(mConstBuffer + handle->mOffset, buffer->mBuffer + handle->mOffset, handle->getSize()); - switch(handle->mDesc.constType) - { - case GFXSCT_Float: - glUniform1fv(handle->mLocation, handle->mDesc.arraySize, (GLfloat*)(mConstBuffer + handle->mOffset)); - break; - case GFXSCT_Float2: - glUniform2fv(handle->mLocation, handle->mDesc.arraySize, (GLfloat*)(mConstBuffer + handle->mOffset)); - break; - case GFXSCT_Float3: - glUniform3fv(handle->mLocation, handle->mDesc.arraySize, (GLfloat*)(mConstBuffer + handle->mOffset)); - break; - case GFXSCT_Float4: - glUniform4fv(handle->mLocation, handle->mDesc.arraySize, (GLfloat*)(mConstBuffer + handle->mOffset)); - break; - case GFXSCT_Int: - case GFXSCT_Sampler: - case GFXSCT_SamplerCube: - case GFXSCT_SamplerCubeArray: - glUniform1iv(handle->mLocation, handle->mDesc.arraySize, (GLint*)(mConstBuffer + handle->mOffset)); - break; - case GFXSCT_Int2: - glUniform2iv(handle->mLocation, handle->mDesc.arraySize, (GLint*)(mConstBuffer + handle->mOffset)); - break; - case GFXSCT_Int3: - glUniform3iv(handle->mLocation, handle->mDesc.arraySize, (GLint*)(mConstBuffer + handle->mOffset)); - break; - case GFXSCT_Int4: - glUniform4iv(handle->mLocation, handle->mDesc.arraySize, (GLint*)(mConstBuffer + handle->mOffset)); - break; - case GFXSCT_Float2x2: - glUniformMatrix2fv(handle->mLocation, handle->mDesc.arraySize, true, (GLfloat*)(mConstBuffer + handle->mOffset)); - break; - case GFXSCT_Float3x3: - glUniformMatrix3fv(handle->mLocation, handle->mDesc.arraySize, true, (GLfloat*)(mConstBuffer + handle->mOffset)); - break; - case GFXSCT_Float4x3: - // NOTE: To save a transpose here we could store the matrix transposed (i.e. column major) in the constant buffer. - // See _mesa_uniform_matrix in the mesa source for the correct transpose algorithm for a 4x3 matrix. - glUniformMatrix4x3fv(handle->mLocation, handle->mDesc.arraySize, true, (GLfloat*)(mConstBuffer + handle->mOffset)); - break; - case GFXSCT_Float4x4: - glUniformMatrix4fv(handle->mLocation, handle->mDesc.arraySize, true, (GLfloat*)(mConstBuffer + handle->mOffset)); - break; - default: - AssertFatal(0,""); - break; - } - } -} - -GFXShaderConstBufferRef GFXGLShader::allocConstBuffer() -{ - GFXGLShaderConstBuffer* buffer = new GFXGLShaderConstBuffer(this, mConstBufferSize, mConstBuffer); - buffer->registerResourceWithDevice(getOwningDevice()); - mActiveBuffers.push_back( buffer ); - return buffer; -} - -void GFXGLShader::useProgram() -{ - glUseProgram(mProgram); -} - -void GFXGLShader::zombify() -{ - clearShaders(); - dMemset(mConstBuffer, 0, mConstBufferSize); -} - -char* GFXGLShader::_handleIncludes( const Torque::Path& path, FileStream *s ) -{ - // TODO: The #line pragma on GLSL takes something called a - // "source-string-number" which it then never explains. - // - // Until i resolve this mystery i disabled this. - // - //String linePragma = String::ToString( "#line 1 \r\n"); - //U32 linePragmaLen = linePragma.length(); - - U32 shaderLen = s->getStreamSize(); - char* buffer = (char*)dMalloc(shaderLen + 1); - //dStrncpy( buffer, linePragma.c_str(), linePragmaLen ); - s->read(shaderLen, buffer); - buffer[shaderLen] = 0; - - char* p = dStrstr(buffer, "#include"); - while(p) - { - char* q = p; - p += 8; - if(dIsspace(*p)) - { - U32 n = 0; - while(dIsspace(*p)) ++p; - AssertFatal(*p == '"', "Bad #include directive"); - ++p; - static char includeFile[256]; - while(*p != '"') - { - AssertFatal(*p != 0, "Bad #include directive"); - includeFile[n++] = *p++; - AssertFatal(n < sizeof(includeFile), "#include directive too long"); - } - ++p; - includeFile[n] = 0; - - // First try it as a local file. - Torque::Path includePath = Torque::Path::Join(path.getPath(), '/', includeFile); - includePath = Torque::Path::CompressPath(includePath); - - FileStream includeStream; - - if ( !includeStream.open( includePath, Torque::FS::File::Read ) ) - { - // Try again assuming the path is absolute - // and/or relative. - includePath = String( includeFile ); - includePath = Torque::Path::CompressPath(includePath); - if ( !includeStream.open( includePath, Torque::FS::File::Read ) ) - { - AssertISV(false, avar("failed to open include '%s'.", includePath.getFullPath().c_str())); - - if ( smLogErrors ) - Con::errorf( "GFXGLShader::_handleIncludes - Failed to open include '%s'.", - includePath.getFullPath().c_str() ); - - // Fail... don't return the buffer. - dFree(buffer); - return NULL; - } - } - - char* includedText = _handleIncludes(includePath, &includeStream); - - // If a sub-include fails... cleanup and return. - if ( !includedText ) - { - dFree(buffer); - return NULL; - } - - // TODO: Disabled till this is fixed correctly. - // - // Count the number of lines in the file - // before the include. - /* - U32 includeLine = 0; - { - char* nl = dStrstr( buffer, "\n" ); - while ( nl ) - { - includeLine++; - nl = dStrstr( nl, "\n" ); - if(nl) ++nl; - } - } - */ - - String manip(buffer); - manip.erase(q-buffer, p-q); - String sItx(includedText); - - // TODO: Disabled till this is fixed correctly. - // - // Add a new line pragma to restore the proper - // file and line number after the include. - //sItx += String::ToString( "\r\n#line %d \r\n", includeLine ); - - dFree(includedText); - manip.insert(q-buffer, sItx); - char* manipBuf = dStrdup(manip.c_str()); - p = manipBuf + (q - buffer); - dFree(buffer); - buffer = manipBuf; - } - p = dStrstr(p, "#include"); - } - - return buffer; -} - -bool GFXGLShader::_loadShaderFromStream( GLuint shader, - const Torque::Path &path, - FileStream *s, - const Vector ¯os ) -{ - Vector buffers; - Vector lengths; - - // The GLSL version declaration must go first! - const char *versionDecl = "#version 150\r\n"; - buffers.push_back( dStrdup( versionDecl ) ); - lengths.push_back( dStrlen( versionDecl ) ); - - if(GFXGL->mCapabilities.shaderModel5) - { - const char *extension = "#extension GL_ARB_gpu_shader5 : enable\r\n"; - buffers.push_back( dStrdup( extension ) ); - lengths.push_back( dStrlen( extension ) ); - } - - const char *newLine = "\r\n"; - buffers.push_back( dStrdup( newLine ) ); - lengths.push_back( dStrlen( newLine ) ); - - // Now add all the macros. - for( U32 i = 0; i < macros.size(); i++ ) - { - if(macros[i].name.isEmpty()) // TODO OPENGL - continue; - - String define = String::ToString( "#define %s %s\n", macros[i].name.c_str(), macros[i].value.c_str() ); - buffers.push_back( dStrdup( define.c_str() ) ); - lengths.push_back( define.length() ); - } - - // Now finally add the shader source. - U32 shaderLen = s->getStreamSize(); - char *buffer = _handleIncludes(path, s); - if ( !buffer ) - return false; - - buffers.push_back(buffer); - lengths.push_back(shaderLen); - - glShaderSource(shader, buffers.size(), (const GLchar**)const_cast(buffers.address()), NULL); - -#if defined(TORQUE_DEBUG) && defined(TORQUE_DEBUG_GFX) - FileStream stream; - if ( !stream.open( path.getFullPath()+"_DEBUG", Torque::FS::File::Write ) ) - { - AssertISV(false, avar("GFXGLShader::initShader - failed to write debug shader '%s'.", path.getFullPath().c_str())); - } - - for(int i = 0; i < buffers.size(); ++i) - stream.writeText(buffers[i]); -#endif - - // Cleanup the shader source buffer. - for ( U32 i=0; i < buffers.size(); i++ ) - dFree( buffers[i] ); - - glCompileShader(shader); - - return true; -} - -bool GFXGLShader::initShader( const Torque::Path &file, - bool isVertex, - const Vector ¯os ) -{ - PROFILE_SCOPE(GFXGLShader_CompileShader); - GLuint activeShader = glCreateShader(isVertex ? GL_VERTEX_SHADER : GL_FRAGMENT_SHADER); - if(isVertex) - mVertexShader = activeShader; - else - mPixelShader = activeShader; - glAttachShader(mProgram, activeShader); - - - // Ok it's not in the shader gen manager, so ask Torque for it - FileStream stream; - if ( !stream.open( file, Torque::FS::File::Read ) ) - { - AssertISV(false, avar("GFXGLShader::initShader - failed to open shader '%s'.", file.getFullPath().c_str())); - - if ( smLogErrors ) - Con::errorf( "GFXGLShader::initShader - Failed to open shader file '%s'.", - file.getFullPath().c_str() ); - - return false; - } - - if ( !_loadShaderFromStream( activeShader, file, &stream, macros ) ) - return false; - - GLint compile; - glGetShaderiv(activeShader, GL_COMPILE_STATUS, &compile); - - // Dump the info log to the console - U32 logLength = 0; - glGetShaderiv(activeShader, GL_INFO_LOG_LENGTH, (GLint*)&logLength); - - GLint compileStatus = GL_TRUE; - if ( logLength ) - { - FrameAllocatorMarker fam; - char* log = (char*)fam.alloc(logLength); - glGetShaderInfoLog(activeShader, logLength, NULL, log); - - // Always print errors - glGetShaderiv( activeShader, GL_COMPILE_STATUS, &compileStatus ); - - if ( compileStatus == GL_FALSE ) - { - if ( smLogErrors ) - { - Con::errorf( "GFXGLShader::initShader - Error compiling shader!" ); - Con::errorf( "Program %s: %s", file.getFullPath().c_str(), log ); - } - } - else if ( smLogWarnings ) - Con::warnf( "Program %s: %s", file.getFullPath().c_str(), log ); - } - - return compileStatus != GL_FALSE; -} - -/// Returns our list of shader constants, the material can get this and just set the constants it knows about -const Vector& GFXGLShader::getShaderConstDesc() const -{ - PROFILE_SCOPE(GFXGLShader_GetShaderConstants); - return mConstants; -} - -/// Returns the alignment value for constType -U32 GFXGLShader::getAlignmentValue(const GFXShaderConstType constType) const -{ - // Alignment is the same thing as size for us. - return shaderConstTypeSize(constType); -} - -const String GFXGLShader::describeSelf() const -{ - String ret; - ret = String::ToString(" Program: %i", mProgram); - ret += String::ToString(" Vertex Path: %s", mVertexFile.getFullPath().c_str()); - ret += String::ToString(" Pixel Path: %s", mPixelFile.getFullPath().c_str()); - - return ret; -} diff --git a/gl/gfxGLStateCache.h b/gl/gfxGLStateCache.h deleted file mode 100644 index 24b3179e4..000000000 --- a/gl/gfxGLStateCache.h +++ /dev/null @@ -1,141 +0,0 @@ -#ifndef GFX_GL_STATE_CACHE -#define GFX_GL_STATE_CACHE - - -/// GFXGLStateCache store OpenGL state to avoid performance penalities of glGet* calls -/// GL_TEXTURE_1D/2D/3D, GL_FRAMEBUFFER, GL_ARRAY_BUFFER, GL_ELEMENT_ARRAY_BUFFER -class GFXGLStateCache -{ -public: - GFXGLStateCache() - { - mActiveTexture = 0; - mBindedVBO = 0; - mBindedIBO = 0; - mBindedFBO_W = 0; - mBindedFBO_R = 0; - mVertexAttribActive = 0; - } - - class TextureUnit - { - public: - TextureUnit() : mTexture1D(0), mTexture2D(0), mTexture3D(0), mTextureCube(0), mTextureCubeArray(0) - { - - } - GLuint mTexture1D, mTexture2D, mTexture3D, mTextureCube, mTextureCubeArray; - }; - - /// after glBindTexture - void setCacheBindedTex(U32 texUnit, GLenum biding, GLuint handle) - { - mActiveTexture = texUnit; - switch (biding) - { - case GL_TEXTURE_2D: - mTextureUnits[mActiveTexture].mTexture2D = handle; - break; - case GL_TEXTURE_3D: - mTextureUnits[mActiveTexture].mTexture3D = handle; - break; - case GL_TEXTURE_1D: - mTextureUnits[mActiveTexture].mTexture1D = handle; - break; - case GL_TEXTURE_CUBE_MAP: - mTextureUnits[mActiveTexture].mTextureCube = handle; - break; - case GL_TEXTURE_CUBE_MAP_ARRAY: - mTextureUnits[mActiveTexture].mTextureCubeArray = handle; - break; - default: - AssertFatal(0, avar("GFXGLStateCache::setCacheBindedTex - binding (%x) not supported.", biding) ); - return; - } - } - - /// after opengl object binded - void setCacheBinded(GLenum biding, GLuint handle) - { - switch (biding) - { - case GL_TEXTURE_2D: - mTextureUnits[mActiveTexture].mTexture2D = handle; - break; - case GL_TEXTURE_3D: - mTextureUnits[mActiveTexture].mTexture3D = handle; - break; - case GL_TEXTURE_1D: - mTextureUnits[mActiveTexture].mTexture1D = handle; - break; - case GL_TEXTURE_CUBE_MAP: - mTextureUnits[mActiveTexture].mTextureCube = handle; - break; - case GL_TEXTURE_CUBE_MAP_ARRAY: - mTextureUnits[mActiveTexture].mTextureCubeArray = handle; - break; - case GL_FRAMEBUFFER: - mBindedFBO_W = mBindedFBO_R = handle; - break; - case GL_DRAW_FRAMEBUFFER: - mBindedFBO_W = handle; - break; - case GL_READ_FRAMEBUFFER: - mBindedFBO_R = handle; - break; - case GL_ARRAY_BUFFER: - mBindedVBO = handle; - break; - case GL_ELEMENT_ARRAY_BUFFER: - mBindedIBO = handle; - break; - default: - AssertFatal(0, avar("GFXGLStateCache::setCacheBinded - binding (%x) not supported.", biding) ); - break; - } - } - - GLuint getCacheBinded(GLenum biding) const - { - switch (biding) - { - case GL_TEXTURE_2D: - return mTextureUnits[mActiveTexture].mTexture2D; - case GL_TEXTURE_3D: - return mTextureUnits[mActiveTexture].mTexture3D; - case GL_TEXTURE_1D: - return mTextureUnits[mActiveTexture].mTexture1D; - case GL_TEXTURE_CUBE_MAP: - return mTextureUnits[mActiveTexture].mTextureCube; - case GL_TEXTURE_CUBE_MAP_ARRAY: - return mTextureUnits[mActiveTexture].mTextureCubeArray; - case GL_DRAW_FRAMEBUFFER: - return mBindedFBO_W; - case GL_READ_FRAMEBUFFER: - return mBindedFBO_R; - case GL_ARRAY_BUFFER: - return mBindedVBO; - case GL_ELEMENT_ARRAY_BUFFER: - return mBindedIBO; - default: - AssertFatal(0, avar("GFXGLStateCache::getCacheBinded - binding (%x) not supported.", biding) ); - return 0; - } - } - - /// after glActiveTexture - void setCacheActiveTexture(U32 unit) { mActiveTexture = unit; } - U32 getCacheActiveTexture() const { return mActiveTexture; } - - /// for cache glEnableVertexAttribArray / glDisableVertexAttribArray - void setCacheVertexAttribActive(U32 activeMask) { mVertexAttribActive = activeMask; } - U32 getCacheVertexAttribActive() const { return mVertexAttribActive; } - -protected: - GLuint mActiveTexture, mBindedVBO, mBindedIBO, mBindedFBO_W, mBindedFBO_R; - TextureUnit mTextureUnits[TEXTURE_STAGE_COUNT]; - U32 mVertexAttribActive; -}; - - -#endif \ No newline at end of file diff --git a/gl/gfxGLUtils.h b/gl/gfxGLUtils.h deleted file mode 100644 index 34eabcbd8..000000000 --- a/gl/gfxGLUtils.h +++ /dev/null @@ -1,244 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#ifndef TORQUE_GFX_GL_GFXGLUTILS_H_ -#define TORQUE_GFX_GL_GFXGLUTILS_H_ - -#include "core/util/preprocessorHelpers.h" -#include "gfx/gl/gfxGLEnumTranslate.h" -#include "gfx/gl/gfxGLStateCache.h" -#include "gfx/bitmap/imageUtils.h" - -inline U32 getMaxMipmaps(U32 width, U32 height, U32 depth) -{ - return getMax( getBinLog2(depth), getMax(getBinLog2(width), getBinLog2(height))); -} - -inline GLenum minificationFilter(U32 minFilter, U32 mipFilter, U32 /*mipLevels*/) -{ - // the compiler should interpret this as array lookups - switch( minFilter ) - { - case GFXTextureFilterLinear: - switch( mipFilter ) - { - case GFXTextureFilterLinear: - return GL_LINEAR_MIPMAP_LINEAR; - case GFXTextureFilterPoint: - return GL_LINEAR_MIPMAP_NEAREST; - default: - return GL_LINEAR; - } - default: - switch( mipFilter ) { - case GFXTextureFilterLinear: - return GL_NEAREST_MIPMAP_LINEAR; - case GFXTextureFilterPoint: - return GL_NEAREST_MIPMAP_NEAREST; - default: - return GL_NEAREST; - } - } -} - -//Get the surface size of a compressed mip map level - see ddsLoader.cpp -inline U32 getCompressedSurfaceSize(GFXFormat format,U32 width, U32 height, U32 mipLevel=0 ) -{ - if(!ImageUtil::isCompressedFormat(format)) - return 0; - - // Bump by the mip level. - height = getMax(U32(1), height >> mipLevel); - width = getMax(U32(1), width >> mipLevel); - - U32 sizeMultiple = 0; - if(format == GFXFormatBC1 || format == GFXFormatBC1_SRGB) - sizeMultiple = 8; - else - sizeMultiple = 16; - - return getMax(U32(1), width/4) * getMax(U32(1), height/4) * sizeMultiple; -} - -/// Simple class which preserves a given GL integer. -/// This class determines the integer to preserve on construction and restores -/// it on destruction. -class GFXGLPreserveInteger -{ -public: - typedef void(STDCALL *BindFn)(GLenum, GLuint); - - /// Preserve the integer. - /// @param binding The binding which should be set on destruction. - /// @param getBinding The parameter to be passed to glGetIntegerv to determine - /// the integer to be preserved. - /// @param binder The gl function to call to restore the integer. - GFXGLPreserveInteger(GLenum binding, GLint getBinding, BindFn binder) : - mBinding(binding), mPreserved(0), mBinder(binder) - { - AssertFatal(mBinder, "GFXGLPreserveInteger - Need a valid binder function"); - mPreserved = GFXGL->getOpenglCache()->getCacheBinded(mBinding); -#if defined(TORQUE_DEBUG) && defined(TORQUE_DEBUG_GFX) - GLint bindedOnOpenglDriver; - glGetIntegerv(getBinding, &bindedOnOpenglDriver); - AssertFatal( mPreserved == bindedOnOpenglDriver, "GFXGLPreserveInteger - GFXGLDevice/OpenGL mismatch on cache binded resource."); -#endif - } - - /// Restores the integer. - ~GFXGLPreserveInteger() - { - mBinder(mBinding, mPreserved); - } - -private: - GLenum mBinding; - GLint mPreserved; - BindFn mBinder; -}; - -class GFXGLPreserveTexture -{ -public: - typedef void(STDCALL *BindFn)(GLenum, GLuint); - - GFXGLPreserveTexture(GLenum binding, GLint getBinding, BindFn binder) : - mBinding(binding), mPreserved(0), mBinder(binder) - { - AssertFatal(mBinder, "GFXGLPreserveTexture - Need a valid binder function"); - GFXGLDevice *gfx = GFXGL; - mPreserved = gfx->getOpenglCache()->getCacheBinded(mBinding); - mActiveTexture = gfx->getOpenglCache()->getCacheActiveTexture(); -#if defined(TORQUE_DEBUG) && defined(TORQUE_DEBUG_GFX) - GLint activeTextureOnOpenglDriver, bindedTextureOnOpenglDriver; - glGetIntegerv(getBinding, &bindedTextureOnOpenglDriver); - glGetIntegerv(GL_ACTIVE_TEXTURE, &activeTextureOnOpenglDriver); - activeTextureOnOpenglDriver -= GL_TEXTURE0; - AssertFatal( mPreserved == bindedTextureOnOpenglDriver, "GFXGLPreserveTexture - GFXGLDevice/OpenGL mismatch on cache binded resource."); - AssertFatal( activeTextureOnOpenglDriver == mActiveTexture, "GFXGLPreserveTexture - GFXGLDevice/OpenGL mismatch on cache binded resource."); -#endif - } - - /// Restores the texture. - ~GFXGLPreserveTexture() - { -#if defined(TORQUE_DEBUG) && defined(TORQUE_DEBUG_GFX) - GLint activeTextureOnOpenglDriver; - glGetIntegerv(GL_ACTIVE_TEXTURE, &activeTextureOnOpenglDriver); - activeTextureOnOpenglDriver -= GL_TEXTURE0; - GLint cacheActiveTexture = GFXGL->getOpenglCache()->getCacheActiveTexture(); - AssertFatal( cacheActiveTexture == activeTextureOnOpenglDriver, "GFXGLPreserveTexture - GFXGLDevice/OpenGL mismatch on cache ActiveTexture."); -#endif - mBinder(mBinding, mPreserved); - } - -private: - GLenum mBinding; - GLint mPreserved; - BindFn mBinder; - S16 mActiveTexture; -}; - -/// Helper macro to preserve the current VBO binding. -#define PRESERVE_VERTEX_BUFFER() \ -GFXGLPreserveInteger TORQUE_CONCAT(preserve_, __LINE__) (GL_ARRAY_BUFFER, GL_ARRAY_BUFFER_BINDING, (GFXGLPreserveInteger::BindFn)glBindBuffer) - -/// Helper macro to preserve the current element array binding. -#define PRESERVE_INDEX_BUFFER() \ -GFXGLPreserveInteger TORQUE_CONCAT(preserve_, __LINE__) (GL_ELEMENT_ARRAY_BUFFER, GL_ELEMENT_ARRAY_BUFFER_BINDING, (GFXGLPreserveInteger::BindFn)glBindBuffer) - -#define _GET_BUFFER_BINDING( BINDING ) \ -BINDING == GL_ARRAY_BUFFER ? GL_ARRAY_BUFFER_BINDING : ( BINDING == GL_ELEMENT_ARRAY_BUFFER ? GL_ELEMENT_ARRAY_BUFFER_BINDING : 0 ) - -/// Helper macro to preserve the current element array binding. -#define PRESERVE_BUFFER( BINDING ) \ -GFXGLPreserveInteger TORQUE_CONCAT(preserve_, __LINE__) (BINDING, _GET_BUFFER_BINDING(BINDING), (GFXGLPreserveInteger::BindFn)glBindBuffer) - -/// ASSERT: Never call glActiveTexture for a "bind to modify" or in a PRESERVER_TEXTURE MACRO scope. - -/// Helper macro to preserve the current 1D texture binding. -#define PRESERVE_1D_TEXTURE() \ -GFXGLPreserveTexture TORQUE_CONCAT(preserve_, __LINE__) (GL_TEXTURE_1D, GL_TEXTURE_BINDING_1D, (GFXGLPreserveInteger::BindFn)glBindTexture) - -/// Helper macro to preserve the current 2D texture binding. -#define PRESERVE_2D_TEXTURE() \ -GFXGLPreserveTexture TORQUE_CONCAT(preserve_, __LINE__) (GL_TEXTURE_2D, GL_TEXTURE_BINDING_2D, (GFXGLPreserveInteger::BindFn)glBindTexture) - -/// Helper macro to preserve the current 3D texture binding. -#define PRESERVE_3D_TEXTURE() \ -GFXGLPreserveTexture TORQUE_CONCAT(preserve_, __LINE__) (GL_TEXTURE_3D, GL_TEXTURE_BINDING_3D, (GFXGLPreserveInteger::BindFn)glBindTexture) - -/// Helper macro to preserve the current 3D texture binding. -#define PRESERVE_CUBEMAP_TEXTURE() \ -GFXGLPreserveTexture TORQUE_CONCAT(preserve_, __LINE__) (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BINDING_CUBE_MAP, (GFXGLPreserveInteger::BindFn)glBindTexture) - -#define PRESERVE_CUBEMAP_ARRAY_TEXTURE() \ -GFXGLPreserveTexture TORQUE_CONCAT(preserve_, __LINE__) (GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_BINDING_CUBE_MAP_ARRAY, (GFXGLPreserveInteger::BindFn)glBindTexture) - -#define _GET_TEXTURE_BINDING(binding) \ -binding == GL_TEXTURE_2D ? GL_TEXTURE_BINDING_2D : (binding == GL_TEXTURE_3D ? GL_TEXTURE_BINDING_3D : GL_TEXTURE_BINDING_1D ) - -#define PRESERVE_TEXTURE(binding) \ -GFXGLPreserveTexture TORQUE_CONCAT(preserve_, __LINE__) (binding, _GET_TEXTURE_BINDING(binding), (GFXGLPreserveInteger::BindFn)glBindTexture) - -#define PRESERVE_FRAMEBUFFER() \ -GFXGLPreserveInteger TORQUE_CONCAT(preserve_, __LINE__) (GL_READ_FRAMEBUFFER, GL_READ_FRAMEBUFFER_BINDING, (GFXGLPreserveInteger::BindFn)glBindFramebuffer);\ -GFXGLPreserveInteger TORQUE_CONCAT(preserve2_, __LINE__) (GL_DRAW_FRAMEBUFFER, GL_DRAW_FRAMEBUFFER_BINDING, (GFXGLPreserveInteger::BindFn)glBindFramebuffer) - - -#if TORQUE_DEBUG - - // Handy macro for checking the status of a framebuffer. Framebuffers can fail in - // all sorts of interesting ways, these are just the most common. Further, no existing GL profiling - // tool catches framebuffer errors when the framebuffer is created, so we actually need this. - #define CHECK_FRAMEBUFFER_STATUS()\ - {\ - GLenum status;\ - status = glCheckFramebufferStatus(GL_FRAMEBUFFER);\ - switch(status) {\ - case GL_FRAMEBUFFER_COMPLETE:\ - break;\ - case GL_FRAMEBUFFER_UNSUPPORTED:\ - AssertFatal(false, "Unsupported FBO");\ - break;\ - case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:\ - AssertFatal(false, "Incomplete FBO Attachment");\ - break;\ - case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:\ - AssertFatal(false, "Incomplete FBO Missing Attachment");\ - break;\ - case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:\ - AssertFatal(false, "Incomplete FBO Draw buffer");\ - break;\ - case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:\ - AssertFatal(false, "Incomplete FBO Read buffer");\ - break;\ - default:\ - /* programming error; will fail on all hardware */\ - AssertFatal(false, "Something really bad happened with an FBO");\ - }\ - } -#else - #define CHECK_FRAMEBUFFER_STATUS() -#endif //TORQUE_DEBUG - -#endif