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

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