~thumper/nux/next-changes

« back to all changes in this revision

Viewing changes to NuxGraphics/OpenGLEngine.cpp

  • Committer: Neil Jagdish Patel
  • Date: 2010-09-01 21:15:42 UTC
  • Revision ID: neil.patel@canonical.com-20100901211542-cw2ce3ak28unouwb
Add NuxGraphics with licensing

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright 2010 Inalogic Inc.
 
3
 *
 
4
 * This program is free software: you can redistribute it and/or modify it 
 
5
 * under the terms of the GNU Lesser General Public License version 3, as
 
6
 * published by the  Free Software Foundation.
 
7
 *
 
8
 * This program is distributed in the hope that it will be useful, but 
 
9
 * WITHOUT ANY WARRANTY; without even the implied warranties of 
 
10
 * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR 
 
11
 * PURPOSE.  See the applicable version of the GNU Lesser General Public 
 
12
 * License for more details.
 
13
 * 
 
14
 * You should have received a copy of both the GNU Lesser General Public 
 
15
 * License version 3 along with this program.  If not, see 
 
16
 * <http://www.gnu.org/licenses/>
 
17
 *
 
18
 * Authored by: Jay Taoko <jay.taoko_AT_gmail_DOT_com>
 
19
 *
 
20
 */
 
21
 
 
22
 
 
23
#include "NuxCore/NKernel.h"
 
24
 
 
25
#include "NuxImage/Tga.h"
 
26
#include "NuxImage/ImageSurface.h"
 
27
#include "NuxMesh/NTextureArchiveManager.h"
 
28
 
 
29
#include "GLDeviceFactory.h"
 
30
#include "GLDeviceObjects.h"
 
31
#include "GLResourceManager.h"
 
32
 
 
33
#include "GLTextureResourceManager.h"
 
34
#include "GLVertexResourceManager.h"
 
35
 
 
36
#include "FontTexture.h"
 
37
#include "UIColorTheme.h"
 
38
 
 
39
#include "OpenGLEngine.h"
 
40
 
 
41
NAMESPACE_BEGIN_OGL
 
42
 
 
43
ROPConfig ROPConfig::Default;
 
44
ROPConfig::ROPConfig()
 
45
{
 
46
    Blend = false;
 
47
    SrcBlend = GL_SRC_ALPHA;
 
48
    DstBlend = GL_ONE_MINUS_SRC_ALPHA;
 
49
}
 
50
ROPConfig::~ROPConfig()
 
51
{
 
52
}
 
53
 
 
54
 
 
55
 
 
56
NFontPtr GFont;
 
57
NFontPtr GFontBold;
 
58
Color GTextColor = Color(0xFFE9E9E9);
 
59
 
 
60
GraphicsContext::GraphicsContext(GLWindowImpl& GlWindow)
 
61
:   m_FontRenderer(0)
 
62
,   m_GLWindow(GlWindow)
 
63
,   m_ScissorX(0)
 
64
,   m_ScissorY(0)
 
65
,   m_ScissorXOffset(0)
 
66
,   m_ScissorYOffset(0)
 
67
{
 
68
    GlWindow.m_GraphicsContext = this;
 
69
    ResetStats();
 
70
 
 
71
    //Initialize the matrices
 
72
    m_ProjectionMatrix.Identity();
 
73
    m_ModelViewMatrix.Identity();
 
74
 
 
75
    ResourceCache.InitializeResourceFactories();
 
76
 
 
77
    //     m_FilePath.AddSearchPath("./Data");
 
78
    //     m_FilePath.AddSearchPath("../Data");
 
79
    //     m_FilePath.AddSearchPath("../../Data");
 
80
    //     m_FilePath.AddSearchPath("../../../Data");
 
81
    m_FilePath.AddSearchPath("./Data/UITextures");
 
82
 
 
83
    NString font_file = INL_FIND_RESOURCE_LOCATION_NOFAIL(TEXT("Tahoma_size_8.txt"));
 
84
 
 
85
    if(!GFont)
 
86
    {
 
87
        //GFont.reset(new FontTexture(TEXT("Courier New_size_10.txt")));
 
88
        GFont.reset(new FontTexture(INL_FIND_RESOURCE_LOCATION_NOFAIL(TEXT("Tahoma_size_8.txt"))));
 
89
    }
 
90
 
 
91
    if(!GFontBold)
 
92
    {
 
93
        GFontBold.reset(new FontTexture(INL_FIND_RESOURCE_LOCATION_NOFAIL(TEXT("Tahoma_size_8_bold.txt"))));
 
94
    }
 
95
 
 
96
    m_CurrrentContext.x = 0;
 
97
    m_CurrrentContext.y = 0;
 
98
    m_CurrrentContext.width = m_GLWindow.GetWindowWidth();
 
99
    m_CurrrentContext.height = m_GLWindow.GetWindowHeight();
 
100
 
 
101
    SetViewport(0, 0, m_GLWindow.GetWindowWidth(), m_GLWindow.GetWindowHeight());
 
102
    SetScissor(0, 0, m_GLWindow.GetWindowWidth(), m_GLWindow.GetWindowHeight());
 
103
    SetScissorOffset(0, 0);
 
104
    EnableScissoring(true);
 
105
 
 
106
    //gUIColorTheme.Initialize();
 
107
 
 
108
    //InitShaders();
 
109
    //InitTextureBlendModeShader();
 
110
 
 
111
 
 
112
    InitAsmColorShader();
 
113
    InitAsmTextureShader();
 
114
    InitAsmColorModTexMaskAlpha();
 
115
    InitAsm4TextureAdd();
 
116
    InitAsmBlendModes();
 
117
 
 
118
//     InitSlColorShader();
 
119
//     InitSlTextureShader();
 
120
//     InitSl2TextureAdd();
 
121
//     InitSl4TextureAdd();
 
122
//     InitSlColorModTexMaskAlpha();
 
123
 
 
124
    InitOpenGLEngine();
 
125
}
 
