GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/render/mobileopenglgraphics.cpp Lines: 0 527 0.0 %
Date: 2021-03-17 Branches: 0 542 0.0 %

Line Branch Exec Source
1
/*
2
 *  The ManaPlus Client
3
 *  Copyright (C) 2004-2009  The Mana World Development Team
4
 *  Copyright (C) 2009-2010  The Mana Developers
5
 *  Copyright (C) 2011-2019  The ManaPlus Developers
6
 *  Copyright (C) 2019-2021  Andrei Karas
7
 *
8
 *  This file is part of The ManaPlus Client.
9
 *
10
 *  This program is free software; you can redistribute it and/or modify
11
 *  it under the terms of the GNU General Public License as published by
12
 *  the Free Software Foundation; either version 2 of the License, or
13
 *  any later version.
14
 *
15
 *  This program is distributed in the hope that it will be useful,
16
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 *  GNU General Public License for more details.
19
 *
20
 *  You should have received a copy of the GNU General Public License
21
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
22
 */
23
24
#if defined(USE_OPENGL) && !defined(__native_client__) && !defined(__SWITCH__)
25
26
#include "render/mobileopenglgraphics.h"
27
28
#ifdef OPENGLERRORS
29
#include "graphicsmanager.h"
30
#endif  // OPENGLERRORS
31
32
#include "render/opengl/mgl.h"
33
#ifdef __native_client__
34
#include "render/opengl/naclglfunctions.h"
35
#endif  // __native_client__
36
37
#include "render/vertexes/imagecollection.h"
38
39
#include "resources/imagerect.h"
40
#include "resources/openglimagehelper.h"
41
42
#include "resources/image/image.h"
43
44
#include "utils/sdlcheckutils.h"
45
46
#include "debug.h"
47
48
#define vertFill2D(tVar, vVar, x1, y1, x2, y2, dstX, dstY, w, h) \
49
    tVar[vp + 0] = x1; \
50
    tVar[vp + 1] = y1; \
51
    tVar[vp + 2] = x2; \
52
    tVar[vp + 3] = y1; \
53
    tVar[vp + 4] = x2; \
54
    tVar[vp + 5] = y2; \
55
    tVar[vp + 6] = x1; \
56
    tVar[vp + 7] = y1; \
57
    tVar[vp + 8] = x1; \
58
    tVar[vp + 9] = y2; \
59
    tVar[vp + 10] = x2; \
60
    tVar[vp + 11] = y2; \
61
    vVar[vp + 0] = static_cast<GLshort>(dstX); \
62
    vVar[vp + 1] = static_cast<GLshort>(dstY); \
63
    vVar[vp + 2] = static_cast<GLshort>(dstX + w); \
64
    vVar[vp + 3] = static_cast<GLshort>(dstY); \
65
    vVar[vp + 4] = static_cast<GLshort>(dstX + w); \
66
    vVar[vp + 5] = static_cast<GLshort>(dstY + h); \
67
    vVar[vp + 6] = static_cast<GLshort>(dstX); \
68
    vVar[vp + 7] = static_cast<GLshort>(dstY); \
69
    vVar[vp + 8] = static_cast<GLshort>(dstX); \
70
    vVar[vp + 9] = static_cast<GLshort>(dstY + h); \
71
    vVar[vp + 10] = static_cast<GLshort>(dstX + w); \
72
    vVar[vp + 11] = static_cast<GLshort>(dstY + h)
73
74
GLuint MobileOpenGLGraphics::mTextureBinded = 0;
75
#ifdef DEBUG_DRAW_CALLS
76
unsigned int MobileOpenGLGraphics::mDrawCalls = 0;
77
unsigned int MobileOpenGLGraphics::mLastDrawCalls = 0;
78
#endif  // DEBUG_DRAW_CALLS
79
80
MobileOpenGLGraphics::MobileOpenGLGraphics() :
81
    mFloatTexArray(nullptr),
82
    mShortVertArray(nullptr),
83
    mFloatTexArrayCached(nullptr),
84
    mShortVertArrayCached(nullptr),
85
    mAlphaCached(1.0F),
86
    mVpCached(0),
87
    mTexture(false),
88
    mIsByteColor(false),
89
    mByteColor(),
90
    mImageCached(0),
91
    mFloatColor(1.0F),
92
    mMaxVertices(500),
93
    mColorAlpha(false),
94
#ifdef DEBUG_BIND_TEXTURE
95
    mOldTexture(),
96
    mOldTextureId(0),
97
#endif  // DEBUG_BIND_TEXTURE
98
    mFbo()
99
{
100
    mOpenGL = RENDER_GLES_OPENGL;
101
    mName = "mobile OpenGL ES";
102
}
103
104
MobileOpenGLGraphics::~MobileOpenGLGraphics()
105
{
106
    deleteArraysInternal();
107
}
108
109
void MobileOpenGLGraphics::postInit() restrict2
110
{
111
//    glesTest();
112
}
113
114
void MobileOpenGLGraphics::initArrays(const int vertCount) restrict2
115
{
116
    mMaxVertices = vertCount;
117
    if (mMaxVertices < 500)
118
        mMaxVertices = 500;
119
    else if (mMaxVertices > 1024)
120
        mMaxVertices = 1024;
121
122
    // need alocate small size, after if limit reached reallocate to double size
123
    const size_t sz = mMaxVertices * 4 + 30;
124
    vertexBufSize = mMaxVertices;
125
    if (mFloatTexArray == nullptr)
126
        mFloatTexArray = new GLfloat[sz];
127
    if (mShortVertArray == nullptr)
128
        mShortVertArray = new GLshort[sz];
129
    if (mFloatTexArrayCached == nullptr)
130
        mFloatTexArrayCached = new GLfloat[sz];
131
    if (mShortVertArrayCached == nullptr)
132
        mShortVertArrayCached = new GLshort[sz];
133
}
134
135
void MobileOpenGLGraphics::deleteArrays() restrict2
136
{
137
    deleteArraysInternal();
138
}
139
140
void MobileOpenGLGraphics::deleteArraysInternal() restrict2
141
{
142
    delete [] mFloatTexArray;
143
    mFloatTexArray = nullptr;
144
    delete [] mShortVertArray;
145
    mShortVertArray = nullptr;
146
    delete [] mFloatTexArrayCached;
147
    mFloatTexArrayCached = nullptr;
148
    delete [] mShortVertArrayCached;
149
    mShortVertArrayCached = nullptr;
150
}
151
152
bool MobileOpenGLGraphics::setVideoMode(const int w, const int h,
153
                                        const int scale,
154
                                        const int bpp,
155
                                        const bool fs,
156
                                        const bool hwaccel,
157
                                        const bool resize,
158
                                        const bool noFrame,
159
                                        const bool allowHighDPI) restrict2
