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