126
 
 
127
GraphicsContext::~GraphicsContext()
 
128
{
 
129
    ResourceCache.Flush();
 
130
    INL_SAFE_DELETE(m_FontRenderer);
 
131
}
 
132
 
 
133
void GraphicsContext::InitOpenGLEngine()
 
134
{
 
135
    //LoadPainterImages();
 
136
    LoadFonts();
 
137
}
 
138
 
 
139
void GraphicsContext::SetContext(int x, int y, int width, int height)
 
140
{
 
141
    m_CurrrentContext.x = x;
 
142
    m_CurrrentContext.y = y;
 
143
 
 
144
    if(width <= 0 || height <= 0)
 
145
    {
 
146
        //nuxAssertMsg(0, TEXT("[GraphicsContext::SetContext] Incorrect context size.") );
 
147
        if(m_GLWindow.m_DeviceFactory->GetCurrentFrameBufferObject().IsValid())
 
148
        {
 
149
            m_CurrrentContext.width = m_GLWindow.m_DeviceFactory->GetCurrentFrameBufferObject()->GetWidth();
 
150
            m_CurrrentContext.height = m_GLWindow.m_DeviceFactory->GetCurrentFrameBufferObject()->GetHeight();
 
151
        }
 
152
        else
 
153
        {
 
154
            m_CurrrentContext.width = GetWindowWidth();
 
155
            m_CurrrentContext.height = GetWindowHeight();
 
156
        }
 
157
    }
 
158
    else
 
159
    {
 
160
        m_CurrrentContext.width = width;
 
161
        m_CurrrentContext.height = height;
 
162
    }
 
163
}
 
164
 
 
165
void GraphicsContext::GetContextSize(int &w, int &h) const
 
166
{
 
167
    w = m_CurrrentContext.width;
 
168
    h = m_CurrrentContext.height;
 
169
}
 
170
 
 
171
int GraphicsContext::GetContextWidth() const
 
172
{
 
173
    return m_CurrrentContext.width;
 
174
}
 
175
 
 
176
int GraphicsContext::GetContextHeight() const
 
177
{
 
178
    return m_CurrrentContext.height;
 
179
}
 
180
 
 
181
int GraphicsContext::GetContextX() const
 
182
{
 
183
    return m_CurrrentContext.x;
 
184
}
 
185
 
 
186
int GraphicsContext::GetContextY() const
 
187
{
 
188
    return m_CurrrentContext.y;
 
189
}
 
190
 
 
191
void GraphicsContext::GetWindowSize(int &w, int &h) const
 
192
{
 
193
    m_GLWindow.GetWindowSize(w, h);
 
194
}
 
195
 
 
196
int GraphicsContext::GetWindowWidth() const
 
197
{
 
198
    return m_GLWindow.GetWindowWidth();
 
199
}
 
200
 
 
201
int GraphicsContext::GetWindowHeight() const
 
202
{
 
203
    return m_GLWindow.GetWindowHeight();
 
204
}
 
205
 
 
206
void GraphicsContext::LoadFonts()
 
207
{
 
208
    m_FontRenderer = new FontRenderer(*this);
 
209
}
 
210
 
 
211
int GraphicsContext::RenderColorText(const NFontPtr& Font, int x, int y, const NString& Str,
 
212
                                     const Color& TextColor,
 
213
                                     bool WriteAlphaChannel,
 
214
                                     int NumCharacter)
 
215
{
 
216
    if(m_FontRenderer)
 
217
        return m_FontRenderer->RenderColorText(Font, x, y, Str, TextColor, WriteAlphaChannel, NumCharacter);
 
218
    return 0;
 
219
}
 
220
 
 
221
int GraphicsContext::RenderColorTextLineStatic(const NFontPtr& Font, const PageBBox& pageSize, const NString& Str,
 
222
                                               const Color& TextColor,
 
223
                                               bool WriteAlphaChannel,
 
224
                                               TextAlignment alignment)
 
225
{
 
226
    if(m_FontRenderer)
 
227
        return m_FontRenderer->RenderColorTextLineStatic(Font, pageSize, Str, TextColor, WriteAlphaChannel, alignment);
 
228
    return 0;
 
229
}
 
230
 
 
231
int GraphicsContext::RenderColorTextLineEdit(const NFontPtr& Font, const PageBBox& pageSize, const NString& Str,
 
232
                                             const Color& TextColor,
 
233
                                             bool WriteAlphaChannel,
 
234
                                             const Color& SelectedTextColor,
 
235
                                             const Color& SelectedTextBackgroundColor,
 
236
                                             const Color& TextBlinkColor,
 
237
                                             const Color& CursorColor,
 
238
                                             bool ShowCursor, unsigned int CursorPosition, int offset, int selection_start, int selection_end)
 
