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

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