//CFTTGraphicsDevice - [2020-04-13 11:57:46]
#ifndef _CFTTGRAPHICSDEVICE_H_
#define _CFTTGRAPHICSDEVICE_H_

#include <GLES/egl.h>
#include "CFTTRenderTarget.h"
#include "CFTTGraphicsBuffer.h"
#include "CFTTTexture.h"
#include "CFTTShaderProgram.h"
#include "CFTTGLES2Wrapper.h"
#include "CFTTRenderToTexture.h"

/*
00203924 CFTTGraphicsDevice::CreateThreadedTextureLoadingContext()
0020388C CFTTGraphicsDevice::DepthMultisampleSupported()
00203880 CFTTGraphicsDevice::FloatTextureSupported()
00203888 CFTTGraphicsDevice::MultisampleSupported()
00203926 CFTTGraphicsDevice::ReleaseThreadedTextureLoadingContext()
00203892 CFTTGraphicsDevice::StencilMultisampleSupported()
002052BE CFTTGraphicsDevice::SupportsThreadedTextureLoading()
00203884 CFTTGraphicsDevice::TextureLODSupported()
00203928 CFTTGraphicsDevice::savePipelineCache()

0x3C
*/

enum EFTTStencilOp {
  EFTTStencilOp_0,
  EFTTStencilOp_1,
  EFTTStencilOp_2,
  EFTTStencilOp_3,
  EFTTStencilOp_4,
  EFTTStencilOp_5,
  EFTTStencilOp_6,
  EFTTStencilOp_7,
};

enum EFTTDepthTest {
  EFTTDepthTest_0,
  EFTTDepthTest_1,
  EFTTDepthTest_2,
  EFTTDepthTest_3,
  EFTTDepthTest_4,
  EFTTDepthTest_5,
  EFTTDepthTest_6,
  EFTTDepthTest_7,
  EFTTDepthTest_8,
};

struct CFTTRTTSetup {
  EFTTTextureType eTextureType_0;
  EFTTTexFormat eTexFormat_4;
  EFTTRTTZBufMode eRTTZBufMode_8;
  bool bool_C;
  int dWidth_10;
  int dheight_14;
  uint dCount_18;
  int field_1C;
  uchar byte_20;
  CFTTRenderToTexture *pRenderToTexture_24;
};

enum GraphicsState {
  GraphicsState_0,
  GraphicsState_1,
  GraphicsState_2,
  GraphicsState_3,
  GraphicsState_4,
  GraphicsState_5,
};

extern GraphicsState FTT_eGraphicsState;

class CFTTGraphicsDevice {
public:
  //CFTTGraphicsDevice();
  virtual ~CFTTGraphicsDevice();