160
{
161
    setMainFlags(w, h,
162
        scale,
163
        bpp,
164
        fs,
165
        hwaccel,
166
        resize,
167
        noFrame,
168
        allowHighDPI);
169
170
    return setOpenGLMode();
171
}
172
173
static inline void drawQuad(const Image *restrict const image,
174
                            const int srcX,
175
                            const int srcY,
176
                            const int dstX,
177
                            const int dstY,
178
                            const int width,
179
                            const int height) A_NONNULL(1) A_INLINE;
180
181
static inline void drawQuad(const Image *restrict const image,
182
                            const int srcX,
183
                            const int srcY,
184
                            const int dstX,
185
                            const int dstY,
186
                            const int width,
187
                            const int height)
188
{
189
//    if (OpenGLImageHelper::mTextureType == GL_TEXTURE_2D)
190
    {
191
        const float tw = static_cast<float>(image->mTexWidth);
192
        const float th = static_cast<float>(image->mTexHeight);
193
        // Find OpenGL normalized texture coordinates.
194
        const float texX1 = static_cast<float>(srcX) / tw;
195
        const float texY1 = static_cast<float>(srcY) / th;
196
        const float texX2 = static_cast<float>(srcX + width) / tw;
197
        const float texY2 = static_cast<float>(srcY + height) / th;
198
199
        GLfloat tex[] =
200
        {
201
            texX1, texY1,
202
            texX2, texY1,
203
            texX1, texY2,
204
            texX2, texY2
205
        };
206
207
        GLshort vert[] =
208
        {
209
            static_cast<GLshort>(dstX), static_cast<GLshort>(dstY),
210
            static_cast<GLshort>(dstX + width), static_cast<GLshort>(dstY),
211
            static_cast<GLshort>(dstX), static_cast<GLshort>(dstY + height),
212
            static_cast<GLshort>(dstX + width),
213
                static_cast<GLshort>(dstY + height)
214
        };
215
216
        glVertexPointer(2, GL_SHORT, 0, &vert);
217
        glTexCoordPointer(2, GL_FLOAT, 0, &tex);
218
219
#ifdef DEBUG_DRAW_CALLS
220
        MobileOpenGLGraphics::mDrawCalls ++;
221
#endif  // DEBUG_DRAW_CALLS
222
        mglDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
223
#ifdef OPENGLERRORS
224
        graphicsManager.logError();
225
#endif  // OPENGLERRORS
226
    }
227
}
228
229
static inline void drawRescaledQuad(const Image *restrict const image,
230
                                    const int srcX, const int srcY,
231
                                    const int dstX, const int dstY,
232
                                    const int width, const int height,
233
                                    const int desiredWidth,
234
                                    const int desiredHeight)
235
                                    A_NONNULL(1) A_INLINE;
236
237
static inline void drawRescaledQuad(const Image *restrict const image,
238
                                    const int srcX, const int srcY,
239
                                    const int dstX, const int dstY,
240
                                    const int width, const int height,
241
                                    const int desiredWidth,
242
                                    const int desiredHeight)
243
{
244
//    if (OpenGLImageHelper::mTextureType == GL_TEXTURE_2D)
245
    {
246
        const float tw = static_cast<float>(image->mTexWidth);
247
        const float th = static_cast<float>(image->mTexHeight);
248
        // Find OpenGL normalized texture coordinates.
249
        const float texX1 = static_cast<float>(srcX) / tw;
250
        const float texY1 = static_cast<float>(srcY) / th;
251
        const float texX2 = static_cast<float>(srcX + width) / tw;
252
        const float texY2 = static_cast<float>(srcY + height) / th;
253
254
        GLfloat tex[] =
255
        {
256
            texX1, texY1,
257
            texX2, texY1,
258
            texX1, texY2,
259
            texX2, texY2
260
        };
261
262
        GLshort vert[] =
263
        {
264
            static_cast<GLshort>(dstX), static_cast<GLshort>(dstY),
265
            static_cast<GLshort>(dstX + desiredWidth),
266
                static_cast<GLshort>(dstY),
267
            static_cast<GLshort>(dstX), static_cast<GLshort>(
268
                dstY + desiredHeight),
269
            static_cast<GLshort>(dstX + desiredWidth),
270
                static_cast<GLshort>(dstY + desiredHeight)
271
        };
272
        glVertexPointer(2, GL_SHORT, 0, &vert);
273
        glTexCoordPointer(2, GL_FLOAT, 0, &tex);
274
275
#ifdef DEBUG_DRAW_CALLS
276
        MobileOpenGLGraphics::mDrawCalls ++;
277
#endif  // DEBUG_DRAW_CALLS
278
        mglDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
279
#ifdef OPENGLERRORS
280
        graphicsManager.logError();
281
#endif  // OPENGLERRORS
282
    }
283
}
284
285
void MobileOpenGLGraphics::drawImage(const Image *restrict const image,
286
                                     int dstX, int dstY) restrict2
287
{
288
    drawImageInline(image, dstX, dstY);
289
}
290
291
void MobileOpenGLGraphics::drawImageInline(const Image *restrict const image,
292
                                           int dstX, int dstY) restrict2
293
{
294
    FUNC_BLOCK("Graphics::drawImage", 1)
295
    if (image == nullptr)
296
        return;
297
298
    setColorAlpha(image->mAlpha);
299
#ifdef DEBUG_BIND_TEXTURE
300
    debugBindTexture(image);
301
#endif  // DEBUG_BIND_TEXTURE
302
    bindTexture(OpenGLImageHelper::mTextureType, image->mGLImage);
303
    enableTexturingAndBlending();
304
305
    const SDL_Rect &imageRect = image->mBounds;
306
    drawQuad(image, imageRect.x, imageRect.y,
307
        dstX, dstY, imageRect.w, imageRect.h);
308
}
309
310
void MobileOpenGLGraphics::copyImage(const Image *restrict const image,
311
                                     int dstX, int dstY) restrict2
312
{
313
    drawImageInline(image, dstX, dstY);
314
}
315
316
void MobileOpenGLGraphics::drawImageCached(const Image *restrict const image,
317
                                           int x, int y) restrict2
