~compiz-team/compiz/0.9.12

« back to all changes in this revision

Viewing changes to plugins/opengl/src/paint.cpp

MergeĀ GLESĀ support

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 * Copyright Ā© 2005 Novell, Inc.
 
3
 * Copyright Ā© 2011 Linaro, Ltd.
3
4
 *
4
5
 * Permission to use, copy, modify, distribute, and sell this software
5
6
 * and its documentation for any purpose is hereby granted without
20
21
 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
21
22
 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
23
 *
23
 
 * Author: David Reveman <davidr@novell.com>
 
24
 * Authors: David Reveman <davidr@novell.com>
 
25
 *          Travis Watkins <travis.watkins@linaro.org>
24
26
 */
25
27
 
26
28
#include "privates.h"
35
37
 
36
38
#include <opengl/opengl.h>
37
39
 
 
40
#include "privates.h"
 
41
 
38
42
#define DEG2RAD (M_PI / 180.0f)
39
43
 
40
44
GLScreenPaintAttrib defaultScreenPaintAttrib = {
64
68
}
65
69
 
66
70
void
67
 
PrivateGLScreen::paintBackground (const CompRegion &region,
 
71
PrivateGLScreen::paintBackground (const GLMatrix   &transform,
 
72
                                  const CompRegion &region,
68
73
                                  bool             transformed)
69
74
{
 
75
    GLVertexBuffer *streamingBuffer = GLVertexBuffer::streamingBuffer ();
 
76
    GLfloat         vertexData[18];
 
77
    GLushort        colorData[4];
 
78
 
70
79
    BoxPtr    pBox = const_cast <Region> (region.handle ())->rects;
71
80
    int       n, nBox = const_cast <Region> (region.handle ())->numRects;
72
 
    GLfloat   *d;
73
 
 
74
 
    boost::scoped_array <GLfloat> data;
75
81
 
76
82
    if (!nBox)
77
83
        return;
97
103
 
98
104
    if (backgroundTextures.empty ())
99
105
    {
100
 
        data.reset (new GLfloat [nBox * 8]);
101
 
 
102
 
        d = data.get ();
 
106
        streamingBuffer->begin (GL_TRIANGLES);
103
107
        n = nBox;
104
108
 
105
109
        while (n--)
106
110
        {
107
 
            *d++ = pBox->x1;
108
 
            *d++ = pBox->y2;
109
 
 
110
 
            *d++ = pBox->x2;
111
 
            *d++ = pBox->y2;
112
 
 
113
 
            *d++ = pBox->x2;
114
 
            *d++ = pBox->y1;
115
 
 
116
 
            *d++ = pBox->x1;
117
 
            *d++ = pBox->y1;
 
111
            vertexData[0]  = pBox->x1;
 
112
            vertexData[1]  = pBox->y1;
 
113
            vertexData[2]  = 0.0f;
 
114
            vertexData[3]  = pBox->x1;
 
115
            vertexData[4]  = pBox->y2;
 
116
            vertexData[5]  = 0.0f;
 
117
            vertexData[6]  = pBox->x2;
 
118
            vertexData[7]  = pBox->y1;
 
119
            vertexData[8]  = 0.0f;
 
120
            vertexData[9]  = pBox->x1;
 
121
            vertexData[10] = pBox->y2;
 
122
            vertexData[11] = 0.0f;
 
123
            vertexData[12] = pBox->x2;
 
124
            vertexData[13] = pBox->y2;
 
125
            vertexData[14] = 0.0f;
 
126
 
 
127
            vertexData[15] = pBox->x2;
 
128
            vertexData[16] = pBox->y1;
 
129
            vertexData[17] = 0.0f;
 
130
 
 
131
            streamingBuffer->addVertices (6, vertexData);
118
132
 
119
133
            pBox++;
120
134
        }
121
135
 
122
 
        glDisableClientState (GL_TEXTURE_COORD_ARRAY);
123
 
 
124
 
        glVertexPointer (2, GL_FLOAT, sizeof (GLfloat) * 2, &data[0]);
125
 
 
126
 
        glColor4us (0, 0, 0, std::numeric_limits<unsigned short>::max ());
127
 
        glDrawArrays (GL_QUADS, 0, nBox * 4);
128
 
        glColor4usv (defaultColor);
129
 
 
130
 
        glEnableClientState (GL_TEXTURE_COORD_ARRAY);
 
136
        colorData[0] = colorData[1] = colorData[2] = 0;
 
137
        colorData[3] = std::numeric_limits <unsigned short>::max ();
 
138
        streamingBuffer->addColors (1, colorData);
 
139
 
 
140
        streamingBuffer->end ();
 
141
        streamingBuffer->render (transform);
131
142
    }
132
143
    else
133
144
    {
134
 
        data.reset (new GLfloat [nBox * 16]);
135
 
 
136
 
        d = data.get ();
137
145
        n = nBox;
138
146
 
139
147
        for (unsigned int i = 0; i < backgroundTextures.size (); i++)
140
148
        {
 
149
            GLfloat textureData[12];
141
150
            GLTexture *bg = backgroundTextures[i];
142
151
            CompRegion r = region & *bg;
143
152
 
144
153
            pBox = const_cast <Region> (r.handle ())->rects;
145
154
            nBox = const_cast <Region> (r.handle ())->numRects;
146
 
            d = data.get ();
147
155
            n = nBox;
148
156
 
 
157
            streamingBuffer->begin (GL_TRIANGLES);
 
158
 
149
159
            while (n--)
150
160
            {
151
 
                *d++ = COMP_TEX_COORD_X (bg->matrix (), pBox->x1);
152
 
                *d++ = COMP_TEX_COORD_Y (bg->matrix (), pBox->y2);
153
 
 
154
 
                *d++ = pBox->x1;
155
 
                *d++ = pBox->y2;
156
 
 
157
 
                *d++ = COMP_TEX_COORD_X (bg->matrix (), pBox->x2);
158
 
                *d++ = COMP_TEX_COORD_Y (bg->matrix (), pBox->y2);
159
 
 
160
 
                *d++ = pBox->x2;
161
 
                *d++ = pBox->y2;
162
 
 
163
 
                *d++ = COMP_TEX_COORD_X (bg->matrix (), pBox->x2);
164
 
                *d++ = COMP_TEX_COORD_Y (bg->matrix (), pBox->y1);
165
 
 
166
 
                *d++ = pBox->x2;
167
 
                *d++ = pBox->y1;
168
 
 
169
 
                *d++ = COMP_TEX_COORD_X (bg->matrix (), pBox->x1);
170
 
                *d++ = COMP_TEX_COORD_Y (bg->matrix (), pBox->y1);
171
 
 
172
 
                *d++ = pBox->x1;
173
 
                *d++ = pBox->y1;
 
161
                GLfloat tx1 = COMP_TEX_COORD_X (bg->matrix (), pBox->x1);
 
162
                GLfloat tx2 = COMP_TEX_COORD_X (bg->matrix (), pBox->x2);
 
163
                GLfloat ty1 = COMP_TEX_COORD_Y (bg->matrix (), pBox->y1);
 
164
                GLfloat ty2 = COMP_TEX_COORD_Y (bg->matrix (), pBox->y2);
 
165
 
 
166
                vertexData[0]  = pBox->x1;
 
167
                vertexData[1]  = pBox->y1;
 
168
                vertexData[2]  = 0.0f;
 
169
                vertexData[3]  = pBox->x1;
 
170
                vertexData[4]  = pBox->y2;
 
171
                vertexData[5]  = 0.0f;
 
172
                vertexData[6]  = pBox->x2;
 
173
                vertexData[7]  = pBox->y1;
 
174
                vertexData[8]  = 0.0f;
 
175
                vertexData[9]  = pBox->x1;
 
176
                vertexData[10] = pBox->y2;
 
177
                vertexData[11] = 0.0f;
 
178
                vertexData[12] = pBox->x2;
 
179
                vertexData[13] = pBox->y2;
 
180
                vertexData[14] = 0.0f;
 
181
 
 
182
                vertexData[15] = pBox->x2;
 
183
                vertexData[16] = pBox->y1;
 
184
                vertexData[17] = 0.0f;
 
185
 
 
186
                textureData[0]  = tx1;
 
187
                textureData[1]  = ty1;
 
188
 
 
189
                textureData[2]  = tx1;
 
190
                textureData[3]  = ty2;
 
191
 
 
192
                textureData[4]  = tx2;
 
193
                textureData[5]  = ty1;
 
194
 
 
195
                textureData[6]  = tx1;
 
196
                textureData[7]  = ty2;
 
197
 
 
198
                textureData[8]  = tx2;
 
199
                textureData[9]  = ty2;
 
200
 
 
201
                textureData[10] = tx2;
 
202
                textureData[11] = ty1;
 
203
 
 
204
                streamingBuffer->addVertices (6, vertexData);
 
205
                streamingBuffer->addTexCoords (0, 6, textureData);
174
206
 
175
207
                pBox++;
176
208
            }
177
209
 
178
 
            glTexCoordPointer (2, GL_FLOAT, sizeof (GLfloat) * 4, &data[0]);
179
 
            glVertexPointer (2, GL_FLOAT, sizeof (GLfloat) * 4, &data[2]);
 
210
            streamingBuffer->end ();
180
211
 
181
212
            if (bg->name ())
182
213
            {
185
216
                else
186
217
                    bg->enable (GLTexture::Fast);
187
218
 
188
 
                glDrawArrays (GL_QUADS, 0, nBox * 4);
 
219
                streamingBuffer->render (transform);
189
220
 
190
221
                bg->disable ();
191
222
            }
329
360
        CompositeWindow::get (fullscreenWindow)->unredirect ();
330
361
 
331
362
    if (!(mask & PAINT_SCREEN_NO_BACKGROUND_MASK))
332
 
        paintBackground (tmpRegion, (mask & PAINT_SCREEN_TRANSFORMED_MASK));
 
363
        paintBackground (transform,
 
364
                         tmpRegion,
 
365
                         (mask & PAINT_SCREEN_TRANSFORMED_MASK));
333
366
 
334
367
    /* paint all windows from bottom to top */
335
368
    foreach (w, pl)
370
403
    }
371
404
}
372
405
 
 
406
// transformIsSimple tells you if it's simple enough to use scissoring
 
407
static bool
 
408
transformIsSimple (const GLMatrix &transform)
 
409
{
 
410
    const float *t = transform.getMatrix ();
 
411
    return // t[0] can be anything (x scale)
 
412
           t[1] == 0.0f &&
 
413
           t[2] == 0.0f &&
 
414
           t[3] == 0.0f &&
 
415
           t[4] == 0.0f &&
 
416
           // t[5] can be anything (y scale)
 
417
           t[6] == 0.0f &&
 
418
           t[7] == 0.0f &&
 
419
           t[8] == 0.0f &&
 
420
           t[9] == 0.0f &&
 
421
           // t[10] can be anything (z scale)
 
422
           t[11] == 0.0f &&
 
423
           // t[12]..t[14] can be anything (translation)
 
424
           t[15] == 1.0f;
 
425
}
 
426
 
373
427
void
374
428
GLScreen::glEnableOutputClipping (const GLMatrix   &transform,
375
429
                                  const CompRegion &region,
377
431
{
378
432
    WRAPABLE_HND_FUNCTN (glEnableOutputClipping, transform, region, output)
379
433
 
380
 
    GLdouble h = screen->height ();
381
 
 
382
 
    GLdouble p1[2] = { static_cast<GLdouble> (region.handle ()->extents.x1),
383
 
                       static_cast<GLdouble> (h - region.handle ()->extents.y2) };
384
 
    GLdouble p2[2] = { static_cast<GLdouble> (region.handle ()->extents.x2),
385
 
                       static_cast<GLdouble> (h - region.handle ()->extents.y1) };
386
 
 
387
 
    GLdouble halfW = output->width () / 2.0;
388
 
    GLdouble halfH = output->height () / 2.0;
389
 
 
390
 
    GLdouble cx = output->x1 () + halfW;
391
 
    GLdouble cy = (h - output->y2 ()) + halfH;
392
 
 
393
 
    GLdouble top[4]    = { 0.0, halfH / (cy - p1[1]), 0.0, 0.5 };
394
 
    GLdouble bottom[4] = { 0.0, halfH / (cy - p2[1]), 0.0, 0.5 };
395
 
    GLdouble left[4]   = { halfW / (cx - p1[0]), 0.0, 0.0, 0.5 };
396
 
    GLdouble right[4]  = { halfW / (cx - p2[0]), 0.0, 0.0, 0.5 };
397
 
 
398
 
    glPushMatrix ();
399
 
    glLoadMatrixf (transform.getMatrix ());
400
 
 
401
 
    glClipPlane (GL_CLIP_PLANE0, top);
402
 
    glClipPlane (GL_CLIP_PLANE1, bottom);
403
 
    glClipPlane (GL_CLIP_PLANE2, left);
404
 
    glClipPlane (GL_CLIP_PLANE3, right);
405
 
 
406
 
    glEnable (GL_CLIP_PLANE0);
407
 
    glEnable (GL_CLIP_PLANE1);
408
 
    glEnable (GL_CLIP_PLANE2);
409
 
    glEnable (GL_CLIP_PLANE3);
410
 
 
411
 
    glPopMatrix ();
 
434
    // Bottom-left corner of the output:
 
435
    const GLint x = output->x1 ();
 
436
    const GLint y = screen->height () - output->y2 ();
 
437
    const GLsizei w = output->width ();
 
438
    const GLsizei h = output->height ();
 
439
 
 
440
    // Transformed (only scale and translation is supported!)
 
441
    const float *t = transform.getMatrix ();
 
442
    const GLfloat scalex = t[0], scaley = t[5], transx = t[12], transy = t[13];
 
443
    const GLfloat centrex = x + w / 2.0f;
 
444
    const GLfloat centrey = y + h / 2.0f;
 
445
    GLfloat scaledw = fabs (w * scalex);
 
446
    GLfloat scaledh = fabs (h * scaley);
 
447
    GLfloat tx = centrex - (scaledw / 2.0f) + transx * w;
 
448
    GLfloat ty = centrey - (scaledh / 2.0f) + transy * h;
 
449
 
 
450
    glScissor (tx, ty, roundf (scaledw), roundf (scaledh));
 
451
    glEnable (GL_SCISSOR_TEST);
412
452
}
413
453
 
414
454
void
416
456
{
417
457
    WRAPABLE_HND_FUNCTN (glDisableOutputClipping)
418
458
 
419
 
    glDisable (GL_CLIP_PLANE0);
420
 
    glDisable (GL_CLIP_PLANE1);
421
 
    glDisable (GL_CLIP_PLANE2);
422
 
    glDisable (GL_CLIP_PLANE3);
 
459
    glDisable (GL_SCISSOR_TEST);
 
460
}
 
461
 
 
462
void
 
463
GLScreen::glBufferStencil (const GLMatrix       &matrix,
 
464
                           GLVertexBuffer       &vertexBuffer,
 
465
                           CompOutput           *output)
 
466
{
 
467
    WRAPABLE_HND_FUNCTN (glBufferStencil, matrix, vertexBuffer, output);
 
468
 
 
469
    GLfloat x = output->x ();
 
470
    GLfloat y = screen->height () - output->y2 ();
 
471
    GLfloat x2 = output->x () + output->width ();
 
472
    GLfloat y2 = screen->height () - output->y2 () + output->height ();
 
473
 
 
474
    GLfloat vertices[] =
 
475
    {
 
476
        x, y, 0,
 
477
        x, y2, 0,
 
478
        x2, y, 0,
 
479
        x2, y2, 0
 
480
    };
 
481
 
 
482
    GLushort colorData[] = { 0xffff, 0xffff, 0xffff, 0xffff };
 
483
 
 
484
    vertexBuffer.begin (GL_TRIANGLE_STRIP);
 
485
 
 
486
    vertexBuffer.addVertices (4, vertices);
 
487
    vertexBuffer.addColors (1, colorData);
 
488
 
 
489
    vertexBuffer.end ();
423
490
}
424
491
 
425
492
#define CLIP_PLANE_MASK (PAINT_SCREEN_TRANSFORMED_MASK | \
446
513
 
447
514
    if ((mask & CLIP_PLANE_MASK) == CLIP_PLANE_MASK)
448
515
    {
449
 
        glEnableOutputClipping (sTransform, region, output);
450
 
 
451
 
        sTransform.toScreenSpace (output, -sAttrib.zTranslate);
452
 
 
453
 
        glPushMatrix ();
454
 
        glLoadMatrixf (sTransform.getMatrix ());
455
 
 
456
 
        priv->paintOutputRegion (sTransform, region, output, mask);
457
 
 
458
 
        glPopMatrix ();
459
 
 
460
 
        glDisableOutputClipping ();
 
516
        if (transformIsSimple (sTransform))
 
517
        {
 
518
            glEnableOutputClipping (sTransform, region, output);
 
519
            sTransform.toScreenSpace (output, -sAttrib.zTranslate);
 
520
            priv->paintOutputRegion (sTransform, region, output, mask);
 
521
            glDisableOutputClipping ();
 
522
        }
 
523
        else if ( (GL::fboEnabled && GL::fboStencilSupported) ||
 
524
                  GL::stencilBuffer )
 
525
        {
 
526
            sTransform.toScreenSpace (output, -sAttrib.zTranslate);
 
527
 
 
528
            glClearStencil (0);
 
529
            glClear (GL_STENCIL_BUFFER_BIT);
 
530
            glEnable (GL_STENCIL_TEST);
 
531
            glStencilFunc (GL_ALWAYS, 1, 1);
 
532
            glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE);
 
533
 
 
534
            GLVertexBuffer vb;
 
535
            vb.setAutoProgram (priv->autoProgram);
 
536
            glBufferStencil (sTransform, vb, output);
 
537
            glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
 
538
            glStencilMask (1);
 
539
            vb.render (sTransform);
 
540
            glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
 
541
 
 
542
            glStencilFunc (GL_EQUAL, 1, 1);
 
543
            glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP);
 
544
            priv->paintOutputRegion (sTransform, region, output, mask);
 
545
            glDisable (GL_STENCIL_TEST);
 
546
        }
 
547
        else
 
548
        {
 
549
            // This won't look quite right but should never happen.
 
550
            // Give a warning?
 
551
            sTransform.toScreenSpace (output, -sAttrib.zTranslate);
 
552
            priv->paintOutputRegion (sTransform, region, output, mask);
 
553
        }
461
554
    }
462
555
    else
463
556
    {
464
557
        sTransform.toScreenSpace (output, -sAttrib.zTranslate);
465
 
 
466
 
        glPushMatrix ();
467
 
        glLoadMatrixf (sTransform.getMatrix ());
468
 
 
469
558
        priv->paintOutputRegion (sTransform, region, output, mask);
470
 
 
471
 
        glPopMatrix ();
472
559
    }
473
560
}
474
561
 