239
{
 
240
    if(m_FontRenderer)
 
241
        return m_FontRenderer->RenderColorTextLineEdit(Font, pageSize, Str,
 
242
        TextColor,
 
243
        WriteAlphaChannel,
 
244
        SelectedTextColor,
 
245
        SelectedTextBackgroundColor,
 
246
        TextBlinkColor,
 
247
        CursorColor,
 
248
        ShowCursor, CursorPosition, offset, selection_start, selection_end);
 
249
    return 0;
 
250
}
 
251
 
 
252
void GraphicsContext::SetTexture(int TextureUnit, NTexture* Texture)
 
253
{
 
254
    nuxAssertMsg(Texture != 0, TEXT("[GraphicsContext::SetTexture] Texture is NULL."));
 
255
    if((TextureUnit < GL_TEXTURE0) || (TextureUnit > GL_TEXTURE31))
 
256
        return;
 
257
 
 
258
    TRefGL< NGLTexture > CachedTexture = ResourceCache.GetCachedResource(Texture);
 
259
    SetTexture(TextureUnit, CachedTexture->m_Texture);
 
260
}
 
261
 
 
262
void GraphicsContext::SetTexture(int TextureUnit, TRefGL< IOpenGLBaseTexture > DeviceTexture)
 
263
{
 
264
    INL_RETURN_IF_FALSE(DeviceTexture.IsValid());
 
265
 
 
266
    CHECKGL( glActiveTextureARB(TextureUnit) );
 
267
    DeviceTexture->BindTextureToUnit(TextureUnit);
 
268
}
 
269
 
 
270
void GraphicsContext::EnableTextureMode(int TextureUnit, int TextureMode)
 
271
{
 
272
    if((TextureUnit < GL_TEXTURE0) || (TextureUnit > GL_TEXTURE31))
 
273
        return;
 
274
    CHECKGL( glActiveTextureARB(TextureUnit) );
 
275
    CHECKGL( glEnable(TextureMode) );
 
276
}
 
277
 
 
278
void GraphicsContext::DisableTextureMode(int TextureUnit, int TextureMode)
 
279
{
 
280
    if((TextureUnit < GL_TEXTURE0) || (TextureUnit > GL_TEXTURE31))
 
281
        return;
 
282
    CHECKGL( glActiveTextureARB(TextureUnit) );
 
283
    CHECKGL( glDisable(TextureMode) );
 
284
    CHECKGL( glBindTexture(TextureMode, 0) );
 
285
}
 
286
 
 
287
void GraphicsContext::DisableAllTextureMode(int TextureUnit)
 
288
{
 
289
    if((TextureUnit < GL_TEXTURE0) || (TextureUnit > GL_TEXTURE31))
 
290
        return;
 
291
 
 
292
    GetThreadGLDeviceFactory()->InvalidateTextureUnit(TextureUnit);
 
293
}
 
294
 
 
295
//////////////////////
 
296
// DRAW CLIPPING    //
 
297
//////////////////////
 
298
void GraphicsContext::PushClippingRectangle(Rect A)
 
299
{
 
300
    if(m_GLWindow.m_DeviceFactory->GetCurrentFrameBufferObject().IsValid())
 
301
    {
 
302
        m_GLWindow.m_DeviceFactory->GetCurrentFrameBufferObject()->PushClippingRegion(A);
 
303
        return;
 
304
    }
 
305
 
 
306
    A.OffsetPosition(m_CurrrentContext.x, m_CurrrentContext.y);
 
307
 
 
308
    Rect B;
 
309
    UINT stacksize = (UINT)ClippingRect.size();
 
310
    INT x0, y0, x1, y1;
 
311
 
 
312
    int window_width, window_height;
 
313
    window_width = m_ViewportWidth;
 
314
    window_height = m_ViewportHeight;
 
315
 
 
316
    if(stacksize == 0)
 
317
    {
 
318
        B = Rect(0, 0, window_width, window_height);
 
319
    }
 
320
    else
 
321
    {
 
322
        B = ClippingRect[stacksize-1];
 
323
    }
 
324
 
 
325
//    http://www.codecomments.com/archive263-2004-12-350347.html
 
326
//    If your rectangles are given in 2D as Top,Left,Bottom,Right coordinates, as typical for GUI programming, then it's simply:
 
327
//        intersect.Left = max(a.Left, b.Left);
 
328
//        intersect.Top = max(a.Top, b.Top);
 
329
//        intersect.Right = min(a.Right, b.Right );
 
330
//        intersect.Bottom = min(a.Bottom, b.Bottom);
 
331
//    And the intersection is empty unless intersect.Right > intersect.Left && intersect.Bottom > intersect.Top
 
332
 
 
333
    x0 = Max(A.x, B.x);
 
334
    y0 = Max(A.y, B.y);
 
335
    x1 = Min(A.x + A.width, B.x + B.width);
 
336
    y1 = Min(A.y + A.height, B.y + B.height);
 
337
 
 
338
    if((x1 > x0) && (y1 > y0))
 
339
    {
 
340
        ClippingRect.push_back(Rect(x0, y0, x1 - x0, y1 - y0));
 
341
        
 
342
        EnableScissoring(true);
 
343
        SetDrawClippingRegion(x0, window_height - y0 - (y1 - y0), x1 - x0, y1 - y0);
 
344
    }
 
345
    else
 
346
    {
 
347
        ClippingRect.push_back(Rect(0, 0, 0, 0));
 
348
        EnableScissoring(true);
 
349
        SetDrawClippingRegion(0, 0, 0, 0);
 
350
    }
 
351
}
 
