~ubuntu-branches/ubuntu/precise/tetzle/precise

« back to all changes in this revision

Viewing changes to src/graphics_layer.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Bart Martens
  • Date: 2011-06-02 02:51:09 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20110602025109-6jmxy9wekpwlrkw6
Tags: 2.0.0-1
* Synced with https://launchpad.net/~gottcode/+archive/gcppa/
* debian/control: Fixed "dpkg-source: warning: unknown information field
  'Suggests' in input data in general section of control info file".

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***********************************************************************
 
2
 *
 
3
 * Copyright (C) 2011 Graeme Gott <graeme@gottcode.org>
 
4
 *
 
5
 * This program is free software: you can redistribute it and/or modify
 
6
 * it under the terms of the GNU General Public License as published by
 
7
 * the Free Software Foundation, either version 3 of the License, or
 
8
 * (at your option) any later version.
 
9
 *
 
10
 * This program is distributed in the hope that it will be useful,
 
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 * GNU General Public License for more details.
 
14
 *
 
15
 * You should have received a copy of the GNU General Public License
 
16
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
17
 *
 
18
 ***********************************************************************/
 
19
 
 
20
#include "graphics_layer.h"
 
21
 
 
22
#include "appearance_dialog.h"
 
23
 
 
24
#include <QFile>
 
25
#include <QGLShaderProgram>
 
26
#include <QSettings>
 
27
 
 
28
//-----------------------------------------------------------------------------
 
29
 
 
30
GraphicsLayer* graphics_layer = 0;
 
31
 
 
32
//-----------------------------------------------------------------------------
 
33
 
 
34
#ifndef APIENTRY
 
35
#define APIENTRY
 
36
#endif
 
37
#ifndef APIENTRYP
 
38
#define APIENTRYP APIENTRY *
 
39
#endif
 
40
 
 
41
// Multi-texture extension
 
42
#ifndef GL_VERSION_1_3
 
43
#define GL_TEXTURE0 0x84C0
 
44
#define GL_TEXTURE1 0x84C1
 
45
#endif
 
46
 
 
47
#ifndef GL_VERSION_1_3_DEPRECATED
 
48
#define GL_COMBINE     0x8570
 
49
#define GL_COMBINE_RGB 0x8571
 
50
#define GL_ADD_SIGNED  0x8574
 
51
#endif
 
52
 
 
53
typedef void (APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture);
 
54
static PFNGLACTIVETEXTUREPROC activeTexture = 0;
 
55
typedef void (APIENTRYP PFNGLCLIENTACTIVETEXTUREPROC) (GLenum texture);
 
56
static PFNGLCLIENTACTIVETEXTUREPROC clientActiveTexture = 0;
 
57
 
 
58
// Vertex buffer object extension
 
59
#ifndef GL_VERSION_1_5
 
60
#define GL_ARRAY_BUFFER 0x8892
 
61
#define GL_DYNAMIC_DRAW 0x88E8
 
62
typedef ptrdiff_t GLintptr;
 
63
typedef ptrdiff_t GLsizeiptr;
 
64
#endif
 
65
 
 
66
static GLuint vbo_id = 0;
 
67
 
 
68
typedef void (APIENTRYP PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer);
 
69
static PFNGLBINDBUFFERPROC bindBuffer = 0;
 
70
typedef void (APIENTRYP PFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage);
 
71
static PFNGLBUFFERDATAPROC bufferData = 0;
 
72
typedef void (APIENTRYP PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data);
 
73
static PFNGLBUFFERSUBDATAPROC bufferSubData = 0;
 
74
typedef void (APIENTRYP PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint *buffers);
 
75
static PFNGLDELETEBUFFERSPROC deleteBuffers = 0;
 
76
typedef void (APIENTRYP PFNGLGENBUFFERSPROC) (GLsizei n, GLuint *buffers);
 
77
static PFNGLGENBUFFERSPROC genBuffers = 0;
 
78
 
 
79
// Vertex attribute object extension
 
80
static GLuint vao_id = 0;
 
81
 
 
82
typedef void (APIENTRYP PFNGLBINDVERTEXARRAYPROC) (GLuint array);
 
