Otclient 1.0  14/8/2020
painterogl1.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010-2020 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 #if !defined(OPENGL_ES) || OPENGL_ES==1
24 
25 #include "painterogl1.h"
27 
29 
31 {
32  m_matrixMode = GL_PROJECTION;
33  resetState();
34 }
35 
37 {
39  updateGlColor();
40  updateGlMatrixMode();
41  updateGlTransformMatrix();
42  updateGlProjectionMatrix();
43  updateGlTextureMatrix();
44  updateGlTextureState();
45 }
46 
48 {
50 
51  // vertex and texture coord arrays are always enabled
52  // to avoid massive enable/disables, thus improving frame rate
54  glEnableClientState(GL_VERTEX_ARRAY);
55 }
56 
58 {
60  glDisableClientState(GL_VERTEX_ARRAY);
61 }
62 
63 void PainterOGL1::drawCoords(CoordsBuffer& coordsBuffer, DrawMode drawMode)
64 {
65  int vertexCount = coordsBuffer.getVertexCount();
66  if (vertexCount == 0)
67  return;
68 
69  bool textured = coordsBuffer.getTextureCoordCount() != 0 && m_texture;
70 
71  // skip drawing of empty textures
72  if (textured && m_texture->isEmpty())
73  return;
74 
75  if (textured != m_textureEnabled) {
76  m_textureEnabled = textured;
77  updateGlTextureState();
78  }
79 
80  // GDI Generic driver has this bug
83 
84  // use vertex arrays if possible, much faster
86  // update coords buffer hardware caches if enabled
87  coordsBuffer.updateCaches();
88  bool hardwareCached = coordsBuffer.isHardwareCached();
89 
90  // only set texture coords arrays when needed
91  if (textured) {
92  if (hardwareCached) {
93  coordsBuffer.getHardwareTextureCoordArray()->bind();
94  glTexCoordPointer(2, GL_FLOAT, 0, nullptr);
95  }
96  else
97  glTexCoordPointer(2, GL_FLOAT, 0, coordsBuffer.getTextureCoordArray());
98  }
99 
100  // set vertex array
101  if (hardwareCached) {
102  coordsBuffer.getHardwareVertexArray()->bind();
103  glVertexPointer(2, GL_FLOAT, 0, nullptr);
104  }
105  else
106  glVertexPointer(2, GL_FLOAT, 0, coordsBuffer.getVertexArray());
107 
108  if (hardwareCached)
110 
111  // draw the element in coords buffers
112  if (drawMode == Triangles)
113  glDrawArrays(GL_TRIANGLES, 0, vertexCount);
114  else if (drawMode == TriangleStrip)
115  glDrawArrays(GL_TRIANGLE_STRIP, 0, vertexCount);
116  }
117 #ifndef OPENGL_ES
118  else {
119  int verticesSize = vertexCount * 2;
120  float* vertices = coordsBuffer.getVertexArray();
121  float* texCoords = coordsBuffer.getTextureCoordArray();
122 
123  // use glBegin/glEnd, this is not available in OpenGL ES
124  // and is considered much slower then glDrawArrays,
125  // but this code is executed in really old graphics cards
126  if (drawMode == Triangles)
127  glBegin(GL_TRIANGLES);
128  else if (drawMode == TriangleStrip)
129  glBegin(GL_TRIANGLE_STRIP);
130  for (int i = 0; i < verticesSize; i += 2) {
131  if (textured)
132  glTexCoord2f(texCoords[i], texCoords[i + 1]);
133  glVertex2f(vertices[i], vertices[i + 1]);
134  }
135  glEnd();
136  }
137 #endif
138 }
139 
141 {
142  setTexture(nullptr);
143  drawCoords(coordsBuffer);
144 }
145 
146 void PainterOGL1::drawTextureCoords(CoordsBuffer& coordsBuffer, const TexturePtr& texture)
147 {
148  if (texture->isEmpty())
149  return;
150 
151  setTexture(texture.get());
152  drawCoords(coordsBuffer);
153 }
154 
155 void PainterOGL1::drawTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src)
156 {
157  if (dest.isEmpty() || src.isEmpty() || texture->isEmpty())
158  return;
159 
160  setTexture(texture.get());
161 
163  m_coordsBuffer.addQuad(dest, src);
165 }
166 
167 void PainterOGL1::drawUpsideDownTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src)
168 {
169  if (dest.isEmpty() || src.isEmpty() || texture->isEmpty())
170  return;
171 
172  setTexture(texture.get());
173 
177 }
178 
179 void PainterOGL1::drawRepeatedTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src)
180 {
181  if (dest.isEmpty() || src.isEmpty() || texture->isEmpty())
182  return;
183 
184  setTexture(texture.get());
185 
187  m_coordsBuffer.addRepeatedRects(dest, src);
189 }
190 
192 {
193  if (dest.isEmpty())
194  return;
195 
196  setTexture(nullptr);
197 
199  m_coordsBuffer.addRect(dest);
201 }
202 
203 void PainterOGL1::drawFilledTriangle(const Point& a, const Point& b, const Point& c)
204 {
205  if (a == b || a == c || b == c)
206  return;
207 
208  setTexture(nullptr);
209 
211  m_coordsBuffer.addTriangle(a, b, c);
213 }
214 
215 void PainterOGL1::drawBoundingRect(const Rect& dest, int innerLineWidth)
216 {
217  if (dest.isEmpty() || innerLineWidth == 0)
218  return;
219 
220  setTexture(nullptr);
221 
223  m_coordsBuffer.addBoudingRect(dest, innerLineWidth);
225 }
226 
228 {
229  if (m_matrixMode == static_cast<GLenum>(matrixMode))
230  return;
231 
232  m_matrixMode = matrixMode;
233  updateGlMatrixMode();
234 }
235 
236 void PainterOGL1::setTransformMatrix(const Matrix3& transformMatrix)
237 {
238  m_transformMatrix = transformMatrix;
239  if (g_painter == this)
240  updateGlTransformMatrix();
241 }
242 
243 void PainterOGL1::setProjectionMatrix(const Matrix3& projectionMatrix)
244 {
245  m_projectionMatrix = projectionMatrix;
246  if (g_painter == this)
247  updateGlProjectionMatrix();
248 }
249 
250 void PainterOGL1::setTextureMatrix(const Matrix3& textureMatrix)
251 {
252  // avoid re-updating texture matrix
253  if (m_textureMatrix == textureMatrix)
254  return;
255  m_textureMatrix = textureMatrix;
256  updateGlTextureMatrix();
257 }
258 
259 void PainterOGL1::setColor(const Color& color)
260 {
261  if (m_color == color)
262  return;
263  m_color = color;
264  updateGlColor();
265 }
266 
267 void PainterOGL1::setOpacity(float opacity)
268 {
269  if (m_opacity == opacity)
270  return;
271  m_opacity = opacity;
272  updateGlColor();
273 }
274 
275 void PainterOGL1::updateGlColor()
276 {
277  glColor4f(m_color.rF(), m_color.gF(), m_color.bF(), m_color.aF() * m_opacity);
278 }
279 
280 void PainterOGL1::updateGlMatrixMode()
281 {
282  glMatrixMode(m_matrixMode);
283 }
284 
285 void PainterOGL1::updateGlTransformMatrix()
286 {
287  float glTransformMatrix[] = {
290  0.0f, 0.0f, 1.0f, 0.0f,
292  };
293 
295  glLoadMatrixf(glTransformMatrix);
296 }
297 
298 void PainterOGL1::updateGlProjectionMatrix()
299 {
300  float glProjectionMatrix[] = {
303  0.0f, 0.0f, 1.0f, 0.0f,
305  };
306 
308  glLoadMatrixf(glProjectionMatrix);
309 }
310 
311 void PainterOGL1::updateGlTextureMatrix()
312 {
313  float glTextureMatrix[] = {
314  m_textureMatrix(1,1), m_textureMatrix(1,2), 0.0f, 0.0f,
315  m_textureMatrix(2,1), m_textureMatrix(2,2), 0.0f, 0.0f,
316  0.0f, 0.0f, 1.0f, 0.0f,
317  m_textureMatrix(3,1), m_textureMatrix(3,2), 0.0f, m_textureMatrix(3,3),
318  };
319 
321  glLoadMatrixf(glTextureMatrix);
322 }
323 
324 void PainterOGL1::updateGlTextureState()
325 {
326  if (m_textureEnabled) {
327  glEnable(GL_TEXTURE_2D);
329  glEnableClientState(GL_TEXTURE_COORD_ARRAY);
330  }
331  else {
332  glDisable(GL_TEXTURE_2D);
334  glDisableClientState(GL_TEXTURE_COORD_ARRAY);
335  }
336 }
337 
338 #endif
PainterOGL1::unbind
void unbind()
Definition: painterogl1.cpp:57
CoordsBuffer::addRepeatedRects
void addRepeatedRects(const Rect &dest, const Rect &src)
Definition: coordsbuffer.cpp:57
PainterOGL1::drawFilledTriangle
void drawFilledTriangle(const Point &a, const Point &b, const Point &c)
Definition: painterogl1.cpp:203
PainterOGL1::drawUpsideDownTexturedRect
void drawUpsideDownTexturedRect(const Rect &dest, const TexturePtr &texture, const Rect &src)
Definition: painterogl1.cpp:167
PainterOGL1::MatrixTransform
@ MatrixTransform
Definition: painterogl1.h:42
graphics.h
CoordsBuffer::getVertexArray
float * getVertexArray()
Definition: coordsbuffer.h:75
Color
Definition: color.h:32
HardwareBuffer::bind
void bind()
Definition: hardwarebuffer.h:46
Painter::TriangleStrip
@ TriangleStrip
Definition: painter.h:48
TRect< int >
PainterOGL::m_textureMatrix
Matrix3 m_textureMatrix
Definition: painterogl.h:107
Painter::m_opacity
float m_opacity
Definition: painter.h:118
Color::rF
float rF() const
Definition: color.h:52
PainterOGL::resetState
void resetState()
Definition: painterogl.cpp:41
Color::gF
float gF() const
Definition: color.h:51
PainterOGL::m_texture
Texture * m_texture
Definition: painterogl.h:110
PainterOGL::updateGlClipRect
void updateGlClipRect()
Definition: painterogl.cpp:295
PainterOGL1::setProjectionMatrix
void setProjectionMatrix(const Matrix3 &projectionMatrix)
Definition: painterogl1.cpp:243
CoordsBuffer::addUpsideDownQuad
void addUpsideDownQuad(const Rect &dest, const Rect &src)
Definition: coordsbuffer.h:62
PainterOGL1::setMatrixMode
void setMatrixMode(MatrixMode matrixMode)
Definition: painterogl1.cpp:227
TRect::isEmpty
bool isEmpty() const
Definition: rect.h:49
PainterOGL1::drawFilledRect
void drawFilledRect(const Rect &dest)
Definition: painterogl1.cpp:191
Graphics::canUseDrawArrays
bool canUseDrawArrays()
Definition: graphics.cpp:267
Painter::DrawMode
DrawMode
Definition: painter.h:46
Graphics::hasScissorBug
bool hasScissorBug()
Definition: graphics.cpp:416
PainterOGL::m_coordsBuffer
CoordsBuffer m_coordsBuffer
Definition: painterogl.h:102
CoordsBuffer::getTextureCoordCount
int getTextureCoordCount()
Definition: coordsbuffer.h:78
PainterOGL::bind
virtual void bind()
Definition: painterogl.h:49
HardwareBuffer::unbind
static void unbind(Type type)
Definition: hardwarebuffer.h:47
HardwareBuffer::VertexBuffer
@ VertexBuffer
Definition: hardwarebuffer.h:33
PainterOGL1::bind
void bind()
Definition: painterogl1.cpp:47
g_painterOGL1
PainterOGL1 * g_painterOGL1
Definition: painterogl1.cpp:28
PainterOGL1::PainterOGL1
PainterOGL1()
Definition: painterogl1.cpp:30
PainterOGL1
Definition: painterogl1.h:36
CoordsBuffer::getVertexCount
int getVertexCount()
Definition: coordsbuffer.h:77
Painter::m_color
Color m_color
Definition: painter.h:116
CoordsBuffer::updateCaches
void updateCaches()
Definition: coordsbuffer.cpp:96
CoordsBuffer::isHardwareCached
bool isHardwareCached()
Definition: coordsbuffer.h:73
PainterOGL1::setTextureMatrix
void setTextureMatrix(const Matrix3 &textureMatrix)
Definition: painterogl1.cpp:250
Painter::Triangles
@ Triangles
Definition: painter.h:47
CoordsBuffer::clear
void clear()
Definition: coordsbuffer.h:38
PainterOGL1::MatrixMode
MatrixMode
Definition: painterogl1.h:39
PainterOGL1::drawRepeatedTexturedRect
void drawRepeatedTexturedRect(const Rect &dest, const TexturePtr &texture, const Rect &src)
Definition: painterogl1.cpp:179
g_graphics
Graphics g_graphics
Definition: graphics.cpp:44
CoordsBuffer::addBoudingRect
void addBoudingRect(const Rect &dest, int innerLineWidth)
Definition: coordsbuffer.cpp:41
PainterOGL::m_transformMatrix
Matrix3 m_transformMatrix
Definition: painterogl.h:105
Color::aF
float aF() const
Definition: color.h:49
CoordsBuffer::getHardwareTextureCoordArray
HardwareBuffer * getHardwareTextureCoordArray()
Definition: coordsbuffer.h:81
PainterOGL1::refreshState
void refreshState()
Definition: painterogl1.cpp:36
Color::bF
float bF() const
Definition: color.h:50
PainterOGL1::MatrixProjection
@ MatrixProjection
Definition: painterogl1.h:40
Texture::isEmpty
bool isEmpty()
Definition: texture.h:53
stdext::shared_object_ptr< Texture >
CoordsBuffer
Definition: coordsbuffer.h:29
CoordsBuffer::addRect
void addRect(const Rect &dest)
Definition: coordsbuffer.h:48
PainterOGL1::drawFillCoords
void drawFillCoords(CoordsBuffer &coordsBuffer)
Definition: painterogl1.cpp:140
g_painter
Painter * g_painter
Definition: painter.cpp:28
PainterOGL1::drawTextureCoords
void drawTextureCoords(CoordsBuffer &coordsBuffer, const TexturePtr &texture)
Definition: painterogl1.cpp:146
PainterOGL::m_projectionMatrix
Matrix3 m_projectionMatrix
Definition: painterogl.h:106
PainterOGL1::drawBoundingRect
void drawBoundingRect(const Rect &dest, int innerLineWidth)
Definition: painterogl1.cpp:215
painterogl1.h
PainterOGL::setTexture
virtual void setTexture(Texture *texture)
Definition: painterogl.cpp:144
CoordsBuffer::getHardwareVertexArray
HardwareBuffer * getHardwareVertexArray()
Definition: coordsbuffer.h:80
Matrix
Definition: matrix.h:32
TPoint< int >
PainterOGL1::setOpacity
void setOpacity(float opacity)
Definition: painterogl1.cpp:267
CoordsBuffer::addQuad
void addQuad(const Rect &dest, const Rect &src)
Definition: coordsbuffer.h:57
CoordsBuffer::getTextureCoordArray
float * getTextureCoordArray()
Definition: coordsbuffer.h:76
PainterOGL1::MatrixTexture
@ MatrixTexture
Definition: painterogl1.h:41
PainterOGL1::setTransformMatrix
void setTransformMatrix(const Matrix3 &transformMatrix)
Definition: painterogl1.cpp:236
CoordsBuffer::addTriangle
void addTriangle(const Point &a, const Point &b, const Point &c)
Definition: coordsbuffer.h:44
PainterOGL1::drawTexturedRect
void drawTexturedRect(const Rect &dest, const TexturePtr &texture, const Rect &src)
Definition: painterogl1.cpp:155
stdext::shared_object_ptr::get
T * get() const
Definition: shared_object.h:82
PainterOGL1::drawCoords
void drawCoords(CoordsBuffer &coordsBuffer, DrawMode drawMode=Triangles)
Definition: painterogl1.cpp:63
PainterOGL1::setColor
void setColor(const Color &color)
Definition: painterogl1.cpp:259
PainterOGL::refreshState
virtual void refreshState()
Definition: painterogl.cpp:54