352
 
 
353
void GraphicsContext::PopClippingRectangle()
 
354
{
 
355
    if(m_GLWindow.m_DeviceFactory->GetCurrentFrameBufferObject().IsValid())
 
356
    {
 
357
        m_GLWindow.m_DeviceFactory->GetCurrentFrameBufferObject()->PopClippingRegion();
 
358
        return;
 
359
    }
 
360
 
 
361
    INT window_width, window_height;
 
362
    window_width = m_ViewportWidth;
 
363
    window_height = m_ViewportHeight;
 
364
 
 
365
    ClippingRect.pop_back();
 
366
    UINT stacksize = (UINT)ClippingRect.size();
 
367
    if(stacksize == 0)
 
368
    {
 
369
        EnableScissoring(true);
 
370
        SetDrawClippingRegion(0, 0, window_width, window_height);
 
371
    }
 
372
    else
 
373
    {
 
374
        Rect B = ClippingRect[stacksize-1];
 
375
        EnableScissoring(true);
 
376
        SetDrawClippingRegion(B.x, window_height - B.y - B.GetHeight(), B.GetWidth(), B.GetHeight());
 
377
    }
 
378
}
 
379
 
 
380
void GraphicsContext::ApplyClippingRectangle()
 
381
{
 
382
    if(m_GLWindow.m_DeviceFactory->GetCurrentFrameBufferObject().IsValid())
 
383
    {
 
384
        m_GLWindow.m_DeviceFactory->GetCurrentFrameBufferObject()->ApplyClippingRegion();
 
385
        return;
 
386
    }
 
387
 
 
388
    INT window_width, window_height;
 
389
    window_width = m_ViewportWidth;
 
390
    window_height = m_ViewportHeight;
 
391
 
 
392
    UINT stacksize = (UINT)ClippingRect.size();
 
393
    if(stacksize == 0)
 
394
    {
 
395
        EnableScissoring(true);
 
396
        SetDrawClippingRegion(0, 0, window_width, window_height);
 
397
    }
 
398
    else
 
399
    {
 
400
        Rect B = ClippingRect[stacksize-1];
 
401
        EnableScissoring(true);
 
402
        SetDrawClippingRegion(B.x, window_height - B.y - B.GetHeight(), B.GetWidth(), B.GetHeight());
 
403
    }
 
404
}
 
405
 
 
406
void GraphicsContext::EmptyClippingRegion()
 
407
{
 
408
    INT window_width, window_height;
 
409
    window_width = m_ViewportWidth;
 
410
    window_height = m_ViewportHeight;
 
411
    ClippingRect.clear();
 
412
    {
 
413
        EnableScissoring(true);
 
414
        SetDrawClippingRegion(0, 0, window_width, window_height);
 
415
    }
 
416
}
 
417
 
 
418
Rect GraphicsContext::GetClippingRegion() const
 
419
{
 
420
    UINT stacksize = (UINT)ClippingRect.size();
 
421
    if(stacksize == 0)
 
422
    {
 
423
        return Rect(0, 0, m_ViewportWidth, m_ViewportHeight);
 
424
    }
 
425
    else
 
426
    {
 
427
        Rect r = ClippingRect[stacksize-1];
 
428
        return r;
 
429
    }
 
430
}
 
431
 
 
432
int GraphicsContext::GetNumberOfClippingRegions() const
 
433
{
 
434
    return (int) ClippingRect.size();
 
435
}
 
436
 
 
437
void GraphicsContext::SetDrawClippingRegion(int x, int y, unsigned int width, unsigned int height)
 
438
{
 
439
    SetScissor(x, y, width, height);
 
440
}
 
441
 
 
442
///////////////////
 
443
// DRAW TEXTURE  //
 
444
///////////////////
 
445
 
 
446
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
447
// Rendering calls
 
448
 
 
449
//
 
450
//    From "OpenGL Programming Guide.pdf"
 
451
//
 
452
//    If exact two-dimensional rasterization is desired, you must carefully specify both the orthographic
 
453
//    projection and the vertices of primitives that are to be rasterized. The orthographic projection
 
454
//    should be specified with integer coordinates, as shown in the following example:
 
455
//    gluOrtho2D(0, width, 0, height);
 
456
//    where width and height are the dimensions of the viewport. Given this projection matrix, polygon
 
457
//    vertices and pixel image positions should be placed at integer coordinates to rasterize predictably.
 
458
//    For example, glRecti(0, 0, 1, 1) reliably fills the lower left pixel of the viewport, and glRasterPos2i(0,
 
459
//    0) reliably positions an unzoomed image at the lower left of the viewport. Point vertices, line
 
460
//    vertices, and bitmap positions should be placed at half-integer locations, however. For example, a
 
461
//    line drawn from (x1, 0.5) to (x2, 0.5) will be reliably rendered along the bottom row of pixels int the
 
462
//    viewport, and a point drawn at (0.5, 0.5) will reliably fill the same pixel as glRecti(0, 0, 1, 1).
 
463
//    An optimum compromise that allows all primitives to be specified at integer positions, while still
 
464
//    ensuring predictable rasterization, is to translate x and y by 0.375, as shown in the following code
 
465
//    fragment. Such a translation keeps polygon and pixel image edges safely away from the centers of
 
466
//    pixels, while moving line vertices close enough to the pixel centers.
 
467
//    glViewport(0, 0, width, height);
 
468
//    glMatrixMode(GL_PROJECTION);
 
469
//    glLoadIdentity();
 