503
590
 
504
591
        sTransform.toScreenSpace (output, -DEFAULT_Z_CAMERA);
505
592
 
506
 
        glPushMatrix ();
507
 
        glLoadMatrixf (sTransform.getMatrix ());
508
 
 
509
593
        priv->paintOutputRegion (sTransform, region, output, mask);
510
594
 
511
 
        glPopMatrix ();
512
 
 
513
595
        return true;
514
596
    }
515
597
    else if (mask & PAINT_SCREEN_FULL_MASK)
525
607
    }
526
608
}
527
609
 
528
 
#define ADD_RECT(data, m, n, x1, y1, x2, y2)       \
529
 
    for (it = 0; it < n; it++)                     \
530
 
    {                                              \
531
 
        const GLTexture::Matrix &mat = m[it];      \
532
 
        *(data)++ = COMP_TEX_COORD_X (mat, x1);    \
533
 
        *(data)++ = COMP_TEX_COORD_Y (mat, y1);    \
534
 
    }                                              \
535
 
    *(data)++ = (x1);                              \
536
 
    *(data)++ = (y1);                              \
537
 
    *(data)++ = 0.0;                               \
538
 
    for (it = 0; it < n; it++)                     \
539
 
    {                                              \
540
 
        const GLTexture::Matrix &mat = m[it];      \
541
 
        *(data)++ = COMP_TEX_COORD_X (mat, x1);    \
542
 
        *(data)++ = COMP_TEX_COORD_Y (mat, y2);    \
543
 
    }                                              \
