2012-09-19 11:15:01 -04:00
//-----------------------------------------------------------------------------
// 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"
2014-11-08 17:41:17 +01:00
# include "gfx/gl/tGL/tGL.h"
2012-09-19 11:15:01 -04:00
# 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 ;
2014-11-08 17:41:17 +01:00
class GFXGLStateCache ;
class GFXGLVertexDecl ;
2012-09-19 11:15:01 -04:00
class GFXGLDevice : public GFXDevice
{
public :
2016-05-06 22:57:35 -04:00
struct GLCapabilities
{
bool anisotropicFiltering ;
bool bufferStorage ;
bool shaderModel5 ;
bool textureStorage ;
bool samplerObjects ;
bool copyImage ;
bool vertexAttributeBinding ;
} ;
GLCapabilities mCapabilities ;
2016-05-06 21:50:11 -04:00
2012-09-19 11:15:01 -04:00
void zombify ( ) ;
void resurrect ( ) ;
GFXGLDevice ( U32 adapterIndex ) ;
virtual ~ GFXGLDevice ( ) ;
static void enumerateAdapters ( Vector < GFXAdapter * > & 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 ; }
2014-11-08 17:41:17 +01:00
virtual void enterDebugEvent ( ColorI color , const char * name ) ;
virtual void leaveDebugEvent ( ) ;
virtual void setDebugMarker ( ColorI color , const char * name ) ;
2012-09-19 11:15:01 -04:00
virtual void enumerateVideoModes ( ) ;
2014-11-08 17:41:17 +01:00
virtual U32 getTotalVideoMemory_GL_EXT ( ) ;
2012-09-19 11:15:01 -04:00
virtual U32 getTotalVideoMemory ( ) ;
virtual GFXCubemap * createCubemap ( ) ;
2018-09-16 18:19:04 -05:00
virtual GFXCubemapArray * createCubemapArray ( ) { return NULL ; } //TODO: implement
2012-09-19 11:15:01 -04:00
virtual F32 getFillConventionOffset ( ) const { return 0.0f ; }
///@}
/// @name Render Target functions
/// @{
///
2018-09-16 18:19:04 -05:00
virtual GFXTextureTarget * allocRenderToTextureTarget ( bool genMips = true ) ;
2012-09-19 11:15:01 -04:00
virtual GFXWindowTarget * allocWindowTarget ( PlatformWindow * window ) ;
virtual void _updateRenderTargets ( ) ;
///@}
/// @name Shader functions
/// @{
virtual F32 getPixelShaderVersion ( ) const { return mPixelShaderVersion ; }
virtual void setPixelShaderVersion ( F32 version ) { mPixelShaderVersion = version ; }
2015-06-14 15:59:33 +10:00
virtual void setShader ( GFXShader * shader , bool force = false ) ;
2012-09-19 11:15:01 -04:00
/// @attention GL cannot check if the given format supports blending or filtering!
virtual GFXFormat selectSupportedFormat ( GFXTextureProfile * profile ,
const Vector < GFXFormat > & 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 ( ) ;
2018-11-28 17:51:52 +10:00
//TODO: implement me!
virtual void copyResource ( GFXTextureObject * pDst , GFXCubemap * pSrc , const U32 face ) { } ;
2017-06-23 11:36:20 -05:00
virtual void clear ( U32 flags , const LinearColorF & color , F32 z , U32 stencil ) ;
2018-09-16 18:19:04 -05:00
virtual void clearColorAttachment ( const U32 attachment , const LinearColorF & color ) ;
2012-09-19 11:15:01 -04:00
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 ; }
2014-11-08 17:41:17 +01:00
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 ; }
2012-09-19 11:15:01 -04:00
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 cubemap , const GFXGLCubemap * texture ) ;
virtual void setLightInternal ( U32 lightStage , const GFXLightInfo light , bool lightEnable ) ;
virtual void setLightMaterialInternal ( const GFXLightMaterial mat ) ;
2017-06-23 11:36:20 -05:00
virtual void setGlobalAmbientInternal ( LinearColorF color ) ;
2012-09-19 11:15:01 -04:00
/// @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 ,
2016-02-20 21:28:18 +01:00
GFXBufferType bufferType ,
void * data = NULL ) ;
virtual GFXPrimitiveBuffer * allocPrimitiveBuffer ( U32 numIndices , U32 numPrimitives , GFXBufferType bufferType , void * data = NULL ) ;
2012-09-19 11:15:01 -04:00
// 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.
2014-11-08 17:41:17 +01:00
virtual GFXVertexDecl * allocVertexDecl ( const GFXVertexFormat * vertexFormat ) ;
2012-09-19 11:15:01 -04:00
2014-11-08 17:41:17 +01:00
virtual void setVertexDecl ( const GFXVertexDecl * decl ) ;
2012-09-19 11:15:01 -04:00
virtual void setVertexStream ( U32 stream , GFXVertexBuffer * buffer ) ;
2014-11-08 17:41:17 +01:00
virtual void setVertexStreamFrequency ( U32 stream , U32 frequency ) ;
2012-09-19 11:15:01 -04:00
private :
typedef GFXDevice Parent ;
friend class GFXGLTextureObject ;
friend class GFXGLCubemap ;
friend class GFXGLWindowTarget ;
friend class GFXGLPrimitiveBuffer ;
friend class GFXGLVertexBuffer ;
static GFXAdapter : : CreateDeviceInstanceDelegate mCreateDeviceInstance ;
U32 mAdapterIndex ;
2014-11-08 17:41:17 +01:00
StrongRefPtr < GFXGLVertexBuffer > mCurrentVB [ VERTEX_STREAM_COUNT ] ;
U32 mCurrentVB_Divisor [ VERTEX_STREAM_COUNT ] ;
bool mNeedUpdateVertexAttrib ;
2012-09-19 11:15:01 -04:00
StrongRefPtr < GFXGLPrimitiveBuffer > mCurrentPB ;
2014-11-08 17:41:17 +01:00
U32 mDrawInstancesCount ;
GFXShader * mCurrentShader ;
GFXShaderRef mGenericShader [ GS_COUNT ] ;
GFXShaderConstBufferRef mGenericShaderBuffer [ GS_COUNT ] ;
GFXShaderConstHandle * mModelViewProjSC [ GS_COUNT ] ;
2012-09-19 11:15:01 -04:00
/// 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 ;
2014-11-08 17:41:17 +01:00
bool mSupportsAnisotropic ;
U32 mNumVertexStream ;
2012-09-19 11:15:01 -04:00
U32 mMaxShaderTextures ;
U32 mMaxFFTextures ;
2014-11-08 17:41:17 +01:00
U32 mMaxTRColors ;
2012-09-19 11:15:01 -04:00
RectI mClip ;
GFXGLStateBlockRef mCurrentGLStateBlock ;
GLenum mActiveTextureType [ TEXTURE_STAGE_COUNT ] ;
Vector < StrongRefPtr < GFXGLVertexBuffer > > mVolatileVBs ; ///< Pool of existing volatile VBs so we can reuse previously created ones
Vector < StrongRefPtr < GFXGLPrimitiveBuffer > > 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
2016-12-23 13:59:55 +10:00
void vsyncCallback ( ) ; ///< Vsync callback
2012-09-19 11:15:01 -04:00
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
2014-11-08 17:41:17 +01:00
GFXGLStateCache * mOpenglStateCache ;
GFXWindowTargetRef * mWindowRT ;
bool mUseGlMap ;
2012-09-19 11:15:01 -04:00
} ;
2014-11-08 17:41:17 +01:00
# define GFXGL static_cast<GFXGLDevice*>(GFXDevice::get())
2012-09-19 11:15:01 -04:00
# endif