470
//    gluOrtho2D(0, width, 0, height);
 
471
//    glMatrixMode(GL_MODELVIEW);
 
472
//    glLoadIdentity();
 
473
//    glTranslatef(0.375, 0.375, 0.0);
 
474
/* render all primitives at integer positions */
 
475
 
 
476
const float RASTERIZATION_OFFSET = 0.375f;
 
477
void GraphicsContext::Push2DWindow(int w, int h)
 
478
{
 
479
    CHECKGL( glMatrixMode(GL_MODELVIEW) );
 
480
    {
 
481
        m_ModelViewMatrix.Translate(m_CurrrentContext.x + RASTERIZATION_OFFSET, m_CurrrentContext.y + RASTERIZATION_OFFSET, 0);
 
482
        Matrix4 temp;
 
483
        std::list<Matrix4>::iterator it;
 
484
        for(it = m_2DModelViewMatricesStack.begin(); it != m_2DModelViewMatricesStack.end(); it++)
 
485
        {
 
486
            temp = m_ModelViewMatrix;
 
487
            m_ModelViewMatrix = temp * (*it);
 
488
        }
 
489
        // m_ModelViewMatrix is row_major while opengl is column major. We need to transpose.
 
490
        m_ModelViewMatrix.Transpose();
 
491
        CHECKGL( glLoadMatrixf((GLfloat*)(m_ModelViewMatrix.m)) );
 
492
    }
 
493
    CHECKGL( glMatrixMode(GL_PROJECTION) );
 
494
    {
 
495
        m_ProjectionMatrix.Orthographic(0, w, h, 0, -1.0f, 1.0f);
 
496
        // m_ProjectionMatrix is row_major while opengl is column major. We need to transpose.
 
497
        m_ProjectionMatrix.Transpose();
 
498
        CHECKGL( glLoadMatrixf((GLfloat*)(m_ProjectionMatrix.m)) );
 
499
    }
 
500
}
 
501
 
 
502
void GraphicsContext::Pop2DWindow()
 
503
{
 
504
    CHECKGL( glMatrixMode(GL_PROJECTION) );
 
505
    CHECKGL( glLoadIdentity() );
 
506
    CHECKGL( glMatrixMode(GL_MODELVIEW) );
 
507
    CHECKGL( glLoadIdentity() );
 
508
    CHECKGL( glFrustum(
 
509
        -1.0,     // left
 
510
        1.0,      // right
 
511
        -1.0,     // bottom
 
512
        1.0,      // top
 
513
        0.1,    // near,
 
514
        2000.0  // far
 
515
        ) );
 
516
}
 
517
 
 
518
void GraphicsContext::Push2DModelViewMatrix(Matrix4 mat)
 
519
{
 
520
    m_2DModelViewMatricesStack.push_back(mat);
 
521
    {
 
522
        CHECKGL( glMatrixMode(GL_MODELVIEW) );
 
523
        m_ModelViewMatrix.Translate(m_CurrrentContext.x + RASTERIZATION_OFFSET, m_CurrrentContext.y + RASTERIZATION_OFFSET, 0);
 
524
        Matrix4 temp;
 
525
        std::list<Matrix4>::iterator it;
 
526
        for(it = m_2DModelViewMatricesStack.begin(); it != m_2DModelViewMatricesStack.end(); it++)
 
527
        {
 
528
            temp = m_ModelViewMatrix;
 
529
            m_ModelViewMatrix = (*it) * temp;
 
530
        }
 
531
 
 
532
        // m_ModelViewMatrix is row_major while opengl is column major. We need to transpose.
 
533
        m_ModelViewMatrix.Transpose();
 
534
        CHECKGL( glLoadMatrixf((GLfloat*)(m_ModelViewMatrix.m)) );
 
535
    }
 
536
}
 
537
 
 
538
Matrix4 GraphicsContext::Pop2DModelViewMatrix()
 
539
{
 
540
    Matrix4 Mat;
 
541
    Mat.Zero();
 
542
    if(m_2DModelViewMatricesStack.size() <= 0)
 
543
        return Mat;
 
544
 
 
545
    std::list<Matrix4>::iterator it;
 
546
    it = m_2DModelViewMatricesStack.end();
 
547
    --it;
 
548
    Mat = (*it);
 
549
    m_2DModelViewMatricesStack.pop_back();
 
550
 
 
551
    {
 
552
        CHECKGL( glMatrixMode(GL_MODELVIEW) );
 
553
        m_ModelViewMatrix.Translate(m_CurrrentContext.x + RASTERIZATION_OFFSET, m_CurrrentContext.y + RASTERIZATION_OFFSET, 0);
 
554
        Matrix4 temp;
 
555
        std::list<Matrix4>::iterator it;
 
556
        for(it = m_2DModelViewMatricesStack.begin(); it != m_2DModelViewMatricesStack.end(); it++)
 
557
        {
 
558
            temp = m_ModelViewMatrix;
 
559
            m_ModelViewMatrix = temp * (*it);
 
560
        }
 
561
 
 
562
        // m_ModelViewMatrix is row_major while opengl is column major. We need to transpose.
 
563
        m_ModelViewMatrix.Transpose();
 
564
        CHECKGL( glLoadMatrixf((GLfloat*)(m_ModelViewMatrix.m)) );
 
565
    }
 
566
    return Mat;
 
567
}
 
568
 
 
569
void GraphicsContext::Clear2DModelViewMatrix()
 