83
static PFNGLBINDVERTEXARRAYPROC bindVertexArray = 0;
 
84
typedef void (APIENTRYP PFNGLDELETEVERTEXARRAYSPROC) (GLsizei n, const GLuint *arrays);
 
85
static PFNGLDELETEVERTEXARRAYSPROC deleteVertexArrays = 0;
 
86
typedef void (APIENTRYP PFNGLGENVERTEXARRAYSPROC) (GLsizei n, GLuint *arrays);
 
87
static PFNGLGENVERTEXARRAYSPROC genVertexArrays = 0;
 
88
 
 
89
namespace
 
90
{
 
91
        enum StateFlags
 
92
        {
 
93
                MultiTextureFlag = 0x01,
 
94
                VertexBufferObjectFlag = 0x02,
 
95
                FragmentShadersFlag = 0x04,
 
96
                VertexArrayObjectFlag = 0x08
 
97
        };
 
98
 
 
99
        enum Versions
 
100
        {
 
101
                Version11 = 0,
 
102
                Version13 = MultiTextureFlag,
 
103
                Version15 = MultiTextureFlag | VertexBufferObjectFlag,
 
104
                Version21 = FragmentShadersFlag | MultiTextureFlag | VertexBufferObjectFlag,
 
105
                Version30 = VertexArrayObjectFlag | FragmentShadersFlag | MultiTextureFlag | VertexBufferObjectFlag
 
106
        };
 
107
}
 
108
 
 
109
static void* getProcAddress(const QString& name)
 
110
{
 
111
        void* result;
 
112
        QString names[] = { name, name + "ARB", name + "EXT" };
 
113
        for (int i = 0; i < 3; ++i) {
 
114
                result = QGLContext::currentContext()->getProcAddress(names[i]);
 
115
                if (result) {
 
116
                        break;
 
117
                }
 
118
        }
 
119
        return result;
 
120
}
 
121
 
 
122
static inline void convertMatrix(const qreal* in, GLfloat* out)
 
123
{
 
124
        for (int i = 0; i < 16; ++i) {
 
125
                out[i] = static_cast<GLfloat>(in[i]);
 
126
        }
 
127
}
 
128
 
 
129
//-----------------------------------------------------------------------------
 
130
 
 
131
void GraphicsLayer::init()
 
132
{
 
133
        unsigned int state = 0;
 
134
        int detected = 11;
 
135
 
 
136
        // Try to load multi-texture functions
 
137
        activeTexture = (PFNGLACTIVETEXTUREPROC) getProcAddress("glActiveTexture");
 
138
        clientActiveTexture = (PFNGLCLIENTACTIVETEXTUREPROC) getProcAddress("glClientActiveTexture");
 
139
        if ((activeTexture != 0) && (clientActiveTexture != 0)) {
 
140
                state |= MultiTextureFlag;
 
141
                detected = 13;
 
142
        }
 
143
 
 
144
        // Try to load vertex buffer object functions
 
145
        bindBuffer = (PFNGLBINDBUFFERPROC) getProcAddress("glBindBuffer");
 
146
        bufferData = (PFNGLBUFFERDATAPROC) getProcAddress("glBufferData");
 
147
        bufferSubData = (PFNGLBUFFERSUBDATAPROC) getProcAddress("glBufferSubData");
 
148
        deleteBuffers = (PFNGLDELETEBUFFERSPROC) getProcAddress("glDeleteBuffers");
 
149
        genBuffers = (PFNGLGENBUFFERSPROC) getProcAddress("glGenBuffers");
 
150
        if ((bindBuffer != 0) && (bufferData != 0) && (bufferSubData != 0) && (deleteBuffers != 0) && (genBuffers != 0)) {
 
151
                state |= VertexBufferObjectFlag;
 
152
                if (state == Version15) {
 
153
                        detected = 15;
 
154
                }
 
155
        }
 
156
 
 
157
        // Check for minimum supported programmable pipeline
 
158
        if (QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_2_1) {
 
159
                state |= FragmentShadersFlag;
 
160
                if (activeTexture != 0) {
 
161
                        state |= MultiTextureFlag;
 
162
                }
 
163
        }
 
164
 
 
165
        // Try to load vertex array object functions
 
166
        if (state == Version21) {
 
167
                detected = 21;
 
168
                bindVertexArray = (PFNGLBINDVERTEXARRAYPROC) getProcAddress("glBindVertexArray");
 
169
                deleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC) getProcAddress("glDeleteVertexArrays");
 
170
                genVertexArrays = (PFNGLGENVERTEXARRAYSPROC) getProcAddress("glGenVertexArrays");
 
171
                if ((bindVertexArray != 0) && (deleteVertexArrays != 0) && (genVertexArrays != 0)) {
 
172
                        state |= VertexArrayObjectFlag;
 
173
                        detected = 30;
 
174
                }
 
175
        }
 