318
{
319
    if (image == nullptr)
320
        return;
321
322
    if (image->mGLImage != mImageCached)
323
    {
324
        completeCache();
325
        mImageCached = image->mGLImage;
326
        mAlphaCached = image->mAlpha;
327
    }
328
329
    const SDL_Rect &imageRect = image->mBounds;
330
    const int srcX = imageRect.x;
331
    const int srcY = imageRect.y;
332
    const int w = imageRect.w;
333
    const int h = imageRect.h;
334
335
    if (w == 0 || h == 0)
336
        return;
337
338
    const float tw = static_cast<float>(image->mTexWidth);
339
    const float th = static_cast<float>(image->mTexHeight);
340
341
    const unsigned int vLimit = mMaxVertices * 4;
342
343
    unsigned int vp = mVpCached;
344
345
    // Draw a set of textured rectangles
346
//    if (OpenGLImageHelper::mTextureType == GL_TEXTURE_2D)
347
    {
348
        float texX1 = static_cast<float>(srcX) / tw;
349
        float texY1 = static_cast<float>(srcY) / th;
350
        float texX2 = static_cast<float>(srcX + w) / tw;
351
        float texY2 = static_cast<float>(srcY + h) / th;
352
353
        vertFill2D(mFloatTexArrayCached, mShortVertArrayCached,
354
            texX1, texY1, texX2, texY2,
355
            x, y, w, h);
356
357
        vp += 12;
358
        if (vp >= vLimit)
359
        {
360
            completeCache();
361
            vp = 0;
362
        }
363
        else
364
        {
365
            mVpCached = vp;
366
        }
367
    }
368
}
369
370
void MobileOpenGLGraphics::drawPatternCached(const Image *restrict const image,
371
                                             const int x,
372
                                             const int y,
373
                                             const int w,
374
                                             const int h) restrict2
375
{
376
    if (image == nullptr)
377
        return;
378
379
    if (image->mGLImage != mImageCached)
380
    {
381
        completeCache();
382
        mImageCached = image->mGLImage;
383
    }
384
385
    const SDL_Rect &imageRect = image->mBounds;
386
    const int srcX = imageRect.x;
387
    const int srcY = imageRect.y;
388
    const int iw = imageRect.w;
389
    const int ih = imageRect.h;
390
391
    if (iw == 0 || ih == 0)
392
        return;
393
394
    const float tw = static_cast<float>(image->mTexWidth);
395
    const float th = static_cast<float>(image->mTexHeight);
396
397
    unsigned int vp = mVpCached;
398
    const unsigned int vLimit = mMaxVertices * 4;
399
    const float texX1 = static_cast<float>(srcX) / tw;
400
    const float texY1 = static_cast<float>(srcY) / th;
401
402
    for (int py = 0; py < h; py += ih)
403
    {
404
        const int height = (py + ih >= h) ? h - py : ih;
405
        const float texY2 = static_cast<float>(srcY + height) / th;
406
        const int dstY = y + py;
407
        for (int px = 0; px < w; px += iw)
408
        {
409
            const int width = (px + iw >= w) ? w - px : iw;
410
            const int dstX = x + px;
411
412
            const float texX2 = static_cast<float>(srcX + width) / tw;
413
414
            vertFill2D(mFloatTexArrayCached, mShortVertArrayCached,
415
                texX1, texY1, texX2, texY2,
416
                dstX, dstY, width, height);
417
418
            vp += 12;
419
            if (vp >= vLimit)
420
            {
421
                completeCache();
422
                vp = 0;
423
            }
424
        }
425
    }
426
    mVpCached = vp;
427
}
428
429
void MobileOpenGLGraphics::completeCache() restrict2
430
{
431
    if (mImageCached == 0U)
432
        return;
433
434
    setColorAlpha(mAlphaCached);
435
#ifdef DEBUG_BIND_TEXTURE
436
//    debugBindTexture(image);
437
#endif  // DEBUG_BIND_TEXTURE
438
    bindTexture(OpenGLImageHelper::mTextureType, mImageCached);
439
    enableTexturingAndBlending();
440
441
    drawTriangleArrayfsCached(mVpCached);
442
    mImageCached = 0;
443
    mVpCached = 0;
444
}
445
446
void MobileOpenGLGraphics::drawRescaledImage(const Image *restrict const image,
447
                                             int dstX, int dstY,
448
                                             const int desiredWidth,
449
                                             const int desiredHeight) restrict2
450
{
451
    FUNC_BLOCK("Graphics::drawRescaledImage", 1)
452
    if (image == nullptr)
453
        return;
454
455
    const SDL_Rect &imageRect = image->mBounds;
456
457
    // Just draw the image normally when no resizing is necessary,
458
    if (imageRect.w == desiredWidth && imageRect.h == desiredHeight)
459
    {
460
        drawImageInline(image, dstX, dstY);
461
        return;
462
    }
463
464
    setColorAlpha(image->mAlpha);
465
#ifdef DEBUG_BIND_TEXTURE
466
    debugBindTexture(image);
467
#endif  // DEBUG_BIND_TEXTURE
468
    bindTexture(OpenGLImageHelper::mTextureType, image->mGLImage);
469
    enableTexturingAndBlending();
470
471
    // Draw a textured quad.
472
    drawRescaledQuad(image, imageRect.x, imageRect.y, dstX, dstY,
473
        imageRect.w, imageRect.h, desiredWidth, desiredHeight);
474
}
475
476
void MobileOpenGLGraphics::drawPattern(const Image *restrict const image,
477
                                       const int x, const int y,
478
                                       const int w, const int h) restrict2
479
{
480
    drawPatternInline(image, x, y, w, h);
481
}
482
483
void MobileOpenGLGraphics::drawPatternInline(const Image *restrict const image,
484
                                             const int x,
485
                                             const int y,
486
                                             const int w,
487
                                             const int h) restrict2