570
{
 
571
    m_2DModelViewMatricesStack.clear();
 
572
 
 
573
    {
 
574
        CHECKGL( glMatrixMode(GL_MODELVIEW) );
 
575
        m_ModelViewMatrix.Translate(m_CurrrentContext.x + RASTERIZATION_OFFSET, m_CurrrentContext.y + RASTERIZATION_OFFSET, 0);
 
576
        Matrix4 temp;
 
577
        std::list<Matrix4>::iterator it;
 
578
        for(it = m_2DModelViewMatricesStack.begin(); it != m_2DModelViewMatricesStack.end(); it++)
 
579
        {
 
580
            temp = m_ModelViewMatrix;
 
581
            m_ModelViewMatrix = temp * (*it);
 
582
        }
 
583
 
 
584
        // m_ModelViewMatrix is row_major while opengl is column major. We need to transpose.
 
585
        m_ModelViewMatrix.Transpose();
 
586
        CHECKGL( glLoadMatrixf((GLfloat*)(m_ModelViewMatrix.m)) );
 
587
    }
 
588
}
 
589
 
 
590
Matrix4 GraphicsContext::GetProjectionMatrix()
 
591
{
 
592
    return m_ProjectionMatrix;
 
593
}
 
594
 
 
595
Matrix4 GraphicsContext::GetModelViewMatrix()
 
596
{
 
597
    return m_ModelViewMatrix;
 
598
}
 
599
 
 
600
Matrix4 GraphicsContext::GetModelViewProjectionMatrix()
 
601
{
 
602
    return m_ModelViewMatrix*m_ProjectionMatrix;
 
603
}
 
604
 
 
605
Matrix4 GraphicsContext::GetOpenGLModelViewProjectionMatrix()
 
606
{
 
607
    // This matrix is the transposed version of GetModelViewProjectionMatrix.
 
608
    return m_ModelViewMatrix*m_ProjectionMatrix;
 
609
}
 
610
 
 
611
void GraphicsContext::SetEnvModeTextureAlphaBlend(int TextureUnit)
 
612
{
 
613
    // Render RGBA bitmap texture and alpha blend with the background
 
614
    // Make sure you call EnableBlending(bool b) before.
 
615
    CHECKGL( glActiveTextureARB(TextureUnit) );
 
616
    //glEnable(GL_BLEND);
 
617
    CHECKGL( glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) );
 
618
    // TextureEnvironment
 
619
    CHECKGL( glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB) );
 
620
    // RGB
 
621
    CHECKGL( glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE) ); 
 
622
    CHECKGL( glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE) );
 
623
    CHECKGL( glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR) );
 
624
    // ALPHA
 
625
    CHECKGL( glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE) );
 
626
    CHECKGL( glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE) );
 
627
    CHECKGL( glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA) );
 
628
}
 
629
 
 
630
void GraphicsContext::SetEnvModeSelectTexture(int TextureUnit)
 
631
{
 
632
    // Render RGBA bitmap texture.
 
633
    CHECKGL( glActiveTextureARB(TextureUnit) );
 
634
    // TextureEnvironment
 
635
    CHECKGL( glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB) );
 
636
    // RGB
 
637
    CHECKGL( glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE) ); 
 
638
    CHECKGL( glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE) );
 
639
    CHECKGL( glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR) );
 
640
    // ALPHA
 
641
    CHECKGL( glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE) );
 
642
    CHECKGL( glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE) );
 
643
    CHECKGL( glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA) );
 
644
}
 
645
 
 
646
void GraphicsContext::SetEnvModeSelectColor(int TextureUnit)
 
647
{
 
648
    // Render the color;
 
649
    CHECKGL( glActiveTextureARB(TextureUnit) );
 
650
    CHECKGL( glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB) );
 
651
    // RGB
 
652
    CHECKGL( glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE) ); 
 
653
    CHECKGL( glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PRIMARY_COLOR) );
 
654
    CHECKGL( glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR) );
 
655
    // ALPHA
 
656
    CHECKGL( glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE) );
 
657
    CHECKGL( glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PRIMARY_COLOR) );
 
658
    CHECKGL( glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA) );
 
659
}
 
660
 
 
661
void GraphicsContext::SetEnvModeModulateColorWithTexture(int TextureUnit)
 
662
{
 
663
    // Render RGBA bitmat texture and alpha blend with the background
 
664
    CHECKGL( glActiveTextureARB(TextureUnit) );
 
665
    CHECKGL( glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB) );
 
666
    // RGB
 
667
    CHECKGL( glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE) ); 
 
668
    CHECKGL( glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PRIMARY_COLOR) );
 
669
    CHECKGL( glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR) );
 
670
    CHECKGL( glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE) );
 
671
    CHECKGL( glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR) );
 
672
    // ALPHA
 
673
    CHECKGL( glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE) );
 
674
    CHECKGL( glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_TEXTURE) );
 
675
    CHECKGL( glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA) );
 
676
    CHECKGL( glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_TEXTURE) );
 
677
    CHECKGL( glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA) );
 
678
}
 
679
 
 
680
void GraphicsContext::SetViewport(int origin_x, int origin_y, int w, int h)
 