176
 
 
177
        // Check for a requested state
 
178
        unsigned int new_state = 0;
 
179
        int requested = QSettings().value("GraphicsLayer", detected).toInt();
 
180
        if (requested == 30) {
 
181
                new_state = Version30;
 
182
        } else if (requested == 21) {
 
183
                new_state = Version21;
 
184
        } else if (requested == 15) {
 
185
                new_state = Version15;
 
186
        } else if (requested == 13) {
 
187
                new_state = Version13;
 
188
        } else if (requested == 11) {
 
189
                new_state = Version11;
 
190
        } else {
 
191
                new_state = state;
 
192
                qWarning("Requested GraphicsLayer%d is invalid; using detected GraphicsLayer%d instead.", requested, detected);
 
193
        }
 
194
        if (state >= new_state) {
 
195
                state = new_state;
 
196
        } else {
 
197
                qWarning("Unable to use requested GraphicsLayer%d; using detected GraphicsLayer%d instead.", requested, detected);
 
198
        }
 
199
 
 
200
        // Create graphics layer instance
 
201
        if (state == Version30) {
 
202
                genVertexArrays(1, &vao_id);
 
203
                bindVertexArray(vao_id);
 
204
                graphics_layer = new GraphicsLayer21;
 
205
        } else if (state == Version21) {
 
206
                graphics_layer = new GraphicsLayer21;
 
207
        } else if (state == Version15) {
 
208
                graphics_layer = new GraphicsLayer15;
 
209
        } else if (state == Version13) {
 
210
                graphics_layer = new GraphicsLayer13;
 
211
        } else {
 
212
                graphics_layer = new GraphicsLayer11;
 
213
        }
 
214
        graphics_layer->setTextureUnits(1);
 
215
}
 
216
 
 
217
//-----------------------------------------------------------------------------
 
218
 
 
219
GraphicsLayer::GraphicsLayer()
 
220
:       m_changed(true)
 
221
{
 
222
        glDisable(GL_BLEND);
 
223
 
 
224
        // Enable OpenGL features
 
225
        glEnable(GL_CULL_FACE);
 
226
        glEnable(GL_DEPTH_TEST);
 
227
 
 
228
        // Set OpenGL parameters
 
229
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 
230
        glDepthFunc(GL_LEQUAL);
 
231
        glFrontFace(GL_CCW);
 
232
 
 
233
        // Start with a 1MB vertex buffer
 
234
        m_data.resize(0x100000 / sizeof(Vertex));
 
235
        VertexArray free_region;
 
236
        free_region.end = m_data.count();
 
237
        m_free_regions.append(free_region);
 
238
}
 
239
 
 
240
//-----------------------------------------------------------------------------
 
241
 
 
242
GraphicsLayer::~GraphicsLayer()
 
243
{
 
244
        // Delete VBO
 
245
        if (vbo_id != 0) {
 
246
                bindBuffer(GL_ARRAY_BUFFER, 0);
 
247
                deleteBuffers(1, &vbo_id);
 
248
                vbo_id = 0;
 
249
        }
 
250
 
 
251
        // Delete VAO
 
252
        if (vao_id != 0) {
 
253
                bindVertexArray(0);
 
254
                deleteVertexArrays(1, &vao_id);
 
255
                vao_id = 0;
 
256
        }
 
257
}
 
258
 
 
259
//-----------------------------------------------------------------------------
 
260
 
 
261
void GraphicsLayer::updateArray(VertexArray& array, const QVector<Vertex>& data)
 