  virtual int create() = 0;
  virtual void destroy() = 0;
  virtual void createVolatileResources() = 0;
  virtual void deleteVolatileResources() = 0;
  virtual int GetRendererFamily() const = 0;
  virtual int GetRendererType() const = 0;
  virtual int Matrices_FlipsRTT() const = 0;
  virtual int Matrices_FlipsY() const = 0;
  virtual int Matrices_NDCIsCube() const = 0;
  virtual bool DepthTextureSupported() const = 0;
  virtual void GetGPUName(wchar_t *, int) const = 0;
  virtual bool FloatTextureSupported() const;        //00203880
  virtual bool TextureLODSupported() const;          //00203884
  virtual bool MultisampleSupported() const;         //00203888
  virtual bool DepthMultisampleSupported();          //0020388C
  virtual bool StencilMultisampleSupported() const;  //00203892
  virtual uint ARGBToPlatformU32(uint, uint, uint, uint) const = 0;
  virtual uint ARGBToPlatformU32(uint) const = 0;
  virtual uint ExtractAFromPlatformU32(uint) const = 0;
  virtual uint ExtractRFromPlatformU32(uint8) const = 0;
  virtual uint ExtractGFromPlatformU32(uint) const = 0;
  virtual uint ExtractBFromPlatformU32(uint) const = 0;
  virtual ushort ARGBToPlatform4444(uint, uint, uint, uint) const = 0;
  virtual uint ARGBToPlatform4444(uint) const = 0;
  virtual uint ExtractAFromPlatform4444(ushort) const = 0;
  virtual uint ExtractRFromPlatform4444(ushort) const = 0;
  virtual uint ExtractGFromPlatform4444(ushort) const = 0;
  virtual uint ExtractBFromPlatform4444(ushort) const = 0;
  virtual bool beginScene(CFTTClearSettings const &, CFTTRenderTarget *, bool) = 0;
  virtual void endScene() = 0;
  virtual int width() const = 0;
  virtual int height() const = 0;
  virtual int getDepthBufferBitDepth() const = 0;
  virtual void setWindowHandle(void *) = 0;
  virtual int resetDisplay(int, int, int, int) = 0;
  virtual int SupportsThreadedTextureLoading();         //002052BE
  virtual void CreateThreadedTextureLoadingContext();   //00203924
  virtual void ReleaseThreadedTextureLoadingContext();  //00203926
  virtual void savePipelineCache();                     //00203928
  virtual void setWireFrame(bool) = 0;
  virtual void setDither(bool) = 0;
  virtual void setDepthTest(EFTTDepthTest, bool) = 0;
  virtual void enableStencilTest(bool) = 0;
  virtual void setStencilFunc(EFTTStencilFunc, GLuint, GLuint) = 0;
  virtual void setStencilOp(EFTTStencilOp, EFTTStencilOp, EFTTStencilOp) = 0;
  virtual void setStencilMask(uint) = 0;
  virtual void enableScissorTest(int, int, int, int) = 0;
  virtual void disableScissorTest() = 0;
  virtual CFTTTexture *createTexture() = 0;
  virtual CFTTTexture *createTexture(int, int, int, EFTTTexFormat, EFTTTextureType) = 0;
  virtual CFTTRenderToTexture *createRenderToTexture(EFTTTexFormat eFormat1,
                                                     int a2,
                                                     int a3,
                                                     uint a4,
                                                     int a5,
                                                     EFTTRTTZBufMode eMode6,
                                                     bool b7,
                                                     EFTTTextureType eType8,
                                                     uchar c9) = 0;
  virtual CFTTRenderToTexture *createRenderToTexture(CFTTRTTSetup) = 0;
  virtual int getTextureFormatSupport(EFTTTexFormat, bool, bool) = 0;
  virtual CFTTShaderProgram *createShaderProgram(CFTTUberShader const *, uchar const *, bool) = 0;
  virtual CFTTGraphicsBuffer *createGraphicsBuffer(EFTTGraphicsBufferType, EFTTGraphicsBufferVolatility, uint) = 0;
  virtual void setIndexBuffer(CFTTGraphicsBuffer *) = 0;
  virtual void setVertexBuffer(CFTTGraphicsBuffer *, uint, uint, uint) = 0;
  virtual void drawIndexed(FTTPRIMTYPE, int, int, int, int) = 0;
  virtual void drawNonIndexed(FTTPRIMTYPE, int) = 0;
  virtual void AssessHardware() = 0;

  uint8 field_4;
  uint8 reserve_5;  //以下三个是对齐用的
  uint8 reserve_6;
  uint8 reserve_7;
  uint8 byte_8;
  bool bMapbuffer_9;
  uint8 byte_A;
  bool bIsGLES3_B;    //是否支持 gles3
  bool bHighFloat_C;  //gles3 高精度浮点格式
  bool bGL_OES_depth_texture_D;
  bool bGL_OES_depth24_E;
  uint8 field_F;
  bool bGL_EXT_discard_framebuffer_10;
  bool bGL_OES_packed_depth_stencil_11;
  bool bGL_OES_compressed_ETC1_RGB8_texture_12;
  bool bGL_EXT_texture_rg_13;
  bool bMali_14;
  uint8 byte_15;
  uint8 byte_16;
  uint8 byte_17;
  GLint iGL_MAX_TEXTURE_SIZE_18;
  GLfloat fGL_MAX_TEXTURE_MAX_ANISOTROPY_EXT_1C;
  int field_20;
  int field_24;
  GLsizei numAttachments_28;
  GLenum attachments_2C[3];
  bool bWireFrame_38;
  uint8 reserve_39;  //以下三个是对齐用的
  uint8 reserve_3A;
  uint8 reserve_3B;
  void *pBuf_3C;
};

extern CFTTGraphicsDevice *g_pGraphicsDevice;
#endif  //_CFTTGRAPHICSDEVICE_H_