1// This file can be included several times.
2#if(!defined(BACKEND_AS_OPENGL_ES) && !defined(ENGINE_CLIENT_BACKEND_OPENGL_BACKEND_OPENGL_H)) || \
3 (defined(BACKEND_AS_OPENGL_ES) && !defined(ENGINE_CLIENT_BACKEND_OPENGL_BACKEND_OPENGL_H_AS_ES))
4
5#if !defined(BACKEND_AS_OPENGL_ES) && !defined(ENGINE_CLIENT_BACKEND_OPENGL_BACKEND_OPENGL_H)
6#define ENGINE_CLIENT_BACKEND_OPENGL_BACKEND_OPENGL_H
7#endif
8
9#if defined(BACKEND_AS_OPENGL_ES) && !defined(ENGINE_CLIENT_BACKEND_OPENGL_BACKEND_OPENGL_H_AS_ES)
10#define ENGINE_CLIENT_BACKEND_OPENGL_BACKEND_OPENGL_H_AS_ES
11#endif
12
13#include <base/system.h>
14
15#include <engine/client/graphics_defines.h>
16
17#include <engine/client/backend/backend_base.h>
18
19class CGLSLTWProgram;
20class CGLSLPrimitiveProgram;
21class CGLSLTileProgram;
22
23#if defined(BACKEND_AS_OPENGL_ES) && defined(CONF_BACKEND_OPENGL_ES3)
24#define BACKEND_GL_MODERN_API 1
25#endif
26
27// takes care of opengl related rendering
28class CCommandProcessorFragment_OpenGL : public CCommandProcessorFragment_GLBase
29{
30protected:
31 struct CTexture
32 {
33 CTexture() :
34 m_Tex(0), m_Tex2DArray(0), m_Sampler(0), m_Sampler2DArray(0), m_LastWrapMode(CCommandBuffer::WRAP_REPEAT), m_MemSize(0), m_Width(0), m_Height(0), m_RescaleCount(0), m_ResizeWidth(0), m_ResizeHeight(0)
35 {
36 }
37
38 TWGLuint m_Tex;
39 TWGLuint m_Tex2DArray; // or 3D texture as fallback
40 TWGLuint m_Sampler;
41 TWGLuint m_Sampler2DArray; // or 3D texture as fallback
42 int m_LastWrapMode;
43
44 int m_MemSize;
45
46 int m_Width;
47 int m_Height;
48 int m_RescaleCount;
49 float m_ResizeWidth;
50 float m_ResizeHeight;
51 };
52 std::vector<CTexture> m_vTextures;
53 std::atomic<uint64_t> *m_pTextureMemoryUsage;
54
55 uint32_t m_CanvasWidth = 0;
56 uint32_t m_CanvasHeight = 0;
57
58 TWGLint m_MaxTexSize;
59
60 bool m_Has2DArrayTextures;
61 bool m_Has2DArrayTexturesAsExtension;
62 TWGLenum m_2DArrayTarget;
63 bool m_Has3DTextures;
64 bool m_HasMipMaps;
65 bool m_HasNPOTTextures;
66
67 bool m_HasShaders;
68 int m_LastBlendMode; // avoid all possible opengl state changes
69 bool m_LastClipEnable;
70
71 int m_OpenGLTextureLodBIAS;
72
73 bool m_IsOpenGLES;
74
75 bool IsTexturedState(const CCommandBuffer::SState &State);
76
77 bool InitOpenGL(const SCommand_Init *pCommand);
78
79 void SetState(const CCommandBuffer::SState &State, bool Use2DArrayTexture = false);
80 virtual bool IsNewApi() { return false; }
81 void DestroyTexture(int Slot);
82
83 bool GetPresentedImageData(uint32_t &Width, uint32_t &Height, CImageInfo::EImageFormat &Format, std::vector<uint8_t> &vDstData) override;
84
85 static size_t GLFormatToPixelSize(int GLFormat);
86
87 void TextureUpdate(int Slot, int X, int Y, int Width, int Height, int GLFormat, uint8_t *pTexData);
88 void TextureCreate(int Slot, int Width, int Height, int GLFormat, int GLStoreFormat, int Flags, uint8_t *pTexData);
89
90 virtual bool Cmd_Init(const SCommand_Init *pCommand);
91 virtual void Cmd_Shutdown(const SCommand_Shutdown *pCommand) {}
92 virtual void Cmd_Texture_Update(const CCommandBuffer::SCommand_Texture_Update *pCommand);
93 virtual void Cmd_Texture_Destroy(const CCommandBuffer::SCommand_Texture_Destroy *pCommand);
94 virtual void Cmd_Texture_Create(const CCommandBuffer::SCommand_Texture_Create *pCommand);
95 virtual void Cmd_TextTexture_Update(const CCommandBuffer::SCommand_TextTexture_Update *pCommand);
96 virtual void Cmd_TextTextures_Destroy(const CCommandBuffer::SCommand_TextTextures_Destroy *pCommand);
97 virtual void Cmd_TextTextures_Create(const CCommandBuffer::SCommand_TextTextures_Create *pCommand);
98 virtual void Cmd_Clear(const CCommandBuffer::SCommand_Clear *pCommand);
99 virtual void Cmd_Render(const CCommandBuffer::SCommand_Render *pCommand);
100 virtual void Cmd_RenderTex3D(const CCommandBuffer::SCommand_RenderTex3D *pCommand) { dbg_assert(false, "Call of unsupported Cmd_RenderTex3D"); }
101 virtual void Cmd_ReadPixel(const CCommandBuffer::SCommand_TrySwapAndReadPixel *pCommand);
102 virtual void Cmd_Screenshot(const CCommandBuffer::SCommand_TrySwapAndScreenshot *pCommand);
103
104 virtual void Cmd_Update_Viewport(const CCommandBuffer::SCommand_Update_Viewport *pCommand);
105
106 virtual void Cmd_CreateBufferObject(const CCommandBuffer::SCommand_CreateBufferObject *pCommand) { dbg_assert(false, "Call of unsupported Cmd_CreateBufferObject"); }
107 virtual void Cmd_RecreateBufferObject(const CCommandBuffer::SCommand_RecreateBufferObject *pCommand) { dbg_assert(false, "Call of unsupported Cmd_RecreateBufferObject"); }
108 virtual void Cmd_UpdateBufferObject(const CCommandBuffer::SCommand_UpdateBufferObject *pCommand) { dbg_assert(false, "Call of unsupported Cmd_UpdateBufferObject"); }
109 virtual void Cmd_CopyBufferObject(const CCommandBuffer::SCommand_CopyBufferObject *pCommand) { dbg_assert(false, "Call of unsupported Cmd_CopyBufferObject"); }
110 virtual void Cmd_DeleteBufferObject(const CCommandBuffer::SCommand_DeleteBufferObject *pCommand) { dbg_assert(false, "Call of unsupported Cmd_DeleteBufferObject"); }
111
112 virtual void Cmd_CreateBufferContainer(const CCommandBuffer::SCommand_CreateBufferContainer *pCommand) { dbg_assert(false, "Call of unsupported Cmd_CreateBufferContainer"); }
113 virtual void Cmd_UpdateBufferContainer(const CCommandBuffer::SCommand_UpdateBufferContainer *pCommand) { dbg_assert(false, "Call of unsupported Cmd_UpdateBufferContainer"); }
114 virtual void Cmd_DeleteBufferContainer(const CCommandBuffer::SCommand_DeleteBufferContainer *pCommand) { dbg_assert(false, "Call of unsupported Cmd_DeleteBufferContainer"); }
115 virtual void Cmd_IndicesRequiredNumNotify(const CCommandBuffer::SCommand_IndicesRequiredNumNotify *pCommand) { dbg_assert(false, "Call of unsupported Cmd_IndicesRequiredNumNotify"); }
116
117 virtual void Cmd_RenderTileLayer(const CCommandBuffer::SCommand_RenderTileLayer *pCommand) { dbg_assert(false, "Call of unsupported Cmd_RenderTileLayer"); }
118 virtual void Cmd_RenderBorderTile(const CCommandBuffer::SCommand_RenderBorderTile *pCommand) { dbg_assert(false, "Call of unsupported Cmd_RenderBorderTile"); }
119 virtual void Cmd_RenderQuadLayer(const CCommandBuffer::SCommand_RenderQuadLayer *pCommand) { dbg_assert(false, "Call of unsupported Cmd_RenderQuadLayer"); }
120 virtual void Cmd_RenderText(const CCommandBuffer::SCommand_RenderText *pCommand) { dbg_assert(false, "Call of unsupported Cmd_RenderText"); }
121 virtual void Cmd_RenderQuadContainer(const CCommandBuffer::SCommand_RenderQuadContainer *pCommand) { dbg_assert(false, "Call of unsupported Cmd_RenderQuadContainer"); }
122 virtual void Cmd_RenderQuadContainerEx(const CCommandBuffer::SCommand_RenderQuadContainerEx *pCommand) { dbg_assert(false, "Call of unsupported Cmd_RenderQuadContainerEx"); }
123 virtual void Cmd_RenderQuadContainerAsSpriteMultiple(const CCommandBuffer::SCommand_RenderQuadContainerAsSpriteMultiple *pCommand) { dbg_assert(false, "Call of unsupported Cmd_RenderQuadContainerAsSpriteMultiple"); }
124
125public:
126 CCommandProcessorFragment_OpenGL();
127 virtual ~CCommandProcessorFragment_OpenGL() = default;
128
129 ERunCommandReturnTypes RunCommand(const CCommandBuffer::SCommand *pBaseCommand) override;
130};
131
132class CCommandProcessorFragment_OpenGL2 : public CCommandProcessorFragment_OpenGL
133{
134 struct SBufferContainer
135 {
136 SBufferContainerInfo m_ContainerInfo;
137 };
138 std::vector<SBufferContainer> m_vBufferContainers;
139
140#ifndef BACKEND_AS_OPENGL_ES
141 GL_SVertexTex3D m_aStreamVertices[1024 * 4];
142#endif
143
144 struct SBufferObject
145 {
146 SBufferObject(TWGLuint BufferObjectId) :
147 m_BufferObjectId(BufferObjectId)
148 {
149 m_pData = NULL;
150 m_DataSize = 0;
151 }
152 TWGLuint m_BufferObjectId;
153 uint8_t *m_pData;
154 size_t m_DataSize;
155 };
156
157 std::vector<SBufferObject> m_vBufferObjectIndices;
158
159#ifndef BACKEND_GL_MODERN_API
160 bool DoAnalyzeStep(size_t CheckCount, size_t VerticesCount, uint8_t aFakeTexture[], size_t SingleImageSize);
161 bool IsTileMapAnalysisSucceeded();
162#endif
163
164 void UseProgram(CGLSLTWProgram *pProgram);
165
166protected:
167 void SetState(const CCommandBuffer::SState &State, CGLSLTWProgram *pProgram, bool Use2DArrayTextures = false);
168
169#ifndef BACKEND_GL_MODERN_API
170 bool Cmd_Init(const SCommand_Init *pCommand) override;
171 void Cmd_Shutdown(const SCommand_Shutdown *pCommand) override;
172
173 void Cmd_RenderTex3D(const CCommandBuffer::SCommand_RenderTex3D *pCommand) override;
174
175 void Cmd_CreateBufferObject(const CCommandBuffer::SCommand_CreateBufferObject *pCommand) override;
176 void Cmd_RecreateBufferObject(const CCommandBuffer::SCommand_RecreateBufferObject *pCommand) override;
177 void Cmd_UpdateBufferObject(const CCommandBuffer::SCommand_UpdateBufferObject *pCommand) override;
178 void Cmd_CopyBufferObject(const CCommandBuffer::SCommand_CopyBufferObject *pCommand) override;
179 void Cmd_DeleteBufferObject(const CCommandBuffer::SCommand_DeleteBufferObject *pCommand) override;
180
181 void Cmd_CreateBufferContainer(const CCommandBuffer::SCommand_CreateBufferContainer *pCommand) override;
182 void Cmd_UpdateBufferContainer(const CCommandBuffer::SCommand_UpdateBufferContainer *pCommand) override;
183 void Cmd_DeleteBufferContainer(const CCommandBuffer::SCommand_DeleteBufferContainer *pCommand) override;
184 void Cmd_IndicesRequiredNumNotify(const CCommandBuffer::SCommand_IndicesRequiredNumNotify *pCommand) override;
185
186 void Cmd_RenderTileLayer(const CCommandBuffer::SCommand_RenderTileLayer *pCommand) override;
187 void Cmd_RenderBorderTile(const CCommandBuffer::SCommand_RenderBorderTile *pCommand) override;
188#endif
189
190 CGLSLTileProgram *m_pTileProgram;
191 CGLSLTileProgram *m_pTileProgramTextured;
192 CGLSLTileProgram *m_pBorderTileProgram;
193 CGLSLTileProgram *m_pBorderTileProgramTextured;
194 CGLSLPrimitiveProgram *m_pPrimitive3DProgram;
195 CGLSLPrimitiveProgram *m_pPrimitive3DProgramTextured;
196};
197
198class CCommandProcessorFragment_OpenGL3 : public CCommandProcessorFragment_OpenGL2
199{
200};
201
202#if defined(BACKEND_AS_OPENGL_ES) && defined(CONF_BACKEND_OPENGL_ES3)
203#undef BACKEND_GL_MODERN_API
204#endif
205
206#endif
207