488
{
489
    FUNC_BLOCK("Graphics::drawPattern", 1)
490
    if (image == nullptr)
491
        return;
492
493
    const SDL_Rect &imageRect = image->mBounds;
494
    const int srcX = imageRect.x;
495
    const int srcY = imageRect.y;
496
    const int iw = imageRect.w;
497
    const int ih = imageRect.h;
498
499
    if (iw == 0 || ih == 0)
500
        return;
501
502
    const float tw = static_cast<float>(image->mTexWidth);
503
    const float th = static_cast<float>(image->mTexHeight);
504
505
    setColorAlpha(image->mAlpha);
506
507
#ifdef DEBUG_BIND_TEXTURE
508
    debugBindTexture(image);
509
#endif  // DEBUG_BIND_TEXTURE
510
    bindTexture(OpenGLImageHelper::mTextureType, image->mGLImage);
511
512
    enableTexturingAndBlending();
513
514
    unsigned int vp = 0;
515
    const unsigned int vLimit = mMaxVertices * 4;
516
    // Draw a set of textured rectangles
517
    const float texX1 = static_cast<float>(srcX) / tw;
518
    const float texY1 = static_cast<float>(srcY) / th;
519
520
    for (int py = 0; py < h; py += ih)
521
    {
522
        const int height = (py + ih >= h) ? h - py : ih;
523
        const float texY2 = static_cast<float>(srcY + height) / th;
524
        const int dstY = y + py;
525
        for (int px = 0; px < w; px += iw)
526
        {
527
            const int width = (px + iw >= w) ? w - px : iw;
528
            const int dstX = x + px;
529
530
            const float texX2 = static_cast<float>(srcX + width) / tw;
531
532
            vertFill2D(mFloatTexArray, mShortVertArray,
533
                texX1, texY1, texX2, texY2,
534
                dstX, dstY, width, height);
535
536
            vp += 12;
537
            if (vp >= vLimit)
538
            {
539
                drawTriangleArrayfs(vp);
540
                vp = 0;
541
            }
542
        }
543
    }
544
    if (vp > 0)
545
        drawTriangleArrayfs(vp);
546
}
547
548
void MobileOpenGLGraphics::drawRescaledPattern(const Image *
549
                                               restrict const image,
550
                                               const int x, const int y,
551
                                               const int w, const int h,
552
                                               const int scaledWidth,
553
                                               const int scaledHeight)
554
                                               restrict2
555
{
556
    if (image == nullptr)
557
        return;
558
559
    if (scaledWidth == 0 || scaledHeight == 0)
560
        return;
561
562
    const SDL_Rect &imageRect = image->mBounds;
563
    const int srcX = imageRect.x;
564
    const int srcY = imageRect.y;
565
    const int iw = imageRect.w;
566
    const int ih = imageRect.h;
567
    if (iw == 0 || ih == 0)
568
        return;
569
570
    setColorAlpha(image->mAlpha);
571
572
#ifdef DEBUG_BIND_TEXTURE
573
    debugBindTexture(image);
574
#endif  // DEBUG_BIND_TEXTURE
575
    bindTexture(OpenGLImageHelper::mTextureType, image->mGLImage);
576
577
    enableTexturingAndBlending();
578
579
    unsigned int vp = 0;
580
    const unsigned int vLimit = mMaxVertices * 4;
581
582
    // Draw a set of textured rectangles
583
    const float tw = static_cast<float>(image->mTexWidth);
584
    const float th = static_cast<float>(image->mTexHeight);
585
586
    const float texX1 = static_cast<float>(srcX) / tw;
587
    const float texY1 = static_cast<float>(srcY) / th;
588
589
    const float tFractionW = iw / tw;
590
    const float tFractionH = ih / th;
591
592
    for (int py = 0; py < h; py += scaledHeight)
593
    {
594
        const int height = (py + scaledHeight >= h)
595
            ? h - py : scaledHeight;
596
        const int dstY = y + py;
597
        const float visibleFractionH = static_cast<float>(height)
598
            / scaledHeight;
599
        const float texY2 = texY1 + tFractionH * visibleFractionH;
600
        for (int px = 0; px < w; px += scaledWidth)
601
        {
602
            const int width = (px + scaledWidth >= w)
603
                ? w - px : scaledWidth;
604
            const int dstX = x + px;
605
            const float visibleFractionW = static_cast<float>(width)
606
                / scaledWidth;
607
            const float texX2 = texX1 + tFractionW * visibleFractionW;
608
609
            vertFill2D(mFloatTexArray, mShortVertArray,
610
                texX1, texY1, texX2, texY2,
611
                dstX, dstY, width, height);
612
613
            vp += 12;
614
            if (vp >= vLimit)
615
            {
616
                drawTriangleArrayfs(vp);
617
                vp = 0;
618
            }
619
        }
620
    }
621
    if (vp > 0)
622
        drawTriangleArrayfs(vp);
623
}
624
625
inline void MobileOpenGLGraphics::drawVertexes(const
626
                                               OpenGLGraphicsVertexes
627
                                               &restrict ogl) restrict2
628
{
629
    const STD_VECTOR<GLshort*> &shortVertPool = ogl.mShortVertPool;
630
    STD_VECTOR<GLshort*>::const_iterator iv;
631
    const STD_VECTOR<GLshort*>::const_iterator iv_end = shortVertPool.end();
632
    const STD_VECTOR<int> &vp = ogl.mVp;
633
    STD_VECTOR<int>::const_iterator ivp;
634
    const STD_VECTOR<int>::const_iterator ivp_end = vp.end();
635
636
    // Draw a set of textured rectangles
637
//    if (OpenGLImageHelper::mTextureType == GL_TEXTURE_2D)
638
    {
639
        const STD_VECTOR<GLfloat*> &floatTexPool = ogl.mFloatTexPool;
640
        STD_VECTOR<GLfloat*>::const_iterator ft;
641
        const STD_VECTOR<GLfloat*>::const_iterator
642
            ft_end = floatTexPool.end();
643
644
        for (iv = shortVertPool.begin(), ft = floatTexPool.begin(),
645
             ivp = vp.begin();
646
             iv != iv_end && ft != ft_end && ivp != ivp_end;
647
             ++ iv, ++ ft, ++ ivp)
648
        {
649
            drawTriangleArrayfs(*iv, *ft, *ivp);
650
        }
651
    }
652
}
653
654
void MobileOpenGLGraphics::calcPattern(ImageVertexes *restrict const vert,
655
                                       const Image *restrict const image,
656
                                       const int x,
657
                                       const int y,
658
                                       const int w,
659
                                       const int h) const restrict2
660
{
661
    calcPatternInline(vert, image, x, y, w, h);
662
}
663
664
void MobileOpenGLGraphics::calcPatternInline(ImageVertexes *
665
                                             restrict const vert,
666
                                             const Image *restrict const image,
667
                                             const int x,
668
                                             const int y,
669
                                             const int w,
670
                                             const int h) const restrict2
