1/*
2* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
3*
4* Permission is hereby granted, free of charge, to any person obtaining a copy
5* of this software and associated documentation files (the "Software"), to deal
6* in the Software without restriction, including without limitation the rights
7* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8* copies of the Software, and to permit persons to whom the Software is
9* furnished to do so, subject to the following conditions:
10*
11* The above copyright notice and this permission notice shall be included in
12* all copies or substantial portions of the Software.
13*
14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20* THE SOFTWARE.
21*/
22
23#ifndef PAINTER_H
24#define PAINTER_H
25
26#include <framework/graphics/declarations.h>
27#include <framework/graphics/coordsbuffer.h>
28#include <framework/graphics/paintershaderprogram.h>
29#include <framework/graphics/texture.h>
30#include <framework/graphics/colorarray.h>
31#include <framework/graphics/drawqueue.h>
32
33class Painter {
34public:
35 enum BlendEquation {
36 BlendEquation_Add,
37 BlendEquation_Max,
38 BlendEquation_Subtract
39 };
40 enum CompositionMode {
41 CompositionMode_Normal,
42 CompositionMode_Multiply,
43 CompositionMode_Add,
44 CompositionMode_Replace,
45 CompositionMode_DestBlending,
46 CompositionMode_Light,
47 CompositionMode_AlphaZeroing,
48 CompositionMode_AlphaRestoring,
49 CompositionMode_ZeroAlphaOverrite
50
51 };
52 enum DepthFunc {
53 DepthFunc_None,
54 DepthFunc_LESS,
55 DepthFunc_LESS_READ,
56 DepthFunc_LEQUAL,
57 DepthFunc_LEQUAL_READ,
58 DepthFunc_EQUAL,
59 DepthFunc_ALWAYS,
60 DepthFunc_ALWAYS_READ
61 };
62 enum DrawMode {
63 Triangles = GL_TRIANGLES,
64 TriangleStrip = GL_TRIANGLE_STRIP
65 };
66
67 struct PainterState {
68 Size resolution;
69 Matrix3 transformMatrix;
70 Matrix3 projectionMatrix;
71 Matrix3 textureMatrix;
72 Color color;
73 Painter::CompositionMode compositionMode;
74 Painter::BlendEquation blendEquation;
75 Rect clipRect;
76 TexturePtr texture;
77 PainterShaderProgram* shaderProgram;
78 bool alphaWriting;
79#ifdef WITH_DEPTH_BUFFER
80 Painter::DepthFunc depthFunc;
81 float depth;
82#endif
83 };
84
85 Painter();
86 ~Painter() {}
87
88 void bind();
89 void unbind();
90
91 void resetState();
92 void refreshState();
93 void saveState();
94 void saveAndResetState();
95 void restoreSavedState();
96
97 void clear(const Color& color);
98 void clearRect(const Color& color, const Rect& rect);
99
100 void setTransformMatrix(const Matrix3& transformMatrix) { m_transformMatrix = transformMatrix; }
101 void setProjectionMatrix(const Matrix3& projectionMatrix) { m_projectionMatrix = projectionMatrix; }
102 void setTextureMatrix(const Matrix3& textureMatrix) { m_textureMatrix = textureMatrix; }
103 void setCompositionMode(CompositionMode compositionMode);
104 void setBlendEquation(BlendEquation blendEquation);
105#ifdef WITH_DEPTH_BUFFER
106 void setDepthFunc(DepthFunc func);
107#endif
108 void setClipRect(const Rect& clipRect);
109 void setShaderProgram(PainterShaderProgram* shaderProgram) { m_shaderProgram = shaderProgram; }
110 void setTexture(const TexturePtr& texture);
111 void setAlphaWriting(bool enable);
112
113 void setResolution(const Size& resolution);
114
115 void scale(float x, float y);
116 void translate(float x, float y);
117 void rotate(float angle);
118 void rotate(float x, float y, float angle);
119
120 void pushTransformMatrix();
121 void popTransformMatrix();
122
123 Matrix3 getTransformMatrix() { return m_transformMatrix; }
124 Matrix3 getProjectionMatrix() { return m_projectionMatrix; }
125 Matrix3 getTextureMatrix() { return m_textureMatrix; }
126 BlendEquation getBlendEquation() { return m_blendEquation; }
127 PainterShaderProgram* getShaderProgram() { return m_shaderProgram; }
128 bool getAlphaWriting() { return m_alphaWriting; }
129
130 void resetBlendEquation() { setBlendEquation(BlendEquation_Add); }
131 void resetTexture() { setTexture(nullptr); }
132 void resetAlphaWriting() { setAlphaWriting(true); }
133 void resetTransformMatrix() { setTransformMatrix(Matrix3()); }
134
135 /* org */
136 void drawCoords(CoordsBuffer& coordsBuffer, DrawMode drawMode = Triangles, ColorArray* colorBuffer = nullptr, const std::vector<std::pair<int, Color>>* colors = nullptr);
137 void drawFillCoords(CoordsBuffer& coordsBuffer);
138 void drawTextureCoords(CoordsBuffer& coordsBuffer, const TexturePtr& texture, const std::vector<std::pair<int, Color>>* colors = nullptr);
139 void drawTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src);
140 inline void drawTexturedRect(const Rect& dest, const TexturePtr& texture) { drawTexturedRect(dest, texture, Rect(Point(0, 0), texture->getSize())); }
141 void drawColorOnTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src);
142 void drawUpsideDownTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src);
143 void drawRepeatedTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src);
144 void drawFilledRect(const Rect& dest);
145
146 void setDrawProgram(PainterShaderProgram* drawProgram) { m_drawProgram = drawProgram; }
147 bool hasShaders() { return true; }
148
149 void drawText(const Point& pos, CoordsBuffer& coordsBuffer, const Color& color, const TexturePtr& texture);
150 void drawText(const Point& pos, CoordsBuffer& coordsBuffer, const std::vector<std::pair<int, Color>>& colors, const TexturePtr& texture);
151
152 void drawLine(const std::vector<float>& vertex, int size, int width = 1);
153
154 void setSecondTexture(const TexturePtr& texture);
155 void setOffset(const Point& offset);
156
157 void setAtlasTextures(const TexturePtr& atlas);
158 void drawCache(const std::vector<float>& vertex, const std::vector<float>& texture, const std::vector<float>& color, int size);
159
160 void setColor(const Color& color) { m_color = color; }
161 void setShaderProgram(const PainterShaderProgramPtr& shaderProgram) { setShaderProgram(shaderProgram.get()); }
162
163 void scale(float factor) { scale(factor, factor); }
164 void translate(const Point& p) { translate(p.x, p.y); }
165 void rotate(const Point& p, float angle) { rotate(p.x, p.y, angle); }
166
167#ifdef WITH_DEPTH_BUFFER
168 void setDepth(float depth) { m_depth = depth; }
169 float getDepth() { return m_depth; }
170 DepthFunc getDepthFunc() { return m_depthFunc; }
171 void resetDepth() { return setDepth(0.0f); }
172 void resetDepthFunc() { setDepthFunc(DepthFunc_None); }
173#endif
174
175 Size getResolution() { return m_resolution; }
176 Color getColor() { return m_color; }
177 Rect getClipRect() { return m_clipRect; }
178 CompositionMode getCompositionMode() { return m_compositionMode; }
179
180 void resetClipRect() { setClipRect(Rect()); }
181 void resetCompositionMode() { setCompositionMode(CompositionMode_Normal); }
182 void resetColor() { setColor(Color::white); }
183 void resetShaderProgram() { setShaderProgram(nullptr); }
184
185 int draws() { return m_draws; }
186 int calls() { return m_calls; }
187 void resetDraws() { m_draws = m_calls = 0; }
188
189 void setDrawColorOnTextureShaderProgram()
190 {
191 setShaderProgram(m_drawSolidColorOnTextureProgram);
192 }
193
194 void setMatrixColor(const Matrix4& mat4)
195 {
196 m_matrixColor = mat4;
197 }
198 void setDrawOutfitLayersProgram()
199 {
200 setShaderProgram(m_drawOutfitLayersProgram);
201 }
202
203protected:
204 void updateGlTexture();
205 void updateGlCompositionMode();
206 void updateGlBlendEquation();
207 void updateGlClipRect();
208 void updateGlAlphaWriting();
209 void updateGlViewport();
210#ifdef WITH_DEPTH_BUFFER
211 void updateDepthFunc();
212#endif
213
214 CoordsBuffer m_coordsBuffer;
215
216 std::vector<Matrix3> m_transformMatrixStack;
217 Matrix3 m_transformMatrix;
218 Matrix3 m_projectionMatrix;
219 Matrix3 m_textureMatrix;
220 Matrix3 m_atlasTextureMatrix;
221
222 BlendEquation m_blendEquation;
223 TexturePtr m_texture;
224 bool m_alphaWriting;
225
226 PainterState m_olderStates[10];
227 int m_oldStateIndex;
228
229 uint m_glTextureId;
230
231 PainterShaderProgram* m_shaderProgram;
232 CompositionMode m_compositionMode;
233 Color m_color;
234 Matrix4 m_matrixColor;
235 Size m_resolution;
236 Rect m_clipRect;
237#ifdef WITH_DEPTH_BUFFER
238 DepthFunc m_depthFunc;
239 float m_depth;
240#endif
241 int m_draws = 0;
242 int m_calls = 0;
243
244private:
245 PainterShaderProgram* m_drawProgram;
246 PainterShaderProgramPtr m_drawTexturedProgram;
247 PainterShaderProgramPtr m_drawSolidColorProgram;
248 PainterShaderProgramPtr m_drawSolidColorOnTextureProgram;
249 PainterShaderProgramPtr m_drawOutfitLayersProgram;
250
251 PainterShaderProgramPtr m_drawNewProgram;
252
253 PainterShaderProgramPtr m_drawTextProgram;
254 PainterShaderProgramPtr m_drawLineProgram;
255};
256
257extern Painter* g_painter;
258
259#endif
260