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