262
{
 
263
        int length = data.count();
 
264
        if (array.length() != length) {
 
265
                removeArray(array);
 
266
                array.start = -1;
 
267
                for (int i = 0; i < m_free_regions.count(); ++i) {
 
268
                        VertexArray& free_region = m_free_regions[i];
 
269
                        if (free_region.length() == length) {
 
270
                                array.start = free_region.start;
 
271
                                array.end = array.start + length;
 
272
                                m_free_regions.removeAt(i);
 
273
                                break;
 
274
                        } else if (free_region.length() > length) {
 
275
                                array.start = free_region.start;
 
276
                                array.end = array.start + length;
 
277
                                free_region.start += length;
 
278
                                break;
 
279
                        }
 
280
                }
 
281
        }
 
282
 
 
283
        if (array.start != -1) {
 
284
                qCopy(data.begin(), data.end(), m_data.begin() + array.start);
 
285
                if (!m_changed) {
 
286
                        m_changed_regions.append(array);
 
287
                }
 
288
        } else {
 
289
                array.start = m_data.count();
 
290
                array.end = array.start + length;
 
291
                m_data += data;
 
292
                m_changed = true;
 
293
                m_changed_regions.clear();
 
294
        }
 
295
}
 
296
 
 
297
//-----------------------------------------------------------------------------
 
298
 
 
299
void GraphicsLayer::removeArray(VertexArray& array)
 
300
{
 
301
        if (array.end == 0) {
 
302
                return;
 
303
        }
 
304
 
 
305
        bool merged = false;
 
306
        int count = m_free_regions.count();
 
307
        int pos = count;
 
308
        for (int i = 0; i < count; ++i) {
 
309
                VertexArray& free_region = m_free_regions[i];
 
310
                if (free_region.end == array.start) {
 
311
                        merged = true;
 
312
                        free_region.end = array.end;
 
313
                        if ((i+1) < count && free_region.end == m_free_regions[i+1].start) {
 
314
                                free_region.end = m_free_regions[i+1].end;
 
315
                                m_free_regions.removeAt(i+1);
 
316
                        }
 
317
                        break;
 
318
                } else if (free_region.start == array.end) {
 
319
                        merged = true;
 
320
                        free_region.start = array.start;
 
321
                        if (i > 0 && free_region.start == m_free_regions[i-1].end) {
 
322
                                free_region.start = m_free_regions[i-1].start;
 
323
                                m_free_regions.removeAt(i-1);
 
324
                        }
 
325
                        break;
 
326
                } else if (free_region.start > array.start) {
 
327
                        pos = i;
 
328
                        break;
 
329
                }
 
330
        }
 
331
        if (!merged) {
 
332
                m_free_regions.insert(pos, array);
 
333
        }
 
334
 
 
335
        array.start = array.end = 0;
 
336
}
 
337
 
 
338
//-----------------------------------------------------------------------------
 
339
 
 
340
void GraphicsLayer::clearChanged()
 
341
{
 
342
        m_changed_regions.clear();
 
343
        m_changed = false;
 
344
}
 
345
 
 
346
//-----------------------------------------------------------------------------
 
347
 
 
348
void GraphicsLayer::uploadChanged()
 
349
{
 
350
        if (!m_changed_regions.isEmpty()) {
 
351
                foreach (const VertexArray& region, m_changed_regions) {
 
352
                        bufferSubData(GL_ARRAY_BUFFER, region.start * sizeof(Vertex), region.length() * sizeof(Vertex), m_data.constBegin() + region.start);
 
353
                }
 
354
                m_changed_regions.clear();
 
355
        } else if (m_changed) {
 
356
                GLsizeiptr size = m_data.count() * sizeof(Vertex);
 
357
                bufferData(GL_ARRAY_BUFFER, size, 0, GL_DYNAMIC_DRAW);
 
358
                bufferSubData(GL_ARRAY_BUFFER, 0, size, m_data.constData());
 
359
                m_changed = false;
 
360
        }
 
361
}
 
362
 
 
363
//-----------------------------------------------------------------------------
 
364
 
 
365
GraphicsLayer21::GraphicsLayer21()
 
366
:       m_program(0)
 