681
{
 
682
    nuxAssert(w >= 0);
 
683
    nuxAssert(h >= 0);
 
684
 
 
685
    m_ViewportX = origin_x;
 
686
    m_ViewportY = origin_y;
 
687
    m_ViewportWidth = w;
 
688
    m_ViewportHeight = h;
 
689
    
 
690
    if(m_ViewportWidth < 0)
 
691
    {
 
692
        nuxAssertMsg(0, TEXT("[GraphicsContext::SetViewport] Incorrect context size.") );
 
693
        m_ViewportWidth = 1;
 
694
    }
 
695
    if(m_ViewportHeight < 0)
 
696
    {
 
697
        nuxAssertMsg(0, TEXT("[GraphicsContext::SetViewport] Incorrect context size.") );
 
698
        m_ViewportHeight = 1;
 
699
    }
 
700
    CHECKGL( glViewport(origin_x, origin_y, m_ViewportWidth, m_ViewportHeight) );
 
701
}
 
702
 
 
703
Rect GraphicsContext::GetViewportRect()
 
704
{
 
705
    return Rect(m_ViewportX, m_ViewportY, m_ViewportWidth, m_ViewportHeight);
 
706
}
 
707
 
 
708
void GraphicsContext::SetScissorOffset(int x, int y)
 
709
{
 
710
    m_ScissorXOffset = x;
 
711
    m_ScissorYOffset = y;
 
712
}
 
713
 
 
714
void GraphicsContext::SetScissor(int x, int y, int w, int h)
 
715
{
 
716
    nuxAssert(w >= 0);
 
717
    nuxAssert(h >= 0);
 
718
    m_ScissorX = x;
 
719
    m_ScissorY = y;
 
720
    m_ScissorWidth = w;
 
721
    m_ScissorHeight = h;
 
722
    if(m_ScissorWidth < 0)
 
723
    {
 
724
        nuxAssertMsg(0, TEXT("[GraphicsContext::SetViewport] Incorrect context size.") );
 
725
        m_ScissorWidth = 1;
 
726
    }
 
727
    if(m_ScissorHeight < 0)
 
728
    {
 
729
        nuxAssertMsg(0, TEXT("[GraphicsContext::SetViewport] Incorrect context size.") );
 
730
        m_ScissorHeight = 1;
 
731
    }
 
732
    CHECKGL( glScissor(m_ScissorX + m_ScissorXOffset, m_ScissorY + m_ScissorYOffset, m_ScissorWidth, m_ScissorHeight) );
 
733
}
 
734
 
 
735
Rect GraphicsContext::GetScissorRect()
 
736
{
 
737
    return Rect(m_ScissorX, m_ScissorY, m_ScissorWidth, m_ScissorHeight);
 
738
}
 
739
 
 
740
void GraphicsContext::EnableScissoring(bool b)
 
741
{
 
742
    GetRenderStates().EnableScissor(b);
 
743
}
 
744
 
 
745
/////////////////////////////////////////
 
746
// 2D Area Clear Color Depth Stencil   //
 
747
/////////////////////////////////////////
 
748
 
 
749
void GraphicsContext::ClearAreaColorDepthStencil(int x, int y, int width, int height, Color clearcolor, float cleardepth, int clearstencil)
 
750
{
 
751
    GetThreadGLDeviceFactory()->InvalidateTextureUnit(GL_TEXTURE0);
 
752
    GetThreadGLDeviceFactory()->InvalidateTextureUnit(GL_TEXTURE1);
 
753
    GetThreadGLDeviceFactory()->InvalidateTextureUnit(GL_TEXTURE2);
 
754
    GetThreadGLDeviceFactory()->InvalidateTextureUnit(GL_TEXTURE3);
 
755
    EnableTextureMode(GL_TEXTURE0, GL_TEXTURE_2D);
 
756
    SetEnvModeSelectColor(GL_TEXTURE0);
 
757
    // enable stencil buffer
 
758
    CHECKGL( glEnable(GL_STENCIL_TEST) );
 
759
    // write a one to the stencil buffer everywhere we are about to draw
 
760
    CHECKGL( glStencilFunc(GL_ALWAYS, clearstencil, 0xFFFFFFFF) );
 
761
    // this is to always pass a one to the stencil buffer where we draw
 
762
    CHECKGL( glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE) );
 
763
 
 
764
 
 
765
 
 
766
    CHECKGL( glEnable(GL_DEPTH_TEST) );
 
767
    CHECKGL( glDepthFunc(GL_ALWAYS) );
 
768
 
 
769
    glBegin(GL_QUADS);
 
770
    {
 
771
        glColor4f(clearcolor.R(), clearcolor.G(), clearcolor.B(), clearcolor.A());
 
772
        glVertex4f(x,           y,          0.0f, 1.0f);
 
773
        glVertex4f(x + width,   y,          0.0f, 1.0f);
 
774
        glVertex4f(x + width,   y + height, 0.0f, 1.0f);
 
775
        glVertex4f(x,           y + height, 0.0f, 1.0f);
 
776
    }
 
777
    glEnd();
 
778
 
 
779
    CHECKGL( glDepthFunc(GL_LESS) );
 
780
    CHECKGL( glDisable(GL_DEPTH_TEST) );
 
781
    CHECKGL( glDisable(GL_STENCIL_TEST) );
 
782
}
 
783
 
 
784
void GraphicsContext::ClearAreaColor(int x, int y, int width, int height, Color clearcolor)
 