544
 
    *(data)++ = (x1);                              \
545
 
    *(data)++ = (y2);                              \
546
 
    *(data)++ = 0.0;                               \
547
 
    for (it = 0; it < n; it++)                     \
548
 
    {                                              \
549
 
        const GLTexture::Matrix &mat = m[it];      \
550
 
        *(data)++ = COMP_TEX_COORD_X (mat, x2);    \
551
 
        *(data)++ = COMP_TEX_COORD_Y (mat, y2);    \
552
 
    }                                              \
553
 
    *(data)++ = (x2);                              \
554
 
    *(data)++ = (y2);                              \
555
 
    *(data)++ = 0.0;                               \
556
 
    for (it = 0; it < n; it++)                     \
557
 
    {                                              \
558
 
        const GLTexture::Matrix &mat = m[it];      \
559
 
        *(data)++ = COMP_TEX_COORD_X (mat, x2);    \
560
 
        *(data)++ = COMP_TEX_COORD_Y (mat, y1);    \
561
 
    }                                              \
562
 
    *(data)++ = (x2);                              \
563
 
    *(data)++ = (y1);                              \
564
 
    *(data)++ = 0.0
565
 
 
566
 
#define ADD_QUAD(data, m, n, x1, y1, x2, y2)            \
567
 
    for (it = 0; it < n; it++)                          \