367
{
 
368
        AppearanceDialog::setBevelsEnabled(true);
 
369
 
 
370
        // Create VBO
 
371
        genBuffers(1, &vbo_id);
 
372
        bindBuffer(GL_ARRAY_BUFFER, vbo_id);
 
373
 
 
374
        // Load shaders
 
375
        QGLShaderProgram* program = loadProgram(0);
 
376
        program->setAttributeBuffer(Position, GL_FLOAT, 0, 3, sizeof(Vertex));
 
377
        program->enableAttributeArray(Position);
 
378
 
 
379
        program = loadProgram(1);
 
380
        program->setAttributeBuffer(TexCoord0, GL_FLOAT, sizeof(GLfloat) * 3, 2, sizeof(Vertex));
 
381
        program->setAttributeBuffer(Position, GL_FLOAT, 0, 3, sizeof(Vertex));
 
382
        program->enableAttributeArray(Position);
 
383
        program->setUniformValue("texture0", GLuint(0));
 
384
 
 
385
        program = loadProgram(2);
 
386
        program->setAttributeBuffer(TexCoord1, GL_FLOAT, sizeof(GLfloat) * 5, 2, sizeof(Vertex));
 
387
        program->setAttributeBuffer(TexCoord0, GL_FLOAT, sizeof(GLfloat) * 3, 2, sizeof(Vertex));
 
388
        program->setAttributeBuffer(Position, GL_FLOAT, 0, 3, sizeof(Vertex));
 
389
        program->enableAttributeArray(Position);
 
390
        program->setUniformValue("texture0", GLuint(0));
 
391
        program->setUniformValue("texture1", GLuint(1));
 
392
}
 
393
 
 
394
//-----------------------------------------------------------------------------
 
395
 
 
396
GraphicsLayer21::~GraphicsLayer21()
 
397
{
 
398
        // Unload shaders
 
399
        for (int i = 0; i < 3; ++i) {
 
400
                delete m_programs[i];
 
401
                m_programs[i] = 0;
 
402
        }
 
403
        m_program = 0;
 
404
}
 
405
 
 
406
//-----------------------------------------------------------------------------
 
407
 
 
408
void GraphicsLayer21::bindTexture(unsigned int unit, GLuint texture)
 
409
{
 
410
        activeTexture(GL_TEXTURE0 + unit);
 
411
        glBindTexture(GL_TEXTURE_2D, texture);
 
412
        activeTexture(GL_TEXTURE0);
 
413
}
 
414
 
 
415
//-----------------------------------------------------------------------------
 
416
 
 
417
void GraphicsLayer21::draw(const VertexArray& array, GLenum mode)
 
418
{
 
419
        glDrawArrays(mode, array.start, array.length());
 
420
}
 
421
 
 
422
//-----------------------------------------------------------------------------
 
423
 
 
424
void GraphicsLayer21::setBlended(bool enabled)
 
425
{
 
426
        if (enabled) {
 
427
                glEnable(GL_BLEND);
 
428
        } else {
 
429
                glDisable(GL_BLEND);
 
430
        }
 
431
}
 
432
 
 
433
//-----------------------------------------------------------------------------
 
434
 
 
435
void GraphicsLayer21::setColor(const QColor& color)
 
436
{
 
437
        m_program->setUniformValue(m_color_location, color);
 
438
}
 
439
 
 
440
//-----------------------------------------------------------------------------
 
441
 
 
442
void GraphicsLayer21::setModelview(const QMatrix4x4& matrix)
 
443
{
 
444
        m_modelview = matrix;
 
445
        convertMatrix((m_projection * m_modelview).constData(), m_matrix[0]);
 
446
        m_program->setUniformValue(m_matrix_location, m_matrix);
 
447
}
 
448
 
 
449
//-----------------------------------------------------------------------------
 
450
 
 
451
void GraphicsLayer21::setProjection(const QMatrix4x4& matrix)
 
452
{
 
453
        m_projection = matrix;
 
454
        convertMatrix((m_projection * m_modelview).constData(), m_matrix[0]);
 
455
        m_program->setUniformValue(m_matrix_location, m_matrix);
 
456
}
 
457
 
 
458
//-----------------------------------------------------------------------------
 
