Otclient  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  } else
96  glTexCoordPointer(2, GL_FLOAT, 0, coordsBuffer.getTextureCoordArray());
97  }
98 
99  // set vertex array
100  if(hardwareCached) {
101  coordsBuffer.getHardwareVertexArray()->bind();
102  glVertexPointer(2, GL_FLOAT, 0, nullptr);
103  } else
104  glVertexPointer(2, GL_FLOAT, 0, coordsBuffer.getVertexArray());
105 
106  if(hardwareCached)
108 
109  // draw the element in coords buffers
110  if(drawMode == Triangles)
111  glDrawArrays(GL_TRIANGLES, 0, vertexCount);
112  else if(drawMode == TriangleStrip)
113  glDrawArrays(GL_TRIANGLE_STRIP, 0, vertexCount);
114  }
115 #ifndef OPENGL_ES
116  else {
117  int verticesSize = vertexCount*2;
118  float *vertices = coordsBuffer.getVertexArray();
119  float *texCoords = coordsBuffer.getTextureCoordArray();
120 
121  // use glBegin/glEnd, this is not available in OpenGL ES
122  // and is considered much slower then glDrawArrays,
123  // but this code is executed in really old graphics cards
124  if(drawMode == Triangles)
125  glBegin(GL_TRIANGLES);
126  else if(drawMode == TriangleStrip)
127  glBegin(GL_TRIANGLE_STRIP);
128  for(int i=0;i<verticesSize;i+=2) {
129  if(textured)
130  glTexCoord2f(texCoords[i], texCoords[i+1]);
131  glVertex2f(vertices[i], vertices[i+1]);
132  }
133  glEnd();
134  }
135 #endif
136 }
137 
139 {
140  setTexture(nullptr);
141  drawCoords(coordsBuffer);
142 }
143 
144 void PainterOGL1::drawTextureCoords(CoordsBuffer& coordsBuffer, const TexturePtr& texture)
145 {
146  if(texture->isEmpty())
147  return;
148 
149  setTexture(texture.get());
150  drawCoords(coordsBuffer);
151 }
152 
153 void PainterOGL1::drawTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src)
154 {
155  if(dest.isEmpty() || src.isEmpty() || texture->isEmpty())
156  return;
157 
158  setTexture(texture.get());
159 
161  m_coordsBuffer.addQuad(dest, src);
163 }
164 
165 void PainterOGL1::drawUpsideDownTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src)
166 {
167  if(dest.isEmpty() || src.isEmpty() || texture->isEmpty())
168  return;
169 
170  setTexture(texture.get());
171 
175 }
176 
177 void PainterOGL1::drawRepeatedTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src)
178 {
179  if(dest.isEmpty() || src.isEmpty() || texture->isEmpty())
180  return;
181 
182  setTexture(texture.get());
183 
185  m_coordsBuffer.addRepeatedRects(dest, src);
187 }
188 
190 {
191  if(dest.isEmpty())
192  return;
193 
194  setTexture(nullptr);
195 
197  m_coordsBuffer.addRect(dest);
199 }
200 
201 void PainterOGL1::drawFilledTriangle(const Point& a, const Point& b, const Point& c)
202 {
203  if(a == b || a == c || b == c)
204  return;
205 
206  setTexture(nullptr);
207 
209  m_coordsBuffer.addTriangle(a, b, c);
211 }
212 
213 void PainterOGL1::drawBoundingRect(const Rect& dest, int innerLineWidth)
214 {
215  if(dest.isEmpty() || innerLineWidth == 0)
216  return;
217 
218  setTexture(nullptr);
219 
221  m_coordsBuffer.addBoudingRect(dest, innerLineWidth);
223 }
224 
226 {
227  if(m_matrixMode == matrixMode)
228  return;
229  m_matrixMode = matrixMode;
230  updateGlMatrixMode();
231 }
232 
233 void PainterOGL1::setTransformMatrix(const Matrix3& transformMatrix)
234 {
235  m_transformMatrix = transformMatrix;
236  if(g_painter == this)
237  updateGlTransformMatrix();
238 }
239 
240 void PainterOGL1::setProjectionMatrix(const Matrix3& projectionMatrix)
241 {
242  m_projectionMatrix = projectionMatrix;
243  if(g_painter == this)
244  updateGlProjectionMatrix();
245 }
246 
247 void PainterOGL1::setTextureMatrix(const Matrix3& textureMatrix)
248 {
249  // avoid re-updating texture matrix
250  if(m_textureMatrix == textureMatrix)
251  return;
252  m_textureMatrix = textureMatrix;
253  updateGlTextureMatrix();
254 }
255 
256 void PainterOGL1::setColor(const Color& color)
257 {
258  if(m_color == color)
259  return;
260  m_color = color;
261  updateGlColor();
262 }
263 
264 void PainterOGL1::setOpacity(float opacity)
265 {
266  if(m_opacity == opacity)
267  return;
268  m_opacity = opacity;
269  updateGlColor();
270 }
271 
272 void PainterOGL1::updateGlColor()
273 {
274  glColor4f(m_color.rF(), m_color.gF(), m_color.bF(), m_color.aF() * m_opacity);
275 }
276 
277 void PainterOGL1::updateGlMatrixMode()
278 {
279  glMatrixMode(m_matrixMode);
280 }
281 
282 void PainterOGL1::updateGlTransformMatrix()
283 {
284  float glTransformMatrix[] = {
287  0.0f, 0.0f, 1.0f, 0.0f,
289  };
290 
292  glLoadMatrixf(glTransformMatrix);
293 }
294 
295 void PainterOGL1::updateGlProjectionMatrix()
296 {
297  float glProjectionMatrix[] = {
300  0.0f, 0.0f, 1.0f, 0.0f,
302  };
303 
305  glLoadMatrixf(glProjectionMatrix);
306 }
307 
308 void PainterOGL1::updateGlTextureMatrix()
309 {
310  float glTextureMatrix[] = {
311  m_textureMatrix(1,1), m_textureMatrix(1,2), 0.0f, 0.0f,
312  m_textureMatrix(2,1), m_textureMatrix(2,2), 0.0f, 0.0f,
313  0.0f, 0.0f, 1.0f, 0.0f,
314  m_textureMatrix(3,1), m_textureMatrix(3,2), 0.0f, m_textureMatrix(3,3),
315  };
316 
318  glLoadMatrixf(glTextureMatrix);
319 }
320 
321 void PainterOGL1::updateGlTextureState()
322 {
323  if(m_textureEnabled) {
324  glEnable(GL_TEXTURE_2D);
326  glEnableClientState(GL_TEXTURE_COORD_ARRAY);
327  } else {
328  glDisable(GL_TEXTURE_2D);
330  glDisableClientState(GL_TEXTURE_COORD_ARRAY);
331  }
332 }
333 
334 #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:201
PainterOGL1::drawUpsideDownTexturedRect
void drawUpsideDownTexturedRect(const Rect &dest, const TexturePtr &texture, const Rect &src)
Definition: painterogl1.cpp:165
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:240
CoordsBuffer::addUpsideDownQuad
void addUpsideDownQuad(const Rect &dest, const Rect &src)
Definition: coordsbuffer.h:62
PainterOGL1::setMatrixMode
void setMatrixMode(MatrixMode matrixMode)
Definition: painterogl1.cpp:225
TRect::isEmpty
bool isEmpty() const
Definition: rect.h:49
PainterOGL1::drawFilledRect
void drawFilledRect(const Rect &dest)
Definition: painterogl1.cpp:189
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:247
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:177
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:138
g_painter
Painter * g_painter
Definition: painter.cpp:28
PainterOGL1::drawTextureCoords
void drawTextureCoords(CoordsBuffer &coordsBuffer, const TexturePtr &texture)
Definition: painterogl1.cpp:144
PainterOGL::m_projectionMatrix
Matrix3 m_projectionMatrix
Definition: painterogl.h:106
PainterOGL1::drawBoundingRect
void drawBoundingRect(const Rect &dest, int innerLineWidth)
Definition: painterogl1.cpp:213
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:264
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:233
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:153
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:256
PainterOGL::refreshState
virtual void refreshState()
Definition: painterogl.cpp:54