568
 
    {                                                   \
569
 
        const GLTexture::Matrix &mat = m[it];           \
570
 
        *(data)++ = COMP_TEX_COORD_XY (mat, x1, y1);    \
571
 
        *(data)++ = COMP_TEX_COORD_YX (mat, x1, y1);    \
572
 
    }                                                   \
573
 
    *(data)++ = (x1);                                   \
574
 
    *(data)++ = (y1);                                   \
575
 
    *(data)++ = 0.0;                                    \
576
 
    for (it = 0; it < n; it++)                          \
577
 
    {                                                   \
578
 
        const GLTexture::Matrix &mat = m[it];           \
579
 
        *(data)++ = COMP_TEX_COORD_XY (mat, x1, y2);    \
580
 
        *(data)++ = COMP_TEX_COORD_YX (mat, x1, y2);    \
581
 
    }                                                   \
582
 
    *(data)++ = (x1);                                   \
583
 
    *(data)++ = (y2);                                   \
584
 
    *(data)++ = 0.0;                                    \
585
 
    for (it = 0; it < n; it++)                          \
586
 
    {                                                   \
587
 
        const GLTexture::Matrix &mat = m[it];           \
588
 
        *(data)++ = COMP_TEX_COORD_XY (mat, x2, y2);    \
589
 
        *(data)++ = COMP_TEX_COORD_YX (mat, x2, y2);    \
590
 
    }                                                   \
591
 
    *(data)++ = (x2);                                   \
592
 
    *(data)++ = (y2);                                   \
593
 
    *(data)++ = 0.0;                                    \
594
 
    for (it = 0; it < n; it++)                          \
595
 
    {                                                   \
596
 
        const GLTexture::Matrix &mat = m[it];           \
597
 
        *(data)++ = COMP_TEX_COORD_XY (mat, x2, y1);    \
598
 
        *(data)++ = COMP_TEX_COORD_YX (mat, x2, y1);    \
599
 
    }                                                   \
600
 
    *(data)++ = (x2);                                   \
601
 
    *(data)++ = (y1);                                   \
602
 
    *(data)++ = 0.0;
603
 
 
604
610
void
605
 
GLWindow::glDrawGeometry ()
 
611
GLScreen::glPaintCompositedOutput (const CompRegion    &region,
 
612
                                   GLFramebufferObject *fbo,
 
613
                                   unsigned int         mask)
606
614
{
607
 
    WRAPABLE_HND_FUNCTN (glDrawGeometry)
608
 
 
609
 
    int     texUnit = priv->geometry.texUnits;
610
 
    int     currentTexUnit = 0;
611
 
    int     stride = priv->geometry.vertexStride;
612
 
    GLfloat *vertices = priv->geometry.vertices + (stride - 3);
613
 
 
614
 
    stride *= sizeof (GLfloat);
615
 
 
616
 
    glVertexPointer (3, GL_FLOAT, stride, vertices);
617
 
 
618
 
    while (texUnit--)
619
 
    {
620
 
        if (texUnit != currentTexUnit)
621
 
        {
622
 
            (*GL::clientActiveTexture) (GL_TEXTURE0_ARB + texUnit);
623
 
            glEnableClientState (GL_TEXTURE_COORD_ARRAY);
624
 
            currentTexUnit = texUnit;
625
 
        }
626
 
        vertices -= priv->geometry.texCoordSize;
627
 
        glTexCoordPointer (priv->geometry.texCoordSize,
628
 
                           GL_FLOAT, stride, vertices);
629
 
    }
630
 
 
631
 
    glDrawArrays (GL_QUADS, 0, priv->geometry.vCount);
632
 
 
633
 
    /* disable all texture coordinate arrays except 0 */
634
 
    texUnit = priv->geometry.texUnits;
635
 
    if (texUnit > 1)
636
 
    {
637
 
        while (--texUnit)
638
 
        {
639
 
            (*GL::clientActiveTexture) (GL_TEXTURE0_ARB + texUnit);
640
 
            glDisableClientState (GL_TEXTURE_COORD_ARRAY);
641
 
        }
642
 
 
643
 
        (*GL::clientActiveTexture) (GL_TEXTURE0_ARB);
644
 
    }
 
615
    WRAPABLE_HND_FUNCTN (glPaintCompositedOutput, region, fbo, mask)
 
616
 
 
617
    GLMatrix sTransform;
 
618
    std::vector<GLfloat> vertexData;
 
619
    std::vector<GLfloat> textureData;
 
620
    const GLTexture::Matrix & texmatrix = fbo->tex ()->matrix ();
 
621
    GLVertexBuffer *streamingBuffer = GLVertexBuffer::streamingBuffer ();
 
622
 
 
623
    streamingBuffer->begin (GL_TRIANGLES);
 
624
 
 
625
    if (mask & COMPOSITE_SCREEN_DAMAGE_ALL_MASK)
 
626
    {
 
627
        GLfloat tx1 = COMP_TEX_COORD_X (texmatrix, 0.0f);
 
628
        GLfloat tx2 = COMP_TEX_COORD_X (texmatrix, screen->width ());
 
629
        GLfloat ty1 = 1.0 - COMP_TEX_COORD_Y (texmatrix, 0.0f);
 
630
        GLfloat ty2 = 1.0 - COMP_TEX_COORD_Y (texmatrix, screen->height ());
 
631
 
 
632
        vertexData = {
 
633
            0.0f,                    0.0f,                     0.0f,
 
634
            0.0f,                    (float)screen->height (), 0.0f,
 
635
            (float)screen->width (), 0.0f,                     0.0f,
 
636
 
 
637
            0.0f,                    (float)screen->height (), 0.0f,
 
638
            (float)screen->width (), (float)screen->height (), 0.0f,
 
639
            (float)screen->width (), 0.0f,                     0.0f,
 
640
        };
 
641
 
 
642
        textureData = {
 
643
            tx1, ty1,
 
644
            tx1, ty2,
 
645
            tx2, ty1,
 
646
            tx1, ty2,
 
647
            tx2, ty2,
 
648
            tx2, ty1,
 
649
        };
 
650
 
 
651
        streamingBuffer->addVertices (6, &vertexData[0]);
 
652
        streamingBuffer->addTexCoords (0, 6, &textureData[0]);
 
653
    }
 
654
    else
 
655
    {
 
656
        BoxPtr pBox = const_cast <Region> (region.handle ())->rects;
 
657
        int nBox = const_cast <Region> (region.handle ())->numRects;
 
658
 
 
659
        while (nBox--)
 
660
        {
 
661
            GLfloat tx1 = COMP_TEX_COORD_X (texmatrix, pBox->x1);
 
662
            GLfloat tx2 = COMP_TEX_COORD_X (texmatrix, pBox->x2);
 
663
            GLfloat ty1 = 1.0 - COMP_TEX_COORD_Y (texmatrix, pBox->y1);
 
664
            GLfloat ty2 = 1.0 - COMP_TEX_COORD_Y (texmatrix, pBox->y2);
 
665
 
 
666
            vertexData = {
 
667
                (float)pBox->x1, (float)pBox->y1, 0.0f,
 
668
                (float)pBox->x1, (float)pBox->y2, 0.0f,
 
669
                (float)pBox->x2, (float)pBox->y1, 0.0f,
 
670
 
 
671
                (float)pBox->x1, (float)pBox->y2, 0.0f,
 
672
                (float)pBox->x2, (float)pBox->y2, 0.0f,
 
673
                (float)pBox->x2, (float)pBox->y1, 0.0f,
 
674
            };
 
675
 
 
676
            textureData = {
 
677
                tx1, ty1,
 
678
                tx1, ty2,
 
679
                tx2, ty1,
 
680
                tx1, ty2,
 
681
                tx2, ty2,
 
682
                tx2, ty1,
 
683
            };
 
684
 
 
685
            streamingBuffer->addVertices (6, &vertexData[0]);
 
686
            streamingBuffer->addTexCoords (0, 6, &textureData[0]);
 
687
            pBox++;
 
688
        }
 
689
    }
 
690
 
 
691
    streamingBuffer->end ();
 
692
    fbo->tex ()->enable (GLTexture::Fast);
 
693
    sTransform.toScreenSpace (&screen->fullscreenOutput (), -DEFAULT_Z_CAMERA);
 
694
    streamingBuffer->render (sTransform);
 
695
    fbo->tex ()->disable ();
645
696
}
646
697
 