671
{
672
    if (image == nullptr || vert == nullptr)
673
        return;
674
675
    const SDL_Rect &imageRect = image->mBounds;
676
    const int srcX = imageRect.x;
677
    const int srcY = imageRect.y;
678
    const int iw = imageRect.w;
679
    const int ih = imageRect.h;
680
681
    if (iw == 0 || ih == 0)
682
        return;
683
684
    const float tw = static_cast<float>(image->mTexWidth);
685
    const float th = static_cast<float>(image->mTexHeight);
686
687
    const unsigned int vLimit = mMaxVertices * 4;
688
689
    OpenGLGraphicsVertexes &ogl = vert->ogl;
690
    unsigned int vp = ogl.continueVp();
691
692
    // Draw a set of textured rectangles
693
//    if (OpenGLImageHelper::mTextureType == GL_TEXTURE_2D)
694
    {
695
        const float texX1 = static_cast<float>(srcX) / tw;
696
        const float texY1 = static_cast<float>(srcY) / th;
697
698
        GLfloat *floatTexArray = ogl.continueFloatTexArray();
699
        GLshort *shortVertArray = ogl.continueShortVertArray();
700
701
        for (int py = 0; py < h; py += ih)
702
        {
703
            const int height = (py + ih >= h) ? h - py : ih;
704
            const int dstY = y + py;
705
            const float texY2 = static_cast<float>(srcY + height) / th;
706
            for (int px = 0; px < w; px += iw)
707
            {
708
                const int width = (px + iw >= w) ? w - px : iw;
709
                const int dstX = x + px;
710
                const float texX2 = static_cast<float>(srcX + width) / tw;
711
712
                vertFill2D(floatTexArray, shortVertArray,
713
                    texX1, texY1, texX2, texY2,
714
                    dstX, dstY, width, height);
715
716
                vp += 12;
717
                if (vp >= vLimit)
718
                {
719
                    floatTexArray = ogl.switchFloatTexArray();
720
                    shortVertArray = ogl.switchShortVertArray();
721
                    ogl.switchVp(vp);
722
                    vp = 0;
723
                }
724
            }
725
        }
726
    }
727
    ogl.switchVp(vp);
728
}
729
730
void MobileOpenGLGraphics::calcTileCollection(ImageCollection *
731
                                              restrict const vertCol,
732
                                              const Image *
733
                                              restrict const image,
734
                                              int x, int y) restrict2
735
{
736
    if (vertCol == nullptr || image == nullptr)
737
        return;
738
    if (vertCol->currentGLImage != image->mGLImage)
739
    {
740
        ImageVertexes *const vert = new ImageVertexes;
741
        vertCol->currentGLImage = image->mGLImage;
742
        vertCol->currentVert = vert;
743
        vert->image = image;
744
        vertCol->draws.push_back(vert);
745
        calcTileVertexesInline(vert, image, x, y);
746
    }
747
    else
748
    {
749
        calcTileVertexesInline(vertCol->currentVert, image, x, y);
750
    }
751
}
752
753
void MobileOpenGLGraphics::drawTileCollection(const ImageCollection *
754
                                              restrict const vertCol)
755
                                              restrict2
756
{
757
    const ImageVertexesVector &draws = vertCol->draws;
758
    const ImageCollectionCIter it_end = draws.end();
759
    for (ImageCollectionCIter it = draws.begin(); it != it_end; ++ it)
760
    {
761
        const ImageVertexes *const vert = *it;
762
        const Image *const image = vert->image;
763
764
        setColorAlpha(image->mAlpha);
765
#ifdef DEBUG_BIND_TEXTURE
766
        debugBindTexture(image);
767
#endif  // DEBUG_BIND_TEXTURE
768
        bindTexture(OpenGLImageHelper::mTextureType, image->mGLImage);
769
        enableTexturingAndBlending();
770
        drawVertexes(vert->ogl);
771
    }
772
}
773
774
void MobileOpenGLGraphics::calcPattern(ImageCollection *restrict const vertCol,
775
                                       const Image *restrict const image,
776
                                       const int x,
777
                                       const int y,
778
                                       const int w,
779
                                       const int h) const restrict2
780
{
781
    if (vertCol == nullptr || image == nullptr)
782
        return;
783
    ImageVertexes *vert = nullptr;
784
    if (vertCol->currentGLImage != image->mGLImage)
785
    {
786
        vert = new ImageVertexes;
787
        vertCol->currentGLImage = image->mGLImage;
788
        vertCol->currentVert = vert;
789
        vert->image = image;
790
        vertCol->draws.push_back(vert);
791
    }
792
    else
793
    {
794
        vert = vertCol->currentVert;
795
    }
796
797
    calcPatternInline(vert, image, x, y, w, h);
798
}
799
800
void MobileOpenGLGraphics::calcTileVertexes(ImageVertexes *restrict const vert,
801
                                            const Image *restrict const image,
802
                                            int dstX, int dstY) const restrict2
803
{
804
    calcTileVertexesInline(vert, image, dstX, dstY);
805
}
806
807
void MobileOpenGLGraphics::calcTileVertexesInline(ImageVertexes *
808
                                                  restrict const vert,
809
                                                  const Image *
810
                                                  restrict const image,
811
                                                  int dstX,
812
                                                  int dstY) const restrict2
813
{
814
    const SDL_Rect &imageRect = image->mBounds;
815
    const int srcX = imageRect.x;
816
    const int srcY = imageRect.y;
817
    const int w = imageRect.w;
818
    const int h = imageRect.h;
819
820
    if (w == 0 || h == 0)
821
        return;
822
823
    const float tw = static_cast<float>(image->mTexWidth);
824
    const float th = static_cast<float>(image->mTexHeight);
825
826
    const unsigned int vLimit = mMaxVertices * 4;
827
828
    OpenGLGraphicsVertexes &ogl = vert->ogl;
829
830
//    STD_VECTOR<int> *vps = ogl.getVp();
831
    unsigned int vp = ogl.continueVp();
832
833
    // Draw a set of textured rectangles
834
//    if (OpenGLImageHelper::mTextureType == GL_TEXTURE_2D)
835
    {
836
        float texX1 = static_cast<float>(srcX) / tw;
837
        float texY1 = static_cast<float>(srcY) / th;
838
        float texX2 = static_cast<float>(srcX + w) / tw;
839
        float texY2 = static_cast<float>(srcY + h) / th;
840
841
        GLfloat *const floatTexArray = ogl.continueFloatTexArray();
842
        GLshort *const shortVertArray = ogl.continueShortVertArray();
843
844
        vertFill2D(floatTexArray, shortVertArray,
845
            texX1, texY1, texX2, texY2,
846
            dstX, dstY, w, h);
847
848
        vp += 12;
849
        if (vp >= vLimit)
850
        {
851
            ogl.switchFloatTexArray();
852
            ogl.switchShortVertArray();
853
            ogl.switchVp(vp);
854
            vp = 0;
855
        }
856
    }
857
    ogl.switchVp(vp);
858
}
859
860
void MobileOpenGLGraphics::drawTileVertexes(const ImageVertexes *
861
                                            restrict const vert) restrict2