459
 
 
460
void GraphicsLayer21::setTextureUnits(unsigned int units)
 
461
{
 
462
        Q_ASSERT(units < 3);
 
463
        QGLShaderProgram* program = m_programs[units];
 
464
        if (m_program == program) {
 
465
                return;
 
466
        }
 
467
 
 
468
        m_program = program;
 
469
        m_program->bind();
 
470
 
 
471
        m_color_location = m_program->uniformLocation("color");
 
472
        m_matrix_location = m_program->uniformLocation("matrix");
 
473
        m_program->setUniformValue(m_matrix_location, m_matrix);
 
474
 
 
475
        if (units > 1) {
 
476
                m_program->enableAttributeArray(TexCoord1);
 
477
                m_program->enableAttributeArray(TexCoord0);
 
478
        } else if (units > 0) {
 
479
                m_program->disableAttributeArray(TexCoord1);
 
480
                m_program->enableAttributeArray(TexCoord0);
 
481
        } else {
 
482
                m_program->disableAttributeArray(TexCoord1);
 
483
                m_program->disableAttributeArray(TexCoord0);
 
484
        }
 
485
}
 
486
 
 
487
//-----------------------------------------------------------------------------
 
488
 
 
489
void GraphicsLayer21::uploadData()
 
490
{
 
491
        uploadChanged();
 
492
}
 
493
 
 
494
//-----------------------------------------------------------------------------
 
495
 
 
496
QGLShaderProgram* GraphicsLayer21::loadProgram(unsigned int index)
 
497
{
 
498
        // Load vertex shader code
 
499
        QString vertex;
 
500
        QFile file(QString(":/shaders/textures%1.vert").arg(index));
 
501
        if (file.open(QFile::ReadOnly)) {
 
502
                vertex = file.readAll();
 
503
                file.close();
 
504
        }
 
505
 
 
506
        // Load fragment shader code
 
507
        QString frag;
 
508
        file.setFileName(QString(":/shaders/textures%1.frag").arg(index));
 
509
        if (file.open(QFile::ReadOnly)) {
 
510
                frag = file.readAll();
 
511
                file.close();
 
512
        }
 
513
 
 
514
        // Update GLSL version
 
515
        QString version;
 
516
        version = (QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_3_0) ? "130" : version;
 
517
#if QT_VERSION >= 0x040700
 
518
        version = (QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_3_1) ? "140" : version;
 
519
        version = (QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_3_2) ? "150" : version;
 
520
        version = (QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_3_3) ? "330" : version;
 
521
        version = (QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_4_0) ? "400" : version;
 
522
#endif
 
523
        if (!version.isEmpty()) {
 
524
                vertex.replace("#version 120\n", "#version " + version + "\n");
 
525
                vertex.replace("attribute ", "in ");
 
526
                vertex.replace("varying ", "out ");
 
527
 
 
528
                frag.replace("#version 120\n", "#version " + version + "\n\nout vec4 out_color;\n");
 
529
                frag.replace("gl_FragColor", "out_color");
 
530
                frag.replace("varying ", "in ");
 
531
        }
 
532
 
 
533
        // Create program
 
534
        m_programs[index] = new QGLShaderProgram;
 
535
        m_programs[index]->addShaderFromSourceCode(QGLShader::Vertex, vertex);
 
536
        m_programs[index]->addShaderFromSourceCode(QGLShader::Fragment, frag);
 
537
 
 
538
        // Set attribute locations
 
539
        m_programs[index]->bindAttributeLocation("position", Position);
 
540
        if (index > 0) {
 
541
                m_programs[index]->bindAttributeLocation("texcoord0", TexCoord0);
 
542
        }
 
543
        if (index > 1) {
 
544
                m_programs[index]->bindAttributeLocation("texcoord1", TexCoord1);
 
545
        }
 
546
 
 
547
        // Link and bind program
 
548
        m_programs[index]->link();
 
549
        m_programs[index]->bind();
 
550
        return m_programs[index];
 
551
}
 
552
 
 
553
//-----------------------------------------------------------------------------
 
554
 
 
555
GraphicsLayer11::GraphicsLayer11()
 