647
 
static inline void
648
 
addSingleQuad (GLfloat      *&d,
 
698
static void
 
699
addSingleQuad (GLVertexBuffer *vertexBuffer,
649
700
               const        GLTexture::MatrixList &matrix,
650
701
               unsigned int nMatrix,
651
702
               int          x1,
652
703
               int          y1,
653
704
               int          x2,
654
705
               int          y2,
655
 
               int          &n,
656
706
               bool         rect)
657
707
{
658
 
    unsigned int it;
 
708
    GLfloat vertexData[18] = {
 
709
        (float)x1, (float)y1, 0.0,
 
710
        (float)x1, (float)y2, 0.0,
 
711
        (float)x2, (float)y1, 0.0,
 
712
        (float)x2, (float)y1, 0.0,
 
713
        (float)x1, (float)y2, 0.0,
 
714
        (float)x2, (float)y2, 0.0
 
715
    };
 
716
    vertexBuffer->addVertices (6, vertexData);
659
717
 
660
718
    if (rect)
661
719
    {
662
 
        ADD_RECT (d, matrix, nMatrix, x1, y1, x2, y2);
 
720
        unsigned int it;
 
721
        for (it = 0; it < nMatrix; it++)
 
722
        {
 
723
            GLfloat data[2];
 
724
            const GLTexture::Matrix &mat = matrix[it];
 
725
            data[0] = COMP_TEX_COORD_X (mat, x1);
 
726
            data[1] = COMP_TEX_COORD_Y (mat, y1);
 
727
            vertexBuffer->addTexCoords (it, 1, data);
 
728
        }
 
729
        for (it = 0; it < nMatrix; it++)
 
730
        {
 
731
            GLfloat data[2];
 
732
            const GLTexture::Matrix &mat = matrix[it];
 
733
            data[0] = COMP_TEX_COORD_X (mat, x1);
 
734
            data[1] = COMP_TEX_COORD_Y (mat, y2);
 
735
            vertexBuffer->addTexCoords (it, 1, data);
 
736
        }
 
737
        for (it = 0; it < nMatrix; it++)
 
738
        {
 
739
            GLfloat data[2];
 
740
            const GLTexture::Matrix &mat = matrix[it];
 
741
            data[0] = COMP_TEX_COORD_X (mat, x2);
 
742
            data[1] = COMP_TEX_COORD_Y (mat, y1);
 
743
            vertexBuffer->addTexCoords (it, 1, data);
 
744
        }
 
745
        for (it = 0; it < nMatrix; it++)
 
746
        {
 
747
            GLfloat data[2];
 
748
            const GLTexture::Matrix &mat = matrix[it];
 
749
            data[0] = COMP_TEX_COORD_X (mat, x2);
 
750
            data[1] = COMP_TEX_COORD_Y (mat, y1);
 
751
            vertexBuffer->addTexCoords (it, 1, data);
 
752
        }
 
753
        for (it = 0; it < nMatrix; it++)
 
754
        {
 
755
            GLfloat data[2];
 
756
            const GLTexture::Matrix &mat = matrix[it];
 
757
            data[0] = COMP_TEX_COORD_X (mat, x1);
 
758
            data[1] = COMP_TEX_COORD_Y (mat, y2);
 
759
            vertexBuffer->addTexCoords (it, 1, data);
 
760
        }
 
761
        for (it = 0; it < nMatrix; it++)
 
762
        {
 
763
            GLfloat data[2];
 
764
            const GLTexture::Matrix &mat = matrix[it];
 
765
            data[0] = COMP_TEX_COORD_X (mat, x2);
 
766
            data[1] = COMP_TEX_COORD_Y (mat, y2);
 
767
            vertexBuffer->addTexCoords (it, 1, data);
 
768
        }
663
769
    }
664
770
    else
665
771
    {
666
 
        ADD_QUAD (d, matrix, nMatrix, x1, y1, x2, y2);
 
772
        unsigned int it;
 
773
        for (it = 0; it < nMatrix; it++)
 
774
        {
 
775
            GLfloat data[2];
 
776
            const GLTexture::Matrix &mat = matrix[it];
 
777
            data[0] = COMP_TEX_COORD_XY (mat, x1, y1);
 
778
            data[1] = COMP_TEX_COORD_YX (mat, x1, y1);
 
779
            vertexBuffer->addTexCoords (it, 1, data);
 
780
        }
 
781
        for (it = 0; it < nMatrix; it++)
 
782
        {
 
783
            GLfloat data[2];
 
784
            const GLTexture::Matrix &mat = matrix[it];
 
785
            data[0] = COMP_TEX_COORD_XY (mat, x1, y2);
 
786
            data[1] = COMP_TEX_COORD_YX (mat, x1, y2);
 
787
            vertexBuffer->addTexCoords (it, 1, data);
 
788
        }
 
789
        for (it = 0; it < nMatrix; it++)
 
790
        {
 
791
            GLfloat data[2];
 
792
            const GLTexture::Matrix &mat = matrix[it];
 
793
            data[0] = COMP_TEX_COORD_XY (mat, x2, y1);
 
794
            data[1] = COMP_TEX_COORD_YX (mat, x2, y1);
 
795
            vertexBuffer->addTexCoords (it, 1, data);
 
796
        }
 
797
        for (it = 0; it < nMatrix; it++)
 
798
        {
 
799
            GLfloat data[2];
 
800
            const GLTexture::Matrix &mat = matrix[it];
 
801
            data[0] = COMP_TEX_COORD_XY (mat, x2, y1);
 
802
            data[1] = COMP_TEX_COORD_YX (mat, x2, y1);
 
803
            vertexBuffer->addTexCoords (it, 1, data);
 
804
        }
 
805
        for (it = 0; it < nMatrix; it++)
 
806
        {
 
807
            GLfloat data[2];
 
808
            const GLTexture::Matrix &mat = matrix[it];
 
809
            data[0] = COMP_TEX_COORD_XY (mat, x1, y2);
 
810
            data[1] = COMP_TEX_COORD_YX (mat, x1, y2);
 
811
            vertexBuffer->addTexCoords (it, 1, data);
 
812
        }
 
813
        for (it = 0; it < nMatrix; it++)
 
814
        {
 
815
            GLfloat data[2];
 
816
            const GLTexture::Matrix &mat = matrix[it];
 
817
            data[0] = COMP_TEX_COORD_XY (mat, x2, y2);
 
818
            data[1] = COMP_TEX_COORD_YX (mat, x2, y2);
 
819
            vertexBuffer->addTexCoords (it, 1, data);
 
820
        }
667
821
    }
668
 
    n++;
669
822
}
670
823
 
671
 
static inline void
672
 
addQuads (GLfloat      *&d,
 
824
static void
 
825
addQuads (GLVertexBuffer *vertexBuffer,
673
826
          const        GLTexture::MatrixList &matrix,
674
827
          unsigned int nMatrix,
675
828
          int          x1,
676
829
          int          y1,
677
830
          int          x2,
678
831
          int          y2,
679
 
          int          &n,
680
 
          int          vSize,
681
832
          bool         rect,
682
 
          GLWindow::Geometry &geometry,
683
833
          unsigned int maxGridWidth,
684
834
          unsigned int maxGridHeight)
685
835
{
687
837
        1 + (x2 - x1 - 1) / (int) maxGridWidth;  // ceil. division
688
838
    int nQuadsY = (maxGridHeight == MAXSHORT) ? 1 :
689
839
        1 + (y2 - y1 - 1) / (int) maxGridHeight;
690
 
    int newVertexSize = (n + nQuadsX * nQuadsY) * vSize * 4;
691
 
 
692
 
    // Make sure enough vertices are allocated for nQuadsX * nQuadsY more quads
693
 
    if (newVertexSize > geometry.vertexSize)
694
 
    {
695
 
        if (!geometry.moreVertices (newVertexSize))
696
 
            return;
697
 
 
698
 
        d = geometry.vertices + (n * vSize * 4);
699
 
    }
700
840
 
701
841
    if (nQuadsX == 1 && nQuadsY == 1)
702
842
    {
703
 
        addSingleQuad (d, matrix, nMatrix, x1, y1, x2, y2, n, rect);
 
843
        addSingleQuad (vertexBuffer, matrix, nMatrix, x1, y1, x2, y2, rect);
704
844
    }
705
845
    else
706
846
    {
716
856
            {
717
857
                nx2 = MIN (nx1 + (int) quadWidth, x2);
718
858
 
719
 
                addSingleQuad (d, matrix, nMatrix, nx1, ny1, nx2, ny2, n, rect);
 
859
                addSingleQuad (vertexBuffer, matrix, nMatrix,
 
860
                               nx1, ny1, nx2, ny2, rect);
720
861
            }
721
862
        }
722
863
    }
734
875
    BoxRec full;
735
876
    int    nMatrix = matrix.size ();
736
877
 
737
 
    priv->geometry.texUnits = nMatrix;
738
 
 
739
878
    full = clip.handle ()->extents;
740
879
    if (region.handle ()->extents.x1 > full.x1)
741
880
        full.x1 = region.handle ()->extents.x1;
753
892
        BoxPtr  pClip;
754
893
        int     nClip;
755
894
        BoxRec  cbox;
756
 
        int     vSize;
757
 
        int     n, it, x1, y1, x2, y2;
758
 
        GLfloat *d;
 
895
        int     it, x1, y1, x2, y2;
759
896
        bool    rect = true;
760
897
 
761
898
        for (it = 0; it < nMatrix; it++)
770
907
        pBox = const_cast <Region> (region.handle ())->rects;
771
908
        nBox = const_cast <Region> (region.handle ())->numRects;
772
909
 
773
 
        vSize = 3 + nMatrix * 2;
774
 
 
775
 
        n = priv->geometry.vCount / 4;
776
 
 
777
 
        if ((n + nBox) * vSize * 4 > priv->geometry.vertexSize)
778
 
        {
779
 
            if (!priv->geometry.moreVertices ((n + nBox) * vSize * 4))
780
 
                return;
781
 
        }
782
 
 
783
 
        d = priv->geometry.vertices + (priv->geometry.vCount * vSize);
784
 
 
785
910
        while (nBox--)
786
911
        {
787
912
            x1 = pBox->x1;
806
931
 
807
932
                if (nClip == 1)
808
933
                {
809
 
                    addQuads (d, matrix, nMatrix,
 
934
                    addQuads (priv->vertexBuffer, matrix, nMatrix,
810
935
                              x1, y1, x2, y2,
811
 
                              n, vSize, rect, priv->geometry,
 
936
                              rect,
812
937
                              maxGridWidth, maxGridHeight);
813
938
                }
814
939
                else
815
940
                {
816
941
                    pClip = const_cast <Region> (clip.handle ())->rects;
817
942
 
818
 
                    if (((n + nClip) * vSize * 4) > priv->geometry.vertexSize)
819
 
                    {
820
 
                        if (!priv->geometry.moreVertices ((n + nClip) *
821
 
                                                          vSize * 4))
822
 
                            return;
823
 
 
824
 
                        d = priv->geometry.vertices + (n * vSize * 4);
825
 
                    }
826
 
 
827
943
                    while (nClip--)
828
944
                    {
829
945
                        cbox = *pClip;
841
957
 
842
958
                        if (cbox.x1 < cbox.x2 && cbox.y1 < cbox.y2)
843
959
                        {
844
 
                            addQuads (d, matrix, nMatrix,
 
960
                            addQuads (priv->vertexBuffer, matrix, nMatrix,
845
961
                                      cbox.x1, cbox.y1, cbox.x2, cbox.y2,
846
 
                                      n, vSize, rect, priv->geometry,
 
962
                                      rect,
847
963
                                      maxGridWidth, maxGridHeight);
848
964
                        }
849
965
                    }
850
966
                }
851
967
            }
852
968
        }
853
 
 
854
 
        priv->geometry.vCount       = n * 4;
855
 
        priv->geometry.vertexStride = vSize;
856
 
        priv->geometry.texCoordSize = 2;
857
 
    }
858
 
}
859
 
 
860
 
static bool
861
 
enableFragmentProgramAndDrawGeometry (GLScreen           *gs,
862
 
                                      GLWindow           *w,
863
 
                                      GLTexture          *texture,
864
 
                                      GLFragment::Attrib &attrib,
865
 
                                      GLTexture::Filter  filter,
866
 
                                      unsigned int       mask)
867
 
{
868
 
    GLFragment::Attrib fa (attrib);
869
 
    bool               blending;
870
 
 
871
 
    if (GL::canDoSaturated && attrib.getSaturation () != COLOR)
872
 
    {
873
 
        int param, function;
874
 
 
875
 
        param    = fa.allocParameters (1);
876
 
        function =
877
 
            GLFragment::getSaturateFragmentFunction (texture, param);
878
 
 
879
 
        fa.addFunction (function);
880
 
 
881
 
        (*GL::programEnvParameter4f) (GL_FRAGMENT_PROGRAM_ARB, param,
882
 
                                      RED_SATURATION_WEIGHT,
883
 
                                      GREEN_SATURATION_WEIGHT,
884
 
                                      BLUE_SATURATION_WEIGHT,
885
 
                                      attrib.getSaturation () / 65535.0f);
886
 
    }
887
 
 
888
 
    if (!fa.enable (&blending))
889
 
        return false;
890
 
 
891
 
    texture->enable (filter);
892
 
 
893
 
    if (mask & PAINT_WINDOW_BLEND_MASK)
894
 
    {
895
 
        if (blending)
896
 
            glEnable (GL_BLEND);
897
 
 
898
 
        if (attrib.getOpacity () != OPAQUE || attrib.getBrightness () != BRIGHT)
899
 
        {
900
 
            GLushort color;
901
 
 
902
 
            color = (attrib.getOpacity () * attrib.getBrightness ()) >> 16;
903
 
 
904
 
            gs->setTexEnvMode (GL_MODULATE);
905
 
            glColor4us (color, color, color, attrib.getOpacity ());
906
 
 
907
 
            w->glDrawGeometry ();
908
 
 
909
 
            glColor4usv (defaultColor);
910
 
            gs->setTexEnvMode (GL_REPLACE);
911
 
        }
912
 
        else
913
 
        {
914
 
            w->glDrawGeometry ();
915
 
        }
916
 
 
917
 
        if (blending)
918
 
            glDisable (GL_BLEND);
919
 
    }
920
 
    else if (attrib.getBrightness () != BRIGHT)
921
 
    {
922
 
        gs->setTexEnvMode (GL_MODULATE);
923
 
        glColor4us (attrib.getBrightness (), attrib.getBrightness (),
924
 
                    attrib.getBrightness (), BRIGHT);
925
 
 
926
 
        w->glDrawGeometry ();
927
 
 
928
 
        glColor4usv (defaultColor);
929
 
        gs->setTexEnvMode (GL_REPLACE);
930
 
    }
931
 
    else
932
 
    {
933
 
        w->glDrawGeometry ();
934
 
    }
935
 
 
936
 
    texture->disable ();
937
 
 
938
 
    fa.disable ();
939
 
 
940
 
    return true;
941
 
}
942
 
 
 
969
    }
 