862
{
863
    if (vert == nullptr)
864
        return;
865
    const Image *const image = vert->image;
866
867
    setColorAlpha(image->mAlpha);
868
#ifdef DEBUG_BIND_TEXTURE
869
    debugBindTexture(image);
870
#endif  // DEBUG_BIND_TEXTURE
871
    bindTexture(OpenGLImageHelper::mTextureType, image->mGLImage);
872
    enableTexturingAndBlending();
873
    drawVertexes(vert->ogl);
874
}
875
876
void MobileOpenGLGraphics::calcWindow(ImageCollection *restrict const vertCol,
877
                                      const int x, const int y,
878
                                      const int w, const int h,
879
                                      const ImageRect &restrict imgRect)
880
                                      restrict2
881
{
882
    ImageVertexes *vert = nullptr;
883
    const Image *const image = imgRect.grid[4];
884
    if (image == nullptr)
885
        return;
886
    if (vertCol->currentGLImage != image->mGLImage)
887
    {
888
        vert = new ImageVertexes;
889
        vertCol->currentGLImage = image->mGLImage;
890
        vertCol->currentVert = vert;
891
        vert->image = image;
892
        vertCol->draws.push_back(vert);
893
    }
894
    else
895
    {
896
        vert = vertCol->currentVert;
897
    }
898
    calcImageRect(vert, x, y, w, h, imgRect);
899
}
900
901
902
void MobileOpenGLGraphics::updateScreen() restrict2
903
{
904
    BLOCK_START("Graphics::updateScreen")
905
//    glFlush();
906
//    glFinish();
907
#ifdef DEBUG_DRAW_CALLS
908
    mLastDrawCalls = mDrawCalls;
909
    mDrawCalls = 0;
910
#endif  // DEBUG_DRAW_CALLS
911
#ifdef USE_SDL2
912
    SDL_GL_SwapWindow(mWindow);
913
#else  // USE_SDL2
914
915
    SDL_GL_SwapBuffers();
916
#endif  // USE_SDL2
917
#ifdef DEBUG_OPENGL
918
    if (isGLNotNull(mglFrameTerminator))
919
        mglFrameTerminator();
920
#endif  // DEBUG_OPENGL
921
922
    BLOCK_END("Graphics::updateScreen")
923
}
924
925
void MobileOpenGLGraphics::beginDraw() restrict2
926
{
927
    glMatrixMode(GL_TEXTURE);
928
    glLoadIdentity();
929
930
    glMatrixMode(GL_PROJECTION);
931
    glLoadIdentity();
932
933
#ifdef ANDROID
934
    glOrthof(0.0, static_cast<float>(mRect.w),
935
        static_cast<float>(mRect.h),
936
        0.0, -1.0, 1.0);
937
#else  // ANDROID
938
939
    glOrtho(0.0, static_cast<double>(mRect.w),
940
        static_cast<double>(mRect.h),
941
        0.0, -1.0, 1.0);
942
#endif  // ANDROID
943
944
    glMatrixMode(GL_MODELVIEW);
945
    glLoadIdentity();
946
947
    setOpenGLFlags();
948
    mglDisable(GL_LIGHTING);
949
    mglDisable(GL_FOG);
950
    mglDisable(GL_COLOR_MATERIAL);
951
952
    glShadeModel(GL_FLAT);
953
954
    glEnableClientState(GL_VERTEX_ARRAY);
955
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
956
957
#ifndef ANDROID
958
    mglHint(GL_LINE_SMOOTH_HINT, GL_FASTEST);
959
    mglHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
960
    mglHint(GL_POINT_SMOOTH_HINT, GL_FASTEST);
961
    mglHint(GL_POLYGON_SMOOTH_HINT, GL_FASTEST);
962
#endif  // ANDROID
963
964
    pushClipArea(Rect(0, 0, mRect.w, mRect.h));
965
}
966
967
void MobileOpenGLGraphics::endDraw() restrict2
968
{
969
    popClipArea();
970
}
971
972
void MobileOpenGLGraphics::pushClipArea(const Rect &restrict area) restrict2
973
{
974
    int transX = 0;
975
    int transY = 0;
976
977
    if (!mClipStack.empty())
978
    {
979
        const ClipRect &clipArea = mClipStack.top();
980
        transX = -clipArea.xOffset;
981
        transY = -clipArea.yOffset;
982
    }
983
984
    Graphics::pushClipArea(area);
985
986
    const ClipRect &clipArea = mClipStack.top();
987
    transX += clipArea.xOffset;
988
    transY += clipArea.yOffset;
989
990
    if (transX != 0 || transY != 0)
991
    {
992
        glTranslatef(static_cast<GLfloat>(transX),
993
                     static_cast<GLfloat>(transY), 0);
994
    }
995
    mglScissor(clipArea.x * mScale,
996
        (mRect.h - clipArea.y - clipArea.height) * mScale,
997
        clipArea.width * mScale,
998
        clipArea.height * mScale);
999
}
1000
1001
void MobileOpenGLGraphics::popClipArea() restrict2
1002
{
1003
    if (mClipStack.empty())
1004
        return;
1005
1006
    const ClipRect &clipArea1 = mClipStack.top();
1007
    int transX = -clipArea1.xOffset;
1008
    int transY = -clipArea1.yOffset;
1009
1010
    Graphics::popClipArea();
1011
1012
    if (mClipStack.empty())
1013
        return;
1014
1015
    const ClipRect &clipArea = mClipStack.top();
1016
    transX += clipArea.xOffset;
1017
    transY += clipArea.yOffset;
1018
    if (transX != 0 || transY != 0)
1019
    {
1020
        glTranslatef(static_cast<GLfloat>(transX),
1021
                     static_cast<GLfloat>(transY), 0);
1022
    }
1023
    mglScissor(clipArea.x * mScale,
1024
        (mRect.h - clipArea.y - clipArea.height) * mScale,
1025
        clipArea.width * mScale,
1026
        clipArea.height * mScale);
1027
}
1028
1029
#ifdef ANDROID
1030
void MobileOpenGLGraphics::drawPoint(int x A_UNUSED, int y A_UNUSED) restrict2
1031
#else  // ANDROID
1032
void MobileOpenGLGraphics::drawPoint(int x, int y) restrict2
1033
#endif  // ANDROID
1034
{
1035
    disableTexturingAndBlending();
1036
    restoreColor();
1037
1038
#ifdef ANDROID
1039
    // TODO need fix
1040
#else  // ANDROID
1041
1042
    glBegin(GL_POINTS);
1043
    glVertex2i(x, y);
1044
    glEnd();
1045
#endif  // ANDROID
1046
}
1047
1048
void MobileOpenGLGraphics::drawLine(int x1, int y1,
1049
                                    int x2, int y2) restrict2