556
{
 
557
        AppearanceDialog::setBevelsEnabled(false);
 
558
 
 
559
        // Disable unused OpenGL features
 
560
        glDisable(GL_LIGHTING);
 
561
 
 
562
        // Enable OpenGL features
 
563
        glEnableClientState(GL_VERTEX_ARRAY);
 
564
 
 
565
        // Set OpenGL parameters
 
566
        setColor(Qt::white);
 
567
}
 
568
 
 
569
//-----------------------------------------------------------------------------
 
570
 
 
571
void GraphicsLayer11::bindTexture(unsigned int unit, GLuint texture)
 
572
{
 
573
        Q_UNUSED(unit);
 
574
        glBindTexture(GL_TEXTURE_2D, texture);
 
575
}
 
576
 
 
577
//-----------------------------------------------------------------------------
 
578
 
 
579
void GraphicsLayer11::draw(const VertexArray& array, GLenum mode)
 
580
{
 
581
        glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), &at(array.start).s);
 
582
        glVertexPointer(3, GL_FLOAT, sizeof(Vertex), &at(array.start).x);
 
583
        glDrawArrays(mode, 0, array.length());
 
584
}
 
585
 
 
586
//-----------------------------------------------------------------------------
 
587
 
 
588
void GraphicsLayer11::setBlended(bool enabled)
 
589
{
 
590
        if (enabled) {
 
591
                glEnable(GL_BLEND);
 
592
        } else {
 
593
                glDisable(GL_BLEND);
 
594
        }
 
595
}
 
596
 
 
597
//-----------------------------------------------------------------------------
 
598
 
 
599
void GraphicsLayer11::setColor(const QColor& color)
 
600
{
 
601
        glColor4f(color.redF(), color.greenF(), color.blueF(), color.alphaF());
 
602
}
 
603
 
 
604
//-----------------------------------------------------------------------------
 
605
 
 
606
void GraphicsLayer11::setModelview(const QMatrix4x4& matrix)
 
607
{
 
608
        GLfloat modelview[16];
 
609
        convertMatrix(matrix.constData(), modelview);
 
610
        glLoadMatrixf(modelview);
 
611
}
 
612
 
 
613
//-----------------------------------------------------------------------------
 
614
 
 
615
void GraphicsLayer11::setProjection(const QMatrix4x4& matrix)
 
616
{
 
617
        GLfloat projection[16];
 
618
        convertMatrix(matrix.constData(), projection);
 
619
        glMatrixMode(GL_PROJECTION);
 
620
        glLoadMatrixf(projection);
 
621
        glMatrixMode(GL_MODELVIEW);
 
622
}
 
623
 
 
624
//-----------------------------------------------------------------------------
 
625
 
 
626
void GraphicsLayer11::setTextureUnits(unsigned int units)
 
627
{
 
628
        if (units) {
 
629
                glEnable(GL_TEXTURE_2D);
 
630
                glEnableClientState(GL_TEXTURE_COORD_ARRAY);
 
631
        } else {
 
632
                glDisableClientState(GL_TEXTURE_COORD_ARRAY);
 
633
                glDisable(GL_TEXTURE_2D);
 
634
        }
 
635
}
 
636
 
 
637
//-----------------------------------------------------------------------------
 
638
 
 
639
void GraphicsLayer11::uploadData()
 
640
{
 
641
        clearChanged();
 
642
}
 
643
 
 
644
//-----------------------------------------------------------------------------
 
645
 
 
646
GraphicsLayer13::GraphicsLayer13()
 
647
{
 
648
        AppearanceDialog::setBevelsEnabled(true);
 
649
 
 
650
        // Set OpenGL parameters
 
651
        activeTexture(GL_TEXTURE1);
 
652
        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
 
653
        glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD_SIGNED);
 
654
        activeTexture(GL_TEXTURE0);
 
655
}
 
656
 
 
657
//-----------------------------------------------------------------------------
 
658
 
 
659
void GraphicsLayer13::bindTexture(unsigned int unit, GLuint texture)
 
660
{
 
661
        activeTexture(GL_TEXTURE0 + unit);
 
662
        glBindTexture(GL_TEXTURE_2D, texture);
 
663
        activeTexture(GL_TEXTURE0);
 
664
}
 