970
}
 
971
 
 
972
#ifndef USE_GLES
943
973
static void
944
 
enableFragmentOperationsAndDrawGeometry (GLScreen           *gs,
945
 
                                         GLWindow           *w,
946
 
                                         GLTexture          *texture,
947
 
                                         GLFragment::Attrib &attrib,
948
 
                                         GLTexture::Filter  filter,
949
 
                                         unsigned int       mask)
 
974
enableLegacyOBSAndRender (GLScreen                  *gs,
 
975
                          GLWindow                  *w,
 
976
                          GLTexture                 *texture,
 
977
                          const GLMatrix            &transform,
 
978
                          const GLWindowPaintAttrib &attrib,
 
979
                          GLTexture::Filter          filter,
 
980
                          unsigned int               mask)
950
981
{
951
 
    if (GL::canDoSaturated && attrib.getSaturation () != COLOR)
 
982
    // XXX: This codepath only works with !GL::vbo so that's the only case
 
983
    //      where you'll find it's called. At least for now.
 
984
 
 
985
    if (GL::canDoSaturated && attrib.saturation != COLOR)
952
986
    {
953
987
        GLfloat constant[4];
954
988
 
955
 
        if (mask & PAINT_WINDOW_BLEND_MASK)
956
 
            glEnable (GL_BLEND);
957
 
 
958
989
        texture->enable (filter);
959
990
 
960
991
        glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
985
1016
        glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
986
1017
        glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
987
1018
 
988
 
        if (GL::canDoSlightlySaturated && attrib.getSaturation () > 0)
 
1019
        if (GL::canDoSlightlySaturated && attrib.saturation > 0)
989
1020
        {
990
1021
            glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
991
1022
            glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PREVIOUS);
1016
1047
            glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PREVIOUS);
1017
1048
            glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
1018
1049
 
1019
 
            constant[3] = attrib.getSaturation () / 65535.0f;
 
1050
            constant[3] = attrib.saturation / 65535.0f;
1020
1051
 
1021
1052
            glTexEnvfv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, constant);