1050
{
1051
    disableTexturingAndBlending();
1052
    restoreColor();
1053
1054
    mShortVertArray[0] = static_cast<GLshort>(x1);
1055
    mShortVertArray[1] = static_cast<GLshort>(y1);
1056
    mShortVertArray[2] = static_cast<GLshort>(x2);
1057
    mShortVertArray[3] = static_cast<GLshort>(y2);
1058
1059
    drawLineArrays(4);
1060
}
1061
1062
void MobileOpenGLGraphics::drawRectangle(const Rect &restrict rect) restrict2
1063
{
1064
    drawRectangle(rect, false);
1065
}
1066
1067
void MobileOpenGLGraphics::fillRectangle(const Rect &restrict rect) restrict2
1068
{
1069
    drawRectangle(rect, true);
1070
}
1071
1072
void MobileOpenGLGraphics::enableTexturingAndBlending() restrict2
1073
{
1074
    if (!mTexture)
1075
    {
1076
        mglEnable(OpenGLImageHelper::mTextureType);
1077
        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
1078
        mTexture = true;
1079
    }
1080
1081
    if (!mAlpha)
1082
    {
1083
        mglEnable(GL_BLEND);
1084
        mAlpha = true;
1085
    }
1086
}
1087
1088
void MobileOpenGLGraphics::disableTexturingAndBlending() restrict2
1089
{
1090
    mTextureBinded = 0;
1091
    if (mAlpha && !mColorAlpha)
1092
    {
1093
        mglDisable(GL_BLEND);
1094
        mAlpha = false;
1095
    }
1096
    else if (!mAlpha && mColorAlpha)
1097
    {
1098
        mglEnable(GL_BLEND);
1099
        mAlpha = true;
1100
    }
1101
1102
    if (mTexture)
1103
    {
1104
        mglDisable(OpenGLImageHelper::mTextureType);
1105
        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1106
        mTexture = false;
1107
    }
1108
}
1109
1110
void MobileOpenGLGraphics::drawRectangle(const Rect &restrict rect,
1111
                                         const bool filled) restrict2
1112
{
1113
    BLOCK_START("Graphics::drawRectangle")
1114
    disableTexturingAndBlending();
1115
    restoreColor();
1116
1117
    const GLshort x = static_cast<GLshort>(rect.x);
1118
    const GLshort y = static_cast<GLshort>(rect.y);
1119
    const GLshort width = static_cast<GLshort>(rect.width);
1120
    const GLshort height = static_cast<GLshort>(rect.height);
1121
    const GLshort xw = static_cast<GLshort>(rect.x + width);
1122
    const GLshort yh = static_cast<GLshort>(rect.y + height);
1123
1124
    if (filled)
1125
    {
1126
        GLshort vert[] =
1127
        {
1128
            x, y,
1129
            xw, y,
1130
            x, yh,
1131
            xw, yh
1132
        };
1133
1134
        glVertexPointer(2, GL_SHORT, 0, &vert);
1135
#ifdef DEBUG_DRAW_CALLS
1136
        mDrawCalls ++;
1137
#endif  // DEBUG_DRAW_CALLS
1138
1139
        mglDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
1140
#ifdef OPENGLERRORS
1141
        graphicsManager.logError();
1142
#endif  // OPENGLERRORS
1143
    }
1144
    else
1145
    {
1146
        GLshort vert[] =
1147
        {
1148
            x, y,
1149
            xw, y,
1150
            xw, yh,
1151
            x, yh
1152
        };
1153
1154
        glVertexPointer(2, GL_SHORT, 0, &vert);
1155
#ifdef DEBUG_DRAW_CALLS
1156
        mDrawCalls ++;
1157
#endif  // DEBUG_DRAW_CALLS
1158
1159
        mglDrawArrays(GL_LINE_LOOP, 0, 4);
1160
#ifdef OPENGLERRORS
1161
        graphicsManager.logError();
1162
#endif  // OPENGLERRORS
1163
    }
1164
    BLOCK_END("Graphics::drawRectangle")
1165
}
1166
1167
void MobileOpenGLGraphics::drawNet(const int x1, const int y1,
1168
                                   const int x2, const int y2,
1169
                                   const int width, const int height) restrict2
1170
{
1171
    unsigned int vp = 0;
1172
    const unsigned int vLimit = mMaxVertices * 4;
1173
1174
    disableTexturingAndBlending();
1175
    restoreColor();
1176
1177
    const GLshort xs1 = static_cast<GLshort>(x1);
1178
    const GLshort xs2 = static_cast<GLshort>(x2);
1179
    const GLshort ys1 = static_cast<GLshort>(y1);
1180
    const GLshort ys2 = static_cast<GLshort>(y2);
1181
    const int16_t width1 = CAST_S16(width);
1182
    const int16_t height1 = CAST_S16(height);
1183
1184
    for (int16_t y = CAST_S16(y1); y < y2; y += height1)
1185
    {
1186
        mShortVertArray[vp + 0] = xs1;
1187
        mShortVertArray[vp + 1] = y;
1188
1189
        mShortVertArray[vp + 2] = xs2;
1190
        mShortVertArray[vp + 3] = y;
1191
1192
        vp += 4;
1193
        if (vp >= vLimit)
1194
        {
1195
            drawLineArrays(vp);
1196
            vp = 0;
1197
        }
1198
    }
1199
1200
    for (int16_t x = CAST_S16(x1); x < x2; x += width1)
1201
    {
1202
        mShortVertArray[vp + 0] = x;
1203
        mShortVertArray[vp + 1] = ys1;
1204
1205
        mShortVertArray[vp + 2] = x;
1206
        mShortVertArray[vp + 3] = ys2;
1207
1208
        vp += 4;
1209
        if (vp >= vLimit)
1210
        {
1211
            drawLineArrays(vp);
1212
            vp = 0;
1213
        }
1214
    }
1215
1216
    if (vp > 0)
1217
        drawLineArrays(vp);
1218
}
1219
1220
void MobileOpenGLGraphics::bindTexture(const GLenum target,
1221
                                       const GLuint texture)
