2018-07-06 14:11:38 +00:00
# ifndef ENGINE_CLIENT_BACKEND_SDL_H
# define ENGINE_CLIENT_BACKEND_SDL_H
2012-01-03 20:39:10 +00:00
# include "SDL.h"
# include "graphics_threaded.h"
2015-08-24 20:46:28 +00:00
# if defined(CONF_PLATFORM_MACOSX)
2012-08-26 18:02:04 +00:00
# include <objc/objc-runtime.h>
2012-01-03 21:49:31 +00:00
2012-08-26 18:02:04 +00:00
class CAutoreleasePool
{
private :
id m_Pool ;
public :
CAutoreleasePool ( )
{
Class NSAutoreleasePoolClass = ( Class ) objc_getClass ( " NSAutoreleasePool " ) ;
m_Pool = class_createInstance ( NSAutoreleasePoolClass , 0 ) ;
SEL selector = sel_registerName ( " init " ) ;
objc_msgSend ( m_Pool , selector ) ;
}
~ CAutoreleasePool ( )
{
SEL selector = sel_registerName ( " drain " ) ;
objc_msgSend ( m_Pool , selector ) ;
}
2015-07-09 00:08:14 +00:00
} ;
2012-01-03 20:39:10 +00:00
# endif
// basic threaded backend, abstract, missing init and shutdown functions
class CGraphicsBackend_Threaded : public IGraphicsBackend
{
public :
2018-07-10 09:29:02 +00:00
// constructed on the main thread, the rest of the functions is run on the render thread
2012-01-03 20:39:10 +00:00
class ICommandProcessor
{
public :
virtual ~ ICommandProcessor ( ) { }
virtual void RunBuffer ( CCommandBuffer * pBuffer ) = 0 ;
} ;
CGraphicsBackend_Threaded ( ) ;
virtual void RunBuffer ( CCommandBuffer * pBuffer ) ;
virtual bool IsIdle ( ) const ;
virtual void WaitForIdle ( ) ;
2015-07-09 00:08:14 +00:00
2012-01-03 20:39:10 +00:00
protected :
void StartProcessor ( ICommandProcessor * pProcessor ) ;
void StopProcessor ( ) ;
private :
ICommandProcessor * m_pProcessor ;
CCommandBuffer * volatile m_pBuffer ;
volatile bool m_Shutdown ;
semaphore m_Activity ;
semaphore m_BufferDone ;
void * m_pThread ;
static void ThreadFunc ( void * pUser ) ;
} ;
// takes care of implementation independent operations
class CCommandProcessorFragment_General
{
void Cmd_Nop ( ) ;
void Cmd_Signal ( const CCommandBuffer : : SCommand_Signal * pCommand ) ;
public :
2017-12-02 21:19:57 +00:00
bool RunCommand ( const CCommandBuffer : : SCommand * pBaseCommand ) ;
2012-01-03 20:39:10 +00:00
} ;
// takes care of opengl related rendering
class CCommandProcessorFragment_OpenGL
{
2012-10-06 21:31:02 +00:00
struct CTexture
{
GLuint m_Tex ;
int m_MemSize ;
2018-03-13 20:44:58 +00:00
int m_Width ;
int m_Height ;
int m_RescaleCount ;
2012-10-06 21:31:02 +00:00
} ;
CTexture m_aTextures [ CCommandBuffer : : MAX_TEXTURES ] ;
volatile int * m_pTextureMemoryUsage ;
2018-03-13 20:44:58 +00:00
GLint m_MaxTexSize ;
2012-10-06 21:31:02 +00:00
public :
enum
{
CMD_INIT = CCommandBuffer : : CMDGROUP_PLATFORM_OPENGL ,
} ;
struct SCommand_Init : public CCommandBuffer : : SCommand
{
SCommand_Init ( ) : SCommand ( CMD_INIT ) { }
volatile int * m_pTextureMemoryUsage ;
} ;
private :
2012-01-03 20:39:10 +00:00
static int TexFormatToOpenGLFormat ( int TexFormat ) ;
2012-10-07 09:22:49 +00:00
static unsigned char Sample ( int w , int h , const unsigned char * pData , int u , int v , int Offset , int ScaleW , int ScaleH , int Bpp ) ;
static void * Rescale ( int Width , int Height , int NewWidth , int NewHeight , int Format , const unsigned char * pData ) ;
2012-01-03 20:39:10 +00:00
void SetState ( const CCommandBuffer : : SState & State ) ;
2012-10-06 21:31:02 +00:00
void Cmd_Init ( const SCommand_Init * pCommand ) ;
2012-01-03 20:39:10 +00:00
void Cmd_Texture_Update ( const CCommandBuffer : : SCommand_Texture_Update * pCommand ) ;
void Cmd_Texture_Destroy ( const CCommandBuffer : : SCommand_Texture_Destroy * pCommand ) ;
void Cmd_Texture_Create ( const CCommandBuffer : : SCommand_Texture_Create * pCommand ) ;
void Cmd_Clear ( const CCommandBuffer : : SCommand_Clear * pCommand ) ;
void Cmd_Render ( const CCommandBuffer : : SCommand_Render * pCommand ) ;
void Cmd_Screenshot ( const CCommandBuffer : : SCommand_Screenshot * pCommand ) ;
public :
CCommandProcessorFragment_OpenGL ( ) ;
2017-12-02 21:19:57 +00:00
bool RunCommand ( const CCommandBuffer : : SCommand * pBaseCommand ) ;
2012-01-03 20:39:10 +00:00
} ;
2018-03-13 20:44:58 +00:00
# define MAX_STREAM_BUFFER_COUNT 30
2017-09-02 13:24:07 +00:00
class CGLSLProgram ;
2017-09-12 18:07:38 +00:00
class CGLSLTWProgram ;
class CGLSLPrimitiveProgram ;
2017-09-02 13:24:07 +00:00
class CGLSLQuadProgram ;
2017-09-12 18:07:38 +00:00
class CGLSLTileProgram ;
class CGLSLBorderTileProgram ;
class CGLSLBorderTileLineProgram ;
2018-03-13 20:44:58 +00:00
class CGLSLTextProgram ;
class CGLSLSpriteProgram ;
class CGLSLSpriteMultipleProgram ;
2017-10-23 16:02:18 +00:00
// takes care of opengl 3.3 related rendering
2017-09-02 13:24:07 +00:00
class CCommandProcessorFragment_OpenGL3_3
{
2017-09-14 00:58:13 +00:00
bool m_UseMultipleTextureUnits ;
2017-09-27 10:16:34 +00:00
bool m_UsePreinitializedVertexBuffer ;
2017-09-14 00:58:13 +00:00
2017-09-02 13:24:07 +00:00
struct CTexture
{
GLuint m_Tex ;
GLuint m_Sampler ;
2017-10-09 13:59:16 +00:00
int m_LastWrapMode ;
2017-09-02 13:24:07 +00:00
int m_MemSize ;
2018-03-13 20:44:58 +00:00
int m_Width ;
int m_Height ;
int m_RescaleCount ;
2017-09-02 13:24:07 +00:00
} ;
CTexture m_aTextures [ CCommandBuffer : : MAX_TEXTURES ] ;
volatile int * m_pTextureMemoryUsage ;
2017-12-02 21:19:57 +00:00
CGLSLPrimitiveProgram * m_pPrimitiveProgram ;
CGLSLTileProgram * m_pTileProgram ;
CGLSLTileProgram * m_pTileProgramTextured ;
CGLSLBorderTileProgram * m_pBorderTileProgram ;
CGLSLBorderTileProgram * m_pBorderTileProgramTextured ;
CGLSLBorderTileLineProgram * m_pBorderTileLineProgram ;
CGLSLBorderTileLineProgram * m_pBorderTileLineProgramTextured ;
2018-03-13 20:44:58 +00:00
CGLSLQuadProgram * m_pQuadProgram ;
CGLSLQuadProgram * m_pQuadProgramTextured ;
CGLSLTextProgram * m_pTextProgram ;
CGLSLSpriteProgram * m_pSpriteProgram ;
CGLSLSpriteMultipleProgram * m_pSpriteProgramMultiple ;
GLuint m_LastProgramID ;
GLuint m_PrimitiveDrawVertexID [ MAX_STREAM_BUFFER_COUNT ] ;
GLuint m_PrimitiveDrawBufferID [ MAX_STREAM_BUFFER_COUNT ] ;
GLuint m_LastIndexBufferBound [ MAX_STREAM_BUFFER_COUNT ] ;
int m_LastStreamBuffer ;
2017-09-27 10:16:34 +00:00
GLuint m_QuadDrawIndexBufferID ;
unsigned int m_CurrentIndicesInBuffer ;
2017-09-12 18:07:38 +00:00
GLint m_MaxTextureUnits ;
2017-11-04 04:38:48 +00:00
GLint m_MaxTexSize ;
2017-09-12 18:07:38 +00:00
int m_LastBlendMode ; //avoid all possible opengl state changes
bool m_LastClipEnable ;
struct STextureBound {
int m_TextureSlot ;
} ;
std : : vector < STextureBound > m_TextureSlotBoundToUnit ; //the texture index generated by loadtextureraw is stored in an index calculated by max texture units
bool IsAndUpdateTextureSlotBound ( int IDX , int Slot ) ;
void DestroyTexture ( int Slot ) ;
2018-03-13 20:44:58 +00:00
void DestroyBufferContainer ( int Index , bool DeleteBOs = true ) ;
2017-09-12 18:07:38 +00:00
2017-09-27 10:16:34 +00:00
void AppendIndices ( unsigned int NewIndicesCount ) ;
2018-03-13 20:44:58 +00:00
struct SBufferContainer
{
SBufferContainer ( ) : m_VertArrayID ( 0 ) , m_LastIndexBufferBound ( 0 ) { }
2017-09-12 18:07:38 +00:00
GLuint m_VertArrayID ;
2017-10-23 16:02:18 +00:00
GLuint m_LastIndexBufferBound ;
2018-03-13 20:44:58 +00:00
SBufferContainerInfo m_ContainerInfo ;
2017-09-12 18:07:38 +00:00
} ;
2018-03-13 20:44:58 +00:00
std : : vector < SBufferContainer > m_BufferContainers ;
std : : vector < GLuint > m_BufferObjectIndices ;
2017-09-27 10:16:34 +00:00
CCommandBuffer : : SColorf m_ClearColor ;
2017-09-02 13:24:07 +00:00
public :
enum
{
CMD_INIT = CCommandBuffer : : CMDGROUP_PLATFORM_OPENGL3_3 ,
CMD_SHUTDOWN ,
} ;
struct SCommand_Init : public CCommandBuffer : : SCommand
{
SCommand_Init ( ) : SCommand ( CMD_INIT ) { }
2017-12-02 21:19:57 +00:00
class IStorage * m_pStorage ;
2017-09-02 13:24:07 +00:00
volatile int * m_pTextureMemoryUsage ;
} ;
struct SCommand_Shutdown : public CCommandBuffer : : SCommand
{
SCommand_Shutdown ( ) : SCommand ( CMD_SHUTDOWN ) { }
} ;
private :
static int TexFormatToOpenGLFormat ( int TexFormat ) ;
static unsigned char Sample ( int w , int h , const unsigned char * pData , int u , int v , int Offset , int ScaleW , int ScaleH , int Bpp ) ;
static void * Rescale ( int Width , int Height , int NewWidth , int NewHeight , int Format , const unsigned char * pData ) ;
2018-03-13 20:44:58 +00:00
2017-12-02 21:19:57 +00:00
void SetState ( const CCommandBuffer : : SState & State , CGLSLTWProgram * pProgram ) ;
2018-03-13 20:44:58 +00:00
void UseProgram ( CGLSLTWProgram * pProgram ) ;
void UploadStreamBufferData ( unsigned int PrimitiveType , const void * pVertices , unsigned int PrimitiveCount ) ;
void RenderText ( const CCommandBuffer : : SState & State , int DrawNum , int TextTextureIndex , int TextOutlineTextureIndex , int TextureSize , const float * pTextColor , const float * pTextOutlineColor ) ;
2017-09-02 13:24:07 +00:00
void Cmd_Init ( const SCommand_Init * pCommand ) ;
void Cmd_Shutdown ( const SCommand_Shutdown * pCommand ) ;
void Cmd_Texture_Update ( const CCommandBuffer : : SCommand_Texture_Update * pCommand ) ;
void Cmd_Texture_Destroy ( const CCommandBuffer : : SCommand_Texture_Destroy * pCommand ) ;
void Cmd_Texture_Create ( const CCommandBuffer : : SCommand_Texture_Create * pCommand ) ;
void Cmd_Clear ( const CCommandBuffer : : SCommand_Clear * pCommand ) ;
void Cmd_Render ( const CCommandBuffer : : SCommand_Render * pCommand ) ;
void Cmd_Screenshot ( const CCommandBuffer : : SCommand_Screenshot * pCommand ) ;
2018-03-13 20:44:58 +00:00
void Cmd_CreateBufferObject ( const CCommandBuffer : : SCommand_CreateBufferObject * pCommand ) ;
void Cmd_RecreateBufferObject ( const CCommandBuffer : : SCommand_RecreateBufferObject * pCommand ) ;
void Cmd_UpdateBufferObject ( const CCommandBuffer : : SCommand_UpdateBufferObject * pCommand ) ;
void Cmd_CopyBufferObject ( const CCommandBuffer : : SCommand_CopyBufferObject * pCommand ) ;
void Cmd_DeleteBufferObject ( const CCommandBuffer : : SCommand_DeleteBufferObject * pCommand ) ;
void Cmd_CreateBufferContainer ( const CCommandBuffer : : SCommand_CreateBufferContainer * pCommand ) ;
void Cmd_UpdateBufferContainer ( const CCommandBuffer : : SCommand_UpdateBufferContainer * pCommand ) ;
void Cmd_DeleteBufferContainer ( const CCommandBuffer : : SCommand_DeleteBufferContainer * pCommand ) ;
void Cmd_IndicesRequiredNumNotify ( const CCommandBuffer : : SCommand_IndicesRequiredNumNotify * pCommand ) ;
void Cmd_RenderTileLayer ( const CCommandBuffer : : SCommand_RenderTileLayer * pCommand ) ;
2017-09-12 18:07:38 +00:00
void Cmd_RenderBorderTile ( const CCommandBuffer : : SCommand_RenderBorderTile * pCommand ) ;
void Cmd_RenderBorderTileLine ( const CCommandBuffer : : SCommand_RenderBorderTileLine * pCommand ) ;
2018-03-13 20:44:58 +00:00
void Cmd_RenderQuadLayer ( const CCommandBuffer : : SCommand_RenderQuadLayer * pCommand ) ;
void Cmd_RenderText ( const CCommandBuffer : : SCommand_RenderText * pCommand ) ;
void Cmd_RenderTextStream ( const CCommandBuffer : : SCommand_RenderTextStream * pCommand ) ;
void Cmd_RenderQuadContainer ( const CCommandBuffer : : SCommand_RenderQuadContainer * pCommand ) ;
void Cmd_RenderQuadContainerAsSprite ( const CCommandBuffer : : SCommand_RenderQuadContainerAsSprite * pCommand ) ;
void Cmd_RenderQuadContainerAsSpriteMultiple ( const CCommandBuffer : : SCommand_RenderQuadContainerAsSpriteMultiple * pCommand ) ;
2017-09-02 13:24:07 +00:00
public :
CCommandProcessorFragment_OpenGL3_3 ( ) ;
2017-12-02 21:19:57 +00:00
bool RunCommand ( const CCommandBuffer : : SCommand * pBaseCommand ) ;
2017-09-02 13:24:07 +00:00
} ;
2012-01-03 20:39:10 +00:00
// takes care of sdl related commands
class CCommandProcessorFragment_SDL
{
// SDL stuff
2015-08-24 20:46:28 +00:00
SDL_Window * m_pWindow ;
SDL_GLContext m_GLContext ;
2012-01-03 20:39:10 +00:00
public :
enum
{
2012-10-06 21:31:02 +00:00
CMD_INIT = CCommandBuffer : : CMDGROUP_PLATFORM_SDL ,
2017-10-23 16:02:18 +00:00
CMD_UPDATE_VIEWPORT ,
2012-01-03 20:39:10 +00:00
CMD_SHUTDOWN ,
} ;
struct SCommand_Init : public CCommandBuffer : : SCommand
{
SCommand_Init ( ) : SCommand ( CMD_INIT ) { }
2015-08-24 20:46:28 +00:00
SDL_Window * m_pWindow ;
SDL_GLContext m_GLContext ;
2012-01-03 20:39:10 +00:00
} ;
2017-10-23 16:02:18 +00:00
struct SCommand_Update_Viewport : public CCommandBuffer : : SCommand
{
SCommand_Update_Viewport ( ) : SCommand ( CMD_UPDATE_VIEWPORT ) { }
int m_X ;
int m_Y ;
int m_Width ;
int m_Height ;
} ;
2012-01-03 20:39:10 +00:00
struct SCommand_Shutdown : public CCommandBuffer : : SCommand
{
SCommand_Shutdown ( ) : SCommand ( CMD_SHUTDOWN ) { }
} ;
private :
void Cmd_Init ( const SCommand_Init * pCommand ) ;
2017-12-02 21:19:57 +00:00
void Cmd_Update_Viewport ( const SCommand_Update_Viewport * pCommand ) ;
2012-01-03 20:39:10 +00:00
void Cmd_Shutdown ( const SCommand_Shutdown * pCommand ) ;
void Cmd_Swap ( const CCommandBuffer : : SCommand_Swap * pCommand ) ;
2016-04-29 22:34:12 +00:00
void Cmd_VSync ( const CCommandBuffer : : SCommand_VSync * pCommand ) ;
2016-04-30 15:59:58 +00:00
void Cmd_Resize ( const CCommandBuffer : : SCommand_Resize * pCommand ) ;
2012-01-03 20:39:10 +00:00
void Cmd_VideoModes ( const CCommandBuffer : : SCommand_VideoModes * pCommand ) ;
public :
CCommandProcessorFragment_SDL ( ) ;
bool RunCommand ( const CCommandBuffer : : SCommand * pBaseCommand ) ;
} ;
// command processor impelementation, uses the fragments to combine into one processor
class CCommandProcessor_SDL_OpenGL : public CGraphicsBackend_Threaded : : ICommandProcessor
{
2015-07-09 00:08:14 +00:00
CCommandProcessorFragment_OpenGL m_OpenGL ;
2017-09-02 13:24:07 +00:00
CCommandProcessorFragment_OpenGL3_3 m_OpenGL3_3 ;
2015-07-09 00:08:14 +00:00
CCommandProcessorFragment_SDL m_SDL ;
CCommandProcessorFragment_General m_General ;
2017-09-02 13:24:07 +00:00
bool m_UseOpenGL3_3 ;
2015-07-09 00:08:14 +00:00
public :
2017-09-02 13:24:07 +00:00
void UseOpenGL3_3 ( bool Use ) { m_UseOpenGL3_3 = Use ; }
2012-01-03 20:39:10 +00:00
virtual void RunBuffer ( CCommandBuffer * pBuffer ) ;
} ;
// graphics backend implemented with SDL and OpenGL
class CGraphicsBackend_SDL_OpenGL : public CGraphicsBackend_Threaded
{
2015-08-24 20:46:28 +00:00
SDL_Window * m_pWindow ;
SDL_GLContext m_GLContext ;
2012-01-03 20:39:10 +00:00
ICommandProcessor * m_pProcessor ;
2012-10-06 21:31:02 +00:00
volatile int m_TextureMemoryUsage ;
2016-04-29 22:34:12 +00:00
int m_NumScreens ;
2017-09-02 13:24:07 +00:00
bool m_UseOpenGL3_3 ;
2012-01-03 20:39:10 +00:00
public :
2017-12-02 21:19:57 +00:00
virtual int Init ( const char * pName , int * Screen , int * pWidth , int * pHeight , int FsaaSamples , int Flags , int * pDesktopWidth , int * pDesktopHeight , int * pCurrentWidth , int * pCurrentHeight , class IStorage * pStorage ) ;
2012-01-03 20:39:10 +00:00
virtual int Shutdown ( ) ;
2012-10-06 21:31:02 +00:00
virtual int MemoryUsage ( ) const ;
2016-04-29 22:34:12 +00:00
virtual int GetNumScreens ( ) const { return m_NumScreens ; }
2012-01-03 20:39:10 +00:00
virtual void Minimize ( ) ;
virtual void Maximize ( ) ;
2016-04-29 19:07:10 +00:00
virtual bool Fullscreen ( bool State ) ;
2016-04-29 22:34:12 +00:00
virtual void SetWindowBordered ( bool State ) ; // on=true/off=false
virtual bool SetWindowScreen ( int Index ) ;
virtual int GetWindowScreen ( ) ;
2012-01-03 20:39:10 +00:00
virtual int WindowActive ( ) ;
virtual int WindowOpen ( ) ;
2015-08-24 23:01:38 +00:00
virtual void SetWindowGrab ( bool Grab ) ;
2014-10-18 14:17:36 +00:00
virtual void NotifyWindow ( ) ;
2017-09-12 18:07:38 +00:00
virtual bool IsOpenGL3_3 ( ) { return m_UseOpenGL3_3 ; }
2012-01-03 20:39:10 +00:00
} ;
2018-07-06 14:11:38 +00:00
# endif // ENGINE_CLIENT_BACKEND_SDL_H