1022
1053
 
1023
 
            if (attrib.getOpacity () < OPAQUE ||
1024
 
                attrib.getBrightness () != BRIGHT)
 
1054
            if (attrib.opacity < OPAQUE ||
 
1055
                attrib.brightness != BRIGHT)
1025
1056
            {
1026
1057
                GL::activeTexture (GL_TEXTURE3_ARB);
1027
1058
 
1028
1059
                texture->enable (filter);
1029
1060
 
1030
 
                constant[3] = attrib.getOpacity () / 65535.0f;
 
1061
                constant[3] = attrib.opacity / 65535.0f;
1031
1062
                constant[0] = constant[1] = constant[2] = constant[3] *
1032
 
                    attrib.getBrightness () / 65535.0f;
 
1063
                    attrib.brightness / 65535.0f;
1033
1064
 
1034
1065
                glTexEnvfv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, constant);
1035
1066
 
1047
1078
                glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
1048
1079
                glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
1049
1080
 
1050
 
                w->glDrawGeometry ();
 
1081
                w->vertexBuffer ()->render (transform, attrib);
1051
1082
 
1052
1083
                texture->disable ();
1053
1084
 
1057
1088
            }
1058
1089
            else
1059
1090
            {
1060
 
                w->glDrawGeometry ();
 
1091
                w->vertexBuffer ()->render (transform, attrib);
1061
1092
            }
1062
1093
 
1063
1094
            texture->disable ();
1074
1105
            glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
1075
1106
            glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
1076
1107
 
1077
 
            constant[3] = attrib.getOpacity () / 65535.0f;
 
1108
            constant[3] = attrib.opacity / 65535.0f;
1078
1109
            constant[0] = constant[1] = constant[2] = constant[3] *
1079
 
                          attrib.getBrightness ()/ 65535.0f;
 
1110
                          attrib.brightness / 65535.0f;
1080
1111
 
1081
1112
            constant[0] = 0.5f + 0.5f * RED_SATURATION_WEIGHT   * constant[0];
1082
1113
            constant[1] = 0.5f + 0.5f * GREEN_SATURATION_WEIGHT * constant[1];
1084
1115
 
1085
1116
            glTexEnvfv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, constant);
1086
1117
 
1087
 
            w->glDrawGeometry ();
 
1118
            w->vertexBuffer ()->render (transform, attrib);
1088
1119
        }
1089
1120
 
1090
1121
        texture->disable ();
1097
1128
 
1098
1129
        glColor4usv (defaultColor);
1099
1130
        gs->setTexEnvMode (GL_REPLACE);
1100
 
 
1101
 
        if (mask & PAINT_WINDOW_BLEND_MASK)
1102
 
            glDisable (GL_BLEND);
1103
1131
    }
1104
1132
    else
