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