665
 
 
666
//-----------------------------------------------------------------------------
 
667
 
 
668
void GraphicsLayer13::draw(const VertexArray& array, GLenum mode)
 
669
{
 
670
        clientActiveTexture(GL_TEXTURE1);
 
671
        glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), &at(array.start).s2);
 
672
        clientActiveTexture(GL_TEXTURE0);
 
673
        glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), &at(array.start).s);
 
674
        glVertexPointer(3, GL_FLOAT, sizeof(Vertex), &at(array.start).x);
 
675
        glDrawArrays(mode, 0, array.length());
 
676
}
 
677
 
 
678
//-----------------------------------------------------------------------------
 
679
 
 
680
void GraphicsLayer13::setTextureUnits(unsigned int units)
 
681
{
 
682
        activeTexture(GL_TEXTURE1);
 
683
        clientActiveTexture(GL_TEXTURE1);
 
684
        if (units > 1) {
 
685
                glEnable(GL_TEXTURE_2D);
 
686
                glEnableClientState(GL_TEXTURE_COORD_ARRAY);
 
687
        } else {
 
688
                glDisableClientState(GL_TEXTURE_COORD_ARRAY);
 
689
                glDisable(GL_TEXTURE_2D);
 
690
        }
 
691
 
 
692
        activeTexture(GL_TEXTURE0);
 
693
        clientActiveTexture(GL_TEXTURE0);
 
694
        if (units > 0) {
 
695
                glEnable(GL_TEXTURE_2D);
 
696
                glEnableClientState(GL_TEXTURE_COORD_ARRAY);
 
697
        } else {
 
698
                glDisableClientState(GL_TEXTURE_COORD_ARRAY);
 
699
                glDisable(GL_TEXTURE_2D);
 
700
        }
 
701
}
 
702
 
 
703
//-----------------------------------------------------------------------------
 
704
 
 
705
GraphicsLayer15::GraphicsLayer15()
 
706
{
 
707
        // Create VBO
 
708
        genBuffers(1, &vbo_id);
 
709
        bindBuffer(GL_ARRAY_BUFFER, vbo_id);
 
710
}
 
711
 
 
712
//-----------------------------------------------------------------------------
 
713
 
 
714
void GraphicsLayer15::draw(const VertexArray& array, GLenum mode)
 
715
{
 
716
        glDrawArrays(mode, array.start, array.length());
 
717
}
 
718
 
 
719
//-----------------------------------------------------------------------------
 
720
 
 
721
void GraphicsLayer15::setTextureUnits(unsigned int units)
 
722
{
 
723
        activeTexture(GL_TEXTURE1);
 
724
        clientActiveTexture(GL_TEXTURE1);
 
725
        if (units > 1) {
 
726
                glEnable(GL_TEXTURE_2D);
 
727
                glEnableClientState(GL_TEXTURE_COORD_ARRAY);
 
728
                glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), reinterpret_cast<GLvoid*>(sizeof(GLfloat) * 5));
 
729
        } else {
 
730
                glDisableClientState(GL_TEXTURE_COORD_ARRAY);
 
731
                glDisable(GL_TEXTURE_2D);
 
732
        }
 
733
 
 
734
        activeTexture(GL_TEXTURE0);
 
735
        clientActiveTexture(GL_TEXTURE0);
 
736
        if (units > 0) {
 
737
                glEnable(GL_TEXTURE_2D);
 
738
                glEnableClientState(GL_TEXTURE_COORD_ARRAY);
 
739
                glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), reinterpret_cast<GLvoid*>(sizeof(GLfloat) * 3));
 
740
        } else {
 
741
                glDisableClientState(GL_TEXTURE_COORD_ARRAY);
 
742
                glDisable(GL_TEXTURE_2D);
 
743
        }
 
744
 
 
745
        glVertexPointer(3, GL_FLOAT, sizeof(Vertex), 0);
 
746
}
 
747
 
 
748
//-----------------------------------------------------------------------------
 
749
 
 
750
void GraphicsLayer15::uploadData()
 
751
{
 
752
        uploadChanged();
 
753
}
 
754
 
 
755
//-----------------------------------------------------------------------------