1222
{
1223
    if (mTextureBinded != texture)
1224
    {
1225
        mTextureBinded = texture;
1226
        mglBindTexture(target, texture);
1227
    }
1228
}
1229
1230
inline void MobileOpenGLGraphics::drawTriangleArrayfs(const int size) restrict2
1231
{
1232
    glVertexPointer(2, GL_SHORT, 0, mShortVertArray);
1233
    glTexCoordPointer(2, GL_FLOAT, 0, mFloatTexArray);
1234
1235
#ifdef DEBUG_DRAW_CALLS
1236
    mDrawCalls ++;
1237
#endif  // DEBUG_DRAW_CALLS
1238
1239
    mglDrawArrays(GL_TRIANGLES, 0, size / 2);
1240
#ifdef OPENGLERRORS
1241
    graphicsManager.logError();
1242
#endif  // OPENGLERRORS
1243
}
1244
1245
inline void MobileOpenGLGraphics::drawTriangleArrayfsCached(const int size)
1246
                                                            restrict2
1247
{
1248
    glVertexPointer(2, GL_SHORT, 0, mShortVertArrayCached);
1249
    glTexCoordPointer(2, GL_FLOAT, 0, mFloatTexArrayCached);
1250
1251
#ifdef DEBUG_DRAW_CALLS
1252
    mDrawCalls ++;
1253
#endif  // DEBUG_DRAW_CALLS
1254
1255
    mglDrawArrays(GL_TRIANGLES, 0, size / 2);
1256
#ifdef OPENGLERRORS
1257
    graphicsManager.logError();
1258
#endif  // OPENGLERRORS
1259
}
1260
1261
inline void MobileOpenGLGraphics::drawTriangleArrayfs(const GLshort *restrict
1262
                                                      const shortVertArray,
1263
                                                      const GLfloat *restrict
1264
                                                      const floatTexArray,
1265
                                                      const int size) restrict2
1266
{
1267
    glVertexPointer(2, GL_SHORT, 0, shortVertArray);
1268
    glTexCoordPointer(2, GL_FLOAT, 0, floatTexArray);
1269
1270
#ifdef DEBUG_DRAW_CALLS
1271
    mDrawCalls ++;
1272
#endif  // DEBUG_DRAW_CALLS
1273
1274
    mglDrawArrays(GL_TRIANGLES, 0, size / 2);
1275
#ifdef OPENGLERRORS
1276
    graphicsManager.logError();
1277
#endif  // OPENGLERRORS
1278
}
1279
1280
inline void MobileOpenGLGraphics::drawLineArrays(const int size) restrict2
1281
{
1282
    glVertexPointer(2, GL_SHORT, 0, mShortVertArray);
1283
1284
#ifdef DEBUG_DRAW_CALLS
1285
    mDrawCalls ++;
1286
#endif  // DEBUG_DRAW_CALLS
1287
1288
    mglDrawArrays(GL_LINES, 0, size / 2);
1289
#ifdef OPENGLERRORS
1290
    graphicsManager.logError();
1291
#endif  // OPENGLERRORS
1292
}
1293
1294
void MobileOpenGLGraphics::dumpSettings()
1295
{
1296
    GLint test[1000];
1297
    logger->log("\n\n");
1298
    logger->log("start opengl dump");
1299
    for (int f = 0; f < 65535; f ++)
1300
    {
1301
        test[0] = 0;
1302
        test[1] = 0;
1303
        test[2] = 0;
1304
        test[3] = 0;
1305
        mglGetIntegerv(f, &test[0]);
1306
        if (test[0] != 0 || test[1] != 0 || test[2] != 0 || test[3] != 0)
1307
        {
1308
            logger->log("\n%d = %d, %d, %d, %d", f,
1309
                test[0], test[1], test[2], test[3]);
1310
        }
1311
    }
1312
}
1313
1314
void MobileOpenGLGraphics::setColorAlpha(const float alpha) restrict2
1315
{
1316
    if (!mIsByteColor && mFloatColor == alpha)
1317
        return;
1318
1319
    glColor4f(1.0F, 1.0F, 1.0F, alpha);
1320
    mIsByteColor = false;
1321
    mFloatColor = alpha;
1322
}
1323
1324
void MobileOpenGLGraphics::restoreColor() restrict2
1325
{
1326
    if (mIsByteColor && mByteColor == mColor)
1327
        return;
1328
1329
    glColor4ub(static_cast<GLubyte>(mColor.r),
1330
               static_cast<GLubyte>(mColor.g),
1331
               static_cast<GLubyte>(mColor.b),
1332
               static_cast<GLubyte>(mColor.a));
1333
    mIsByteColor = true;
1334
    mByteColor = mColor;
1335
}
1336
1337
void MobileOpenGLGraphics::drawImageRect(const int x, const int y,
1338
                                         const int w, const int h,
1339
                                         const ImageRect &restrict imgRect)
1340
                                         restrict2
1341
{
1342
    #include "render/graphics_drawImageRect.hpp"
1343
}
1344
1345
void MobileOpenGLGraphics::calcImageRect(ImageVertexes *restrict const vert,
1346
                                         const int x, const int y,
1347
                                         const int w, const int h,
1348
                                         const ImageRect &restrict imgRect)
1349
                                         restrict2
1350
{
1351
    #include "render/graphics_calcImageRect.hpp"
1352
}
1353
1354
void MobileOpenGLGraphics::clearScreen() const restrict2
1355
{
1356
    mglClear(GL_COLOR_BUFFER_BIT |
1357
        GL_DEPTH_BUFFER_BIT |
1358
        GL_STENCIL_BUFFER_BIT);
1359
}
1360
1361
#ifdef DEBUG_BIND_TEXTURE
1362
void MobileOpenGLGraphics::debugBindTexture(const Image *restrict const image)
1363
                                            restrict2
1364
{
1365
    const std::string texture = image->mIdPath;
1366
    if (mOldTexture != texture)
1367
    {
1368
        if ((!mOldTexture.empty() || !texture.empty())
1369
            && mOldTextureId != image->mGLImage)
1370
        {
1371
            logger->log("bind: %s (%d) to %s (%d)", mOldTexture.c_str(),
1372
                mOldTextureId, texture.c_str(), image->mGLImage);
1373
        }
1374
        mOldTextureId = image->mGLImage;
1375
        mOldTexture = texture;
1376
    }
1377
}
1378
#else  // DEBUG_BIND_TEXTURE
1379
1380
void MobileOpenGLGraphics::debugBindTexture(const Image *restrict const
1381
                                            image A_UNUSED) restrict2
1382
{
1383
}
1384
#endif  // DEBUG_BIND_TEXTURE
1385
1386
#endif  // defined(USE_OPENGL) && !defined(__native_client__)