785
{
 
786
    //glClear(GL_DEPTH_BUFFER_BIT);
 
787
 
 
788
    GetThreadGLDeviceFactory()->InvalidateTextureUnit(GL_TEXTURE0);
 
789
    GetThreadGLDeviceFactory()->InvalidateTextureUnit(GL_TEXTURE1);
 
790
    GetThreadGLDeviceFactory()->InvalidateTextureUnit(GL_TEXTURE2);
 
791
    GetThreadGLDeviceFactory()->InvalidateTextureUnit(GL_TEXTURE3);
 
792
    EnableTextureMode(GL_TEXTURE0, GL_TEXTURE_2D);
 
793
    SetEnvModeSelectColor(GL_TEXTURE0);
 
794
 
 
795
    glBegin(GL_QUADS);
 
796
    {
 
797
        glColor4f(clearcolor.R(), clearcolor.G(), clearcolor.B(), clearcolor.A());
 
798
        glVertex4f(x,           y,          0.0f, 1.0f);
 
799
        glVertex4f(x + width,   y,          0.0f, 1.0f);
 
800
        glVertex4f(x + width,   y + height, 0.0f, 1.0f);
 
801
        glVertex4f(x,           y + height, 0.0f, 1.0f);
 
802
    }
 
803
    glEnd();
 
804
}
 
805
 
 
806
void GraphicsContext::ClearAreaDepthStencil(int x, int y, int width, int height, float cleardepth, int clearstencil)
 
807
{
 
808
    //glClear(GL_DEPTH_BUFFER_BIT);
 
809
 
 
810
    GetThreadGLDeviceFactory()->InvalidateTextureUnit(GL_TEXTURE0);
 
811
    GetThreadGLDeviceFactory()->InvalidateTextureUnit(GL_TEXTURE1);
 
812
    GetThreadGLDeviceFactory()->InvalidateTextureUnit(GL_TEXTURE2);
 
813
    GetThreadGLDeviceFactory()->InvalidateTextureUnit(GL_TEXTURE3);
 
814
    EnableTextureMode(GL_TEXTURE0, GL_TEXTURE_2D);
 
815
    SetEnvModeSelectColor(GL_TEXTURE0);
 
816
    // enable stencil buffer
 
817
    CHECKGL( glEnable(GL_STENCIL_TEST) );
 
818
    // write a one to the stencil buffer everywhere we are about to draw
 
819
    CHECKGL( glStencilFunc(GL_ALWAYS, clearstencil, 0xFFFFFFFF) );
 
820
    // this is to always pass a one to the stencil buffer where we draw
 
821
    CHECKGL( glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE) );
 
822
 
 
823
    CHECKGL( glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE) );
 
824
    CHECKGL( glEnable(GL_DEPTH_TEST) );
 
825
    CHECKGL( glDepthFunc(GL_ALWAYS) );
 
826
 
 
827
    glBegin(GL_QUADS);
 
828
    {
 
829
        glVertex4f(x,           y,          0.0f, 1.0f);
 
830
        glVertex4f(x + width,   y,          0.0f, 1.0f);
 
831
        glVertex4f(x + width,   y + height, 0.0f, 1.0f);
 
832
        glVertex4f(x,           y + height, 0.0f, 1.0f);
 
833
    }
 
834
    glEnd();
 
835
 
 
836
    CHECKGL( glDepthFunc(GL_LESS) );
 
837
    CHECKGL( glDisable(GL_DEPTH_TEST) );
 
838
    CHECKGL( glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE) );
 
839
    CHECKGL( glDisable(GL_STENCIL_TEST) );
 
840
 
 
841
}
 
842
 
 
843
//Statistics
 
844
void GraphicsContext::ResetStats()
 
845
{
 
846
    m_quad_stats            = 0;
 
847
    m_quad_tex_stats        = 0;
 
848
    m_triangle_stats        = 0;
 
849
    m_triangle_tex_stats    = 0;
 
850
    m_line_stats            = 0;
 
851
}
 
852
 
 
853
TRefGL< NGLResource > GraphicsContext::CacheResource(NResource* Resource)
 
854
{
 
855
    return ResourceCache.GetCachedResource(Resource);
 
856
}
 
857
 
 
858
void GraphicsContext::UpdateResource(NResource* Resource)
 
859
{
 
860
    TRefGL< NGLResource > GLResource = ResourceCache.FindCachedResourceById(Resource->GetResourceIndex()); //(NGLResource*)(*(ResourceCache.ResourceMap.find(Resource->ResourceIndex))).second;
 
861
    UBOOL bUpdated = FALSE;
 
862
 
 
863
    if(GLResource.IsValid())
 
864
    {
 
865
        // Iterate through all resource updater types (list is sorted by subclass depth).
 
866
        for (t_u32 i = 0; i < ResourceCache.GetResourceUpdaters().size(); ++i)
 
867
        {
 
868
            NResourceUpdater* ResourceUpdater = ResourceCache.GetResourceUpdaters()[i];
 
869
            nuxAssert(ResourceUpdater);
 
870
 
 
871
            // Check if the updater is valid for updating the resource.
 
872
            if( ResourceUpdater->UpdatesThisResource(Resource) )
 
873
            {
 
874
                bUpdated = ResourceUpdater->UpdateResource(GLResource, Resource);
 
875
                break;
 
876
            }
 
877
        }
 
878
    }
 
879
}
 
880
 
 
881
bool GraphicsContext::IsResourceCached(NResource* Resource)
 
882
{
 
883
    return ResourceCache.IsCachedResource(Resource);
 
884
}
 
885
 
 
886
NAMESPACE_END_OGL