1105
1133
    {
1107
1135
 
1108
1136
        if (mask & PAINT_WINDOW_BLEND_MASK)
1109
1137
        {
1110
 
            glEnable (GL_BLEND);
1111
 
            if (attrib.getOpacity ()!= OPAQUE ||
1112
 
                attrib.getBrightness () != BRIGHT)
 
1138
            if (attrib.opacity != OPAQUE ||
 
1139
                attrib.brightness != BRIGHT)
1113
1140
            {
1114
1141
                GLushort color;
1115
1142
 
1116
 
                color = (attrib.getOpacity () * attrib.getBrightness ()) >> 16;
 
1143
                color = (attrib.opacity * attrib.brightness) >> 16;
1117
1144
 
1118
1145
                gs->setTexEnvMode (GL_MODULATE);
1119
 
                glColor4us (color, color, color, attrib.getOpacity ());
 
1146
                glColor4us (color, color, color, attrib.opacity);
1120
1147
 
1121
 
                w->glDrawGeometry ();
 
1148
                w->vertexBuffer ()->render (transform, attrib);
1122
1149
 
1123
1150
                glColor4usv (defaultColor);
1124
1151
                gs->setTexEnvMode (GL_REPLACE);
1125
1152
            }
1126
1153
            else
1127
1154
            {
1128
 
                w->glDrawGeometry ();
 
1155
                w->vertexBuffer ()->render (transform, attrib);
1129
1156
            }
1130
 
 
1131
 
            glDisable (GL_BLEND);
1132
1157
        }
1133
 
        else if (attrib.getBrightness () != BRIGHT)
 
1158
        else if (attrib.brightness != BRIGHT)
1134
1159
        {
1135
1160
            gs->setTexEnvMode (GL_MODULATE);
1136
 
            glColor4us (attrib.getBrightness (), attrib.getBrightness (),
1137
 
                        attrib.getBrightness (), BRIGHT);
 
1161
            glColor4us (attrib.brightness, attrib.brightness,
 
1162
                        attrib.brightness, BRIGHT);
1138
1163
 
1139
 
            w->glDrawGeometry ();
 
1164
            w->vertexBuffer ()->render (transform, attrib);
1140
1165
 
1141
1166
            glColor4usv (defaultColor);
1142
1167
            gs->setTexEnvMode (GL_REPLACE);
1143
1168
        }
1144
1169
        else
1145
1170
        {
1146
 
            w->glDrawGeometry ();
 
1171
            w->vertexBuffer ()->render (transform, attrib);
1147
1172
        }
1148
1173
 
1149
1174
        texture->disable ();
1150
1175
    }
1151
1176
}
 
1177
#endif
1152
1178
 
1153
1179
void
1154
1180
GLWindow::glDrawTexture (GLTexture          *texture,
1155
 
                         GLFragment::Attrib &attrib,
 
1181
                         const GLMatrix            &transform,
 
1182
                         const GLWindowPaintAttrib &attrib,
1156
1183
                         unsigned int       mask)
1157
1184
{
1158
 
    WRAPABLE_HND_FUNCTN (glDrawTexture, texture, attrib, mask)
 
1185
    WRAPABLE_HND_FUNCTN (glDrawTexture, texture, transform, attrib, mask)
1159
1186
 
1160
1187
    GLTexture::Filter filter;
1161
1188
 
 
1189
    if (mask & PAINT_WINDOW_BLEND_MASK)
 
1190
        glEnable (GL_BLEND);
 
1191
 
1162
1192
    if (mask & (PAINT_WINDOW_TRANSFORMED_MASK |
1163
1193
                PAINT_WINDOW_ON_TRANSFORMED_SCREEN_MASK))
1164
1194
        filter = priv->gScreen->filter (SCREEN_TRANS_FILTER);
1165
1195
    else
1166
1196
        filter = priv->gScreen->filter (NOTHING_TRANS_FILTER);
1167
1197
 
1168
 
    if ((!attrib.hasFunctions () && (!priv->gScreen->lighting () ||
1169
 
         attrib.getSaturation () == COLOR || attrib.getSaturation () == 0)) ||
1170
 
        !enableFragmentProgramAndDrawGeometry (priv->gScreen, this, texture,
1171
 
                                               attrib, filter, mask))
1172
 
    {
1173
 
        enableFragmentOperationsAndDrawGeometry (priv->gScreen, this, texture,
 
1198
    glActiveTexture(GL_TEXTURE0);
 
1199
    texture->enable (filter);
 
1200
 
 
1201
    #ifdef USE_GLES
 
1202
    priv->vertexBuffer->render (transform, attrib);
 
1203
    #else
 
1204
 
 
1205
    if (!GLVertexBuffer::enabled ())
 
1206
        enableLegacyOBSAndRender (priv->gScreen, this, texture, transform,
1174
1207
                                                 attrib, filter, mask);
1175
 
    }
 
1208
    else
 
1209
        priv->vertexBuffer->render (transform, attrib);
 
1210
    #endif
 
1211
 
 
1212
    priv->shaders.clear ();
 
1213
    texture->disable ();
 
1214
 
 
1215
    if (mask & PAINT_WINDOW_BLEND_MASK)
 
1216
        glDisable (GL_BLEND);
1176
1217
}
1177
1218
 
1178
1219
bool
1179
1220
GLWindow::glDraw (const GLMatrix     &transform,
1180
 
                  GLFragment::Attrib &fragment,
 
1221
                  const GLWindowPaintAttrib &attrib,
1181
1222
                  const CompRegion   &region,
1182
1223
                  unsigned int       mask)
1183
1224
{
1184
1225
    WRAPABLE_HND_FUNCTN_RETURN (bool, glDraw, transform,
1185
 
                              fragment, region, mask)
 
1226
                              attrib, region, mask)
1186
1227
 
1187
1228
    const CompRegion &reg = (mask & PAINT_WINDOW_TRANSFORMED_MASK) ?
1188
1229
                            infiniteRegion : region;
1216
1257
    if (priv->updateState & PrivateGLWindow::UpdateRegion)
1217
1258
        priv->updateWindowRegions ();
1218
1259
 
1219
 
    for (unsigned int i = 0; i < textures ().size (); i++)
 
1260
    for (unsigned int i = 0; i < priv->textures.size (); i++)
1220
1261
    {
1221
1262
        ml[0] = priv->matrices[i];
1222
 
        priv->geometry.reset ();
 
1263
        priv->vertexBuffer->begin ();
1223
1264
        glAddGeometry (ml, priv->regions[i], reg);
1224
 
        if (priv->geometry.vCount)
1225
 
            glDrawTexture (textures ()[i], fragment, mask);
 
1265
        if (priv->vertexBuffer->end ())
 
1266
            glDrawTexture (priv->textures[i], transform, attrib, mask);
1226
1267
    }
1227
1268
 
1228
1269
    return true;
1236
1277
{
1237
1278
    WRAPABLE_HND_FUNCTN_RETURN (bool, glPaint, attrib, transform, region, mask)
1238
1279
 
1239
 
    GLFragment::Attrib fragment (attrib);
1240
1280
    bool               status;
1241
1281
 
1242
1282
    priv->lastPaint = attrib;
1266
1306
    if (mask & PAINT_WINDOW_NO_CORE_INSTANCE_MASK)
1267
1307
        return true;
1268
1308
 
1269
 
    if (mask & PAINT_WINDOW_TRANSFORMED_MASK ||
1270
 
        mask & PAINT_WINDOW_WITH_OFFSET_MASK)
1271
 
    {
1272
 
        glPushMatrix ();
1273
 
        glLoadMatrixf (transform.getMatrix ());
1274
 
    }
1275
 
 
1276
 
    status = glDraw (transform, fragment, region, mask);
1277
 
 
1278
 
    if (mask & PAINT_WINDOW_TRANSFORMED_MASK ||
1279
 
        mask & PAINT_WINDOW_WITH_OFFSET_MASK)
1280
 
        glPopMatrix ();
 
1309
    status = glDraw (transform, attrib, region, mask);
1281
1310
 
1282
1311
    return status;
1283
1312
}