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