GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/render/modernopenglgraphics.cpp Lines: 0 512 0.0 %
Date: 2017-11-29 Branches: 0 522 0.0 %

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