Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

# KeosOGLRenderSystem.cpp

Go to the documentation of this file.

    00001 /*
    00002  * This source file is part of KEOS (Free 3D Engine)
    00003  * For the latest info, see http://www.keosengine.org/
    00004  * E-mails : thierry.vouriot@keosengine.org, yeri@keosengine.org
    00005  *
    00006  * This program is free software; you can redistribute it and/or modify it under
    00007  * the terms of the GNU Lesser General Public License as published by the Free Software
    00008  * Foundation; either version 2 of the License, or (at your option) any later
    00009  * version.
    00010  *
    00011  * This program is distributed in the hope that it will be useful, but WITHOUT
    00012  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    00013  * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
    00014  *
    00015  * You should have received a copy of the GNU Lesser General Public License along with
    00016  * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
    00017  * Place - Suite 330, Boston, MA 02111-1307, USA, or go to
    00018  * http://www.gnu.org/copyleft/lesser.txt.
    00019  *
    00020  */
    00021
    00022 #include "KeosOGLRenderSystem.h"
    00023 #include "KeosWin32Window.h"
    00024 #include "KeosOGLException.h"
    00025 #include "KeosLogger.h"
    00026 #include "KeosOGLEnum.h"
    00027 #include "KeosOGLBuffer.h"
    00028 #include "KeosOGLDeclaration.h"
    00029 #include "KeosMatrix4.h"
    00030 #include "KeosColor.h"
    00031 #include "KeosRenderSystemCapabilities.h"
    00032 #include "KeosOGLTexture.h"
    00033 #include "KeosPixelUtils.h"
    00034 #include "KeosString.h"
    00035 #include "KeosOGLShader.h"
    00036 #include "Cg/cgGL.h"
    00037
    00038
    00039 namespace Keos
    00040 {
    00041     //=======================================================================
    00042     // COGLRenderSystem implementation
    00043     //=======================================================================
    00044
    00045     // Functions ant macros for extensions loading
    00046     template <class T> inline void LoadExtension(T& Proc, const char* strName)
    00047     {
    00048         if (!(Proc = reinterpret_cast<T>(wglGetProcAddress(strName))))
    00049             OGL_EXCEPT("wglGetProcAddress", "LoadExtension");
    00050     }
    00051     #define LOAD_EXTENSION(Ext) LoadExtension(Ext, #Ext)
    00052
    00053     // OpenGL Extensions
    00054     PFNGLBINDBUFFERARBPROC              COGLRenderSystem::glBindBufferARB;
    00055     PFNGLDELETEBUFFERSARBPROC           COGLRenderSystem::glDeleteBuffersARB;
    00056     PFNGLGENBUFFERSARBPROC              COGLRenderSystem::glGenBuffersARB;
    00057     PFNGLBUFFERDATAARBPROC              COGLRenderSystem::glBufferDataARB;
    00058     PFNGLBUFFERSUBDATAARBPROC           COGLRenderSystem::glBufferSubDataARB;
    00059     PFNGLGETBUFFERSUBDATAARBPROC        COGLRenderSystem::glGetBufferSubDataARB;
    00060     PFNGLMAPBUFFERARBPROC               COGLRenderSystem::glMapBufferARB;
    00061     PFNGLUNMAPBUFFERARBPROC             COGLRenderSystem::glUnmapBufferARB;
    00062     PFNGLACTIVETEXTUREARBPROC           COGLRenderSystem::glActiveTextureARB;
    00063     PFNGLCLIENTACTIVETEXTUREARBPROC     COGLRenderSystem::glClientActiveTextureARB;
    00064     PFNGLCOMPRESSEDTEXIMAGE2DARBPROC    COGLRenderSystem::glCompressedTexImage2DARB;
    00065     PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC COGLRenderSystem::glCompressedTexSubImage2DARB;
    00066
    00067     //-----------------------------------------------------------------------
    00068     COGLRenderSystem::COGLRenderSystem()
    00069     {
    00070         m_bGLInitialized = false;
    00071     }
    00072
    00073     //-----------------------------------------------------------------------
    00074     COGLRenderSystem::~COGLRenderSystem()
    00075     {
    00076         Shutdown();
    00077     }
    00078
    00079         //-----------------------------------------------------------------------
    00080         const String& COGLRenderSystem::GetName(void) const
    00081     {
    00082         static String strName("OpenGL");
    00083         return strName;
    00084     }
    00085
    00086     //-----------------------------------------------------------------------
    00087     IRenderWindow* COGLRenderSystem::Initialise(bool bAutoCreateWindow, const String& strWindowTitle)
    00088     {
    00089         ILogger::Log("--> Starting Win32GL Subsystem");
    00090
    00091         ConfigOptionMap::iterator opt = m_Options.find("Video Mode");
    00092         if (opt == m_Options.end())
    00093             OGL_EXCEPT("Can't find \"Video Mode\" option", "COGLRenderSystem::Initialise");
    00094         String val = opt->second.currentValue;
    00095         String::size_type pos = val.find('x');
    00096         if (pos == String::npos)
    00097             OGL_EXCEPT("Invalid Video Mode provided", "COGLRenderSystem::Initialise");
    00098             uint w = CStringConverter::ParseUnsignedInt(val.substr(0, pos));
    00099         uint h = CStringConverter::ParseUnsignedInt(val.substr(pos + 1));
    00100
    00101         opt = m_Options.find("Color Depth");
    00102         if (opt == m_Options.end())
    00103             OGL_EXCEPT("Can't find \"Color Depth\" option", "COGLRenderSystem::Initialise");
    00104         val = opt->second.currentValue;
    00105         uint d = CStringConverter::ParseUnsignedInt(val);
    00106         if (d == 0)
    00107             OGL_EXCEPT("Invalid Color Depth provided", "COGLRenderSystem::Initialise");
    00108
    00109         opt = m_Options.find("Fullscreen");
    00110         if (opt == m_Options.end())
    00111             OGL_EXCEPT("Can't find \"Fullscreen\" option", "COGLRenderSystem::Initialise");
    00112         val = opt->second.currentValue;
    00113         bool f = CStringConverter::ParseBool(val);
    00114
    00115
    00116             IRenderWindow* pAutoWindow = CreateRenderWindow(strWindowTitle, w, h, d, f);
    00117
    00118                 return pAutoWindow;
    00119     }
    00120
    00121     //-----------------------------------------------------------------------
    00122     IRenderWindow* COGLRenderSystem::CreateRenderWindow(const String &strName, uint nWidth, uint nHeight, uint nColourDepth, bool bFullScreen)
    00123     {
    00124         ILogger::Log("--> Create Win32 render window");
    00125
    00126         // Create the window
    00127         IRenderWindow* win = new CWin32Window();
    00128         win->Create(strName, nWidth, nHeight, nColourDepth, bFullScreen);
    00129
    00130         AttachRenderTarget( *win );
    00131
    00132         if (!m_bGLInitialized)
    00133         {
    00134             // Initialise GL after the first window has been created
    00135             InitGL();
    00136         }
    00137
    00138         return win;
    00139     }
    00140
    00141     //-----------------------------------------------------------------------
    00142     void COGLRenderSystem::InitGL(void)
    00143     {
    00144         ILogger::Log("--> Initialise OpenGL");
    00145
    00146         // Retrieve extensions
    00147         m_strExtensions = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
    00148
    00149         // Load OpenGL extensions
    00150         LoadExtensions();
    00151
    00152                 // Setup Cg OGL Runtime
    00153                 if (m_pCapabilities->HasCapability(CAP_VERTEX_PROGRAM))
    00154                 {
    00155                         m_VSProfile = cgGLGetLatestProfile(CG_GL_VERTEX);
    00156                         cgGLSetOptimalOptions(m_VSProfile);
    00157                         m_VSOptions[0] = NULL;
    00158                 }
    00159                 if (m_pCapabilities->HasCapability(CAP_FRAGMENT_PROGRAM))
    00160                 {
    00161                         m_PSProfile = cgGLGetLatestProfile(CG_GL_FRAGMENT);
    00162                         cgGLSetOptimalOptions(m_PSProfile);
    00163                         m_PSOptions[0] = NULL;
    00164                 }
    00165
    00166         // Default states
    00167         SetClearColor(CColor::Black);
    00168         glClearDepth(1.0f);
    00169         glClearStencil(0x00);
    00170         glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
    00171         glShadeModel(GL_SMOOTH);
    00172         glEnable(GL_DEPTH_TEST);
    00173
    00174         m_bGLInitialized = true;
    00175     }
    00176
    00177     //-----------------------------------------------------------------------
    00178     void COGLRenderSystem::Reinitialise(void)
    00179     {
    00180         this->Shutdown();
    00181         this->Initialise(true);
    00182     }
    00183
    00184     //-----------------------------------------------------------------------
    00185     void COGLRenderSystem::Shutdown(void)
    00186     {
    00187         IRenderSystem::Shutdown();
    00188     }
    00189
    00190     //-----------------------------------------------------------------------
    00191     bool COGLRenderSystem::CheckExtension(const String& strExtension) const
    00192     {
    00193         return m_strExtensions.find(strExtension) != String::npos;
    00194     }
    00195
    00196     //-----------------------------------------------------------------------
    00197     void COGLRenderSystem::LoadExtensions()
    00198     {
    00199         // Load extensions
    00200         LOAD_EXTENSION(glBindBufferARB);
    00201         LOAD_EXTENSION(glDeleteBuffersARB);
    00202         LOAD_EXTENSION(glGenBuffersARB);
    00203         LOAD_EXTENSION(glBufferDataARB);
    00204         LOAD_EXTENSION(glBufferSubDataARB);
    00205         LOAD_EXTENSION(glGetBufferSubDataARB);
    00206         LOAD_EXTENSION(glMapBufferARB);
    00207         LOAD_EXTENSION(glUnmapBufferARB);
    00208         LOAD_EXTENSION(glActiveTextureARB);
    00209         LOAD_EXTENSION(glClientActiveTextureARB);
    00210         LOAD_EXTENSION(glCompressedTexImage2DARB);
    00211         LOAD_EXTENSION(glCompressedTexSubImage2DARB);
    00212
    00213         // Check for hardware mipmapping support
    00214         if (CheckExtension("GL_SGIS_generate_mipmap"))
    00215         {
    00216             m_pCapabilities->SetCapability(CAP_HW_MIPMAPPING);
    00217         }
    00218         // Check for texture dxt compression
    00219         if (CheckExtension("GL_ARB_texture_compression") && CheckExtension("GL_EXT_texture_compression_s3tc"))
    00220         {
    00221             m_pCapabilities->SetCapability(CAP_TEXTURE_COMPRESSION_DXT);
    00222         }
    00223         // Check for non-power-of-2 texture support
    00224         if (CheckExtension("GL_ARB_texture_non_power_of_two"))
    00225         {
    00226             m_pCapabilities->SetCapability(CAP_NON_POWER_OF_2_TEXTURES);
    00227         }
    00228         // Check for Multitexturing support and set number of texture units
    00229         if( CheckExtension("GL_ARB_multitexture"))
    00230         {
    00231             GLint units;
    00232             glGetIntegerv( GL_MAX_TEXTURE_UNITS, &units );
    00233             m_pCapabilities->SetNumTextureUnits(units);
    00234         }
    00235         else
    00236         {
    00237             // If no multitexture support then set one texture unit
    00238             m_pCapabilities->SetNumTextureUnits(1);
    00239         }
    00240
    00241         // Check for Vertex Program support and set version number
    00242         if(CheckExtension("GL_ARB_vertex_program"))
    00243         {
    00244             m_pCapabilities->SetCapability(CAP_VERTEX_PROGRAM);
    00245
    00246             // Vertex Program Properties
    00247             m_pCapabilities->SetMaxVertexProgramVersion("arbvp1");
    00248             //mCapabilities->setVertexProgramConstantBoolCount(0);
    00249             //mCapabilities->setVertexProgramConstantIntCount(0);
    00250             //mCapabilities->setVertexProgramConstantFloatCount(GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB);
    00251
    00252                         if (CheckExtension("GL_NV_vertex_program2_option"))
    00253                         {
    00254                                 m_pCapabilities->SetMaxVertexProgramVersion("vp30");
    00255                         }
    00256
    00257                         if (CheckExtension("GL_NV_vertex_program3"))
    00258                         {
    00259                                 m_pCapabilities->SetMaxVertexProgramVersion("vp40");
    00260                         }
    00261                 }
    00262
    00263         // Check for Fragment Program support and set version number
    00264         if (CheckExtension("GL_NV_register_combiners2") &&
    00265             CheckExtension("GL_NV_texture_shader"))
    00266         {
    00267             m_pCapabilities->SetCapability(CAP_FRAGMENT_PROGRAM);
    00268             m_pCapabilities->SetMaxFragmentProgramVersion("fp20");
    00269         }
    00270
    00271                 if (CheckExtension("GL_ATI_fragment_shader"))
    00272                 {
    00273             // ATI fragment shader not supported by Cg Compiler
    00274             ILogger::Log("ATI fragment shader not supported by Keos Engine (Cg Compiler)");
    00275             //m_pCapabilities->SetCapability(RSC_FRAGMENT_PROGRAM);
    00276             //m_pCapabilities->SetMaxFragmentProgramVersion("ps_1_4");
    00277             // no boolean params allowed
    00278             //m_pCapabilities->SetFragmentProgramConstantBoolCount(0);
    00279             // no integer params allowed
    00280             //m_pCapabilities->SetFragmentProgramConstantIntCount(0);
    00281                         // only 8 Vector4 constant floats supported
    00282             //m_pCapabilities->SetFragmentProgramConstantFloatCount(8);
    00283                 }
    00284
    00285         if (CheckExtension("GL_ARB_fragment_program"))
    00286         {
    00287             m_pCapabilities->SetCapability(CAP_FRAGMENT_PROGRAM);
    00288             // Fragment Program Properties
    00289             m_pCapabilities->SetMaxFragmentProgramVersion("arbfp1");
    00290             //m_pCapabilities->SetFragmentProgramConstantBoolCount(0);
    00291             //m_pCapabilities->SetFragmentProgramConstantIntCount(0);
    00292             //m_pCapabilities->SetFragmentProgramConstantFloatCount(GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB);
    00293
    00294                         if (CheckExtension("GL_NV_fragment_program_option"))
    00295                         {
    00296                                 m_pCapabilities->SetMaxFragmentProgramVersion("fp30");
    00297                         }
    00298
    00299                         if (CheckExtension("GL_NV_fragment_program2"))
    00300                         {
    00301                                 m_pCapabilities->SetMaxFragmentProgramVersion("fp40");
    00302                         }
    00303                 }
    00304
    00305         m_pCapabilities->Log();
    00306     }
    00307
    00308     //-----------------------------------------------------------------------
    00309     void COGLRenderSystem::BeginScene() const
    00310     {
    00311        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
    00312     }
    00313
    00314     //-----------------------------------------------------------------------
    00315     void COGLRenderSystem::EndScene() const
    00316     {  }
    00317
    00318     //-----------------------------------------------------------------------
    00319     void COGLRenderSystem::PrintInfo() const
    00320     {
    00321         printf("OpenGL informations :\n");
    00322         // Print informations about OpenGL
    00323             char *exten;
    00324             exten = (char *) glGetString(GL_VENDOR);
    00325             printf("%s\n",exten);
    00326             exten = (char *) glGetString(GL_RENDERER);
    00327             printf("%s\n",exten);
    00328             exten = (char *) glGetString(GL_VERSION);
    00329             printf("%s\n",exten);
    00330         //printf("Extensions: %s\n",m_strExtensions.data());
    00331     }
    00332
    00333     //-----------------------------------------------------------------------
    00334     IBufferBase* COGLRenderSystem::_CreateVB(ulong nSize, ulong nStride, ulong nFlags) const
    00335     {
    00336         // Buffer creation
    00337         uint nVertexBuffer = 0;
    00338         glGenBuffersARB(1, &nVertexBuffer);
    00339
    00340         // Fill buffer
    00341         glBindBufferARB(GL_ARRAY_BUFFER_ARB, nVertexBuffer);
    00342         glBufferDataARB(GL_ARRAY_BUFFER_ARB, nSize * nStride, NULL, COGLEnum::BufferFlags(nFlags));
    00343
    00344         return new COGLVertexBuffer(nSize, nVertexBuffer);
    00345     }
    00346
    00347
    00348     //-----------------------------------------------------------------------
    00349     IBufferBase* COGLRenderSystem::_CreateIB(ulong nSize, ulong nStride, ulong nFlags) const
    00350     {
    00351         // Buffer creation
    00352         uint nIndexBuffer = 0;
    00353         glGenBuffersARB(1, &nIndexBuffer);
    00354
    00355         // Fill buffer
    00356         glBindBufferARB(GL_ARRAY_BUFFER_ARB, nIndexBuffer);
    00357         glBufferDataARB(GL_ARRAY_BUFFER_ARB, nSize * nStride, NULL, COGLEnum::BufferFlags(nFlags));
    00358
    00359         return new COGLIndexBuffer(nSize, nIndexBuffer);
    00360     }
    00361
    00362     //-----------------------------------------------------------------------
    00363     IDeclaration* COGLRenderSystem::CreateDeclaration(const TDeclarationElement* Elements, size_t nCount) const
    00364     {
    00365         // OpenGL declaration creation
    00366         COGLDeclaration* Declaration = new COGLDeclaration;
    00367
    00368         // For each elements of the declaration, conversion in OGL element
    00369         std::vector<int> Offset(nCount, 0);
    00370         for (const TDeclarationElement* Elt = Elements; Elt < Elements + nCount; ++Elt)
    00371         {
    00372             // Build OGL element
    00373             COGLDeclaration::TElement CurrentElement;
    00374             CurrentElement.Usage  = Elt->Usage;
    00375             CurrentElement.Type   = Elt->DataType;
    00376             CurrentElement.Offset = Offset[Elt->Stream];
    00377
    00378             // Addition of the element
    00379                 Declaration->AddElement(Elt->Stream, CurrentElement);
    00380
    00381             // Increment offset
    00382             static const uint Size[] = {4, 8, 12, 16, 4};
    00383             Offset[Elt->Stream] += Size[Elt->DataType];
    00384         }
    00385
    00386         return Declaration;
    00387     }
    00388
    00389
    00390     //-----------------------------------------------------------------------
    00391     void COGLRenderSystem::_SetVB(uint nStream, const IBufferBase* pBuffer, ulong nStride, ulong nMinVertex, ulong nMaxVertex)
    00392     {
    00393         // Sending of the buffer OGL in the API
    00394         const COGLVertexBuffer* pVertexBuffer = static_cast<const COGLVertexBuffer*>(pBuffer);
    00395             glBindBufferARB(GL_ARRAY_BUFFER_ARB, pVertexBuffer->GetBuffer());
    00396
    00397         // Tables of correspondence
    00398         static const uint Size[] = {1, 2, 3, 4, 4};
    00399         static const uint Type[] = {GL_FLOAT, GL_FLOAT, GL_FLOAT, GL_FLOAT, GL_UNSIGNED_BYTE};
    00400
    00401         // glPointer setup
    00402         const COGLDeclaration::TElementArray& StreamDesc = m_CurrentDeclaration->GetStreamElements(nStream);
    00403         for (COGLDeclaration::TElementArray::const_iterator i = StreamDesc.begin(); i != StreamDesc.end(); ++i)
    00404         {
    00405             switch (i->Usage)
    00406             {
    00407                 // Position
    00408                 case ELT_USAGE_POSITION :
    00409                     glEnableClientState(GL_VERTEX_ARRAY);
    00410                     glVertexPointer(Size[i->Type], Type[i->Type], nStride, BUFFER_OFFSET(i->Offset + nMinVertex * nStride));
    00411                     break;
    00412
    00413                 // Normal
    00414                 case ELT_USAGE_NORMAL :
    00415                     glEnableClientState(GL_NORMAL_ARRAY);
    00416                     glNormalPointer(Type[i->Type], nStride, BUFFER_OFFSET(i->Offset + nMinVertex * nStride));
    00417                     break;
    00418
    00419                 // Diffuse color
    00420                 case ELT_USAGE_DIFFUSE :
    00421                     glEnableClientState(GL_COLOR_ARRAY);
    00422                     glColorPointer(Size[i->Type], Type[i->Type], nStride, BUFFER_OFFSET(i->Offset + nMinVertex * nStride));
    00423                     break;
    00424
    00425                 // Texture coordinates 0
    00426                 case ELT_USAGE_TEXCOORD0 :
    00427                                     glActiveTextureARB(GL_TEXTURE0_ARB);
    00428                                     glEnable(GL_TEXTURE_2D);
    00429                                     glClientActiveTextureARB(GL_TEXTURE0_ARB);
    00430                                     glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    00431                     glTexCoordPointer(Size[i->Type], Type[i->Type], nStride, BUFFER_OFFSET(i->Offset + nMinVertex * nStride));
    00432                     break;
    00433
    00434                 // Texture coordinates 1
    00435                 case ELT_USAGE_TEXCOORD1 :
    00436                                     glActiveTextureARB(GL_TEXTURE0_ARB);
    00437                                     glEnable(GL_TEXTURE_2D);
    00438                                     glClientActiveTextureARB(GL_TEXTURE0_ARB);
    00439                                     glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    00440                     glTexCoordPointer(Size[i->Type], Type[i->Type], nStride, BUFFER_OFFSET(i->Offset + nMinVertex * nStride));
    00441                     break;
    00442
    00443                 // Texture coordinates 2
    00444                 case ELT_USAGE_TEXCOORD2 :
    00445                                     glActiveTextureARB(GL_TEXTURE0_ARB);
    00446                                     glEnable(GL_TEXTURE_2D);
    00447                                     glClientActiveTextureARB(GL_TEXTURE0_ARB);
    00448                                     glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    00449                     glTexCoordPointer(Size[i->Type], Type[i->Type], nStride, BUFFER_OFFSET(i->Offset + nMinVertex * nStride));
    00450                     break;
    00451
    00452                 // Texture coordinates 3
    00453                 case ELT_USAGE_TEXCOORD3 :
    00454                                     glActiveTextureARB(GL_TEXTURE0_ARB);
    00455                                     glEnable(GL_TEXTURE_2D);
    00456                                     glClientActiveTextureARB(GL_TEXTURE0_ARB);
    00457                                     glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    00458                     glTexCoordPointer(Size[i->Type], Type[i->Type], nStride, BUFFER_OFFSET(i->Offset + nMinVertex * nStride));
    00459                     break;
    00460             }
    00461         }
    00462     }
    00463
    00464     //-----------------------------------------------------------------------
    00465     void COGLRenderSystem::_SetIB(const IBufferBase* pBuffer, ulong nStride)
    00466     {
    00467         const COGLIndexBuffer* pIndexBuffer = static_cast<const COGLIndexBuffer*>(pBuffer);
    00468
    00469         // Sending of the buffer in the API
    00470             glEnableClientState(GL_INDEX_ARRAY);
    00471             glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, pIndexBuffer->GetBuffer());
    00472
    00473         // Save the indices size
    00474         m_nIndexStride = nStride;
    00475     }
    00476
    00477     //-----------------------------------------------------------------------
    00478     void COGLRenderSystem::SetDeclaration(const IDeclaration* pDeclaration)
    00479     {
    00480         // Deactivation of the previous states
    00481         glColor4f(1, 1, 1, 1);
    00482             glDisableClientState(GL_VERTEX_ARRAY);
    00483             glDisableClientState(GL_NORMAL_ARRAY);
    00484             glDisableClientState(GL_COLOR_ARRAY);
    00485         for (int i = 0; i < 4; ++i)
    00486         {
    00487                 glActiveTextureARB(GL_TEXTURE0_ARB + i);
    00488                 glDisable(GL_TEXTURE_2D);
    00489         }
    00490
    00491         // Save the declaration
    00492         m_CurrentDeclaration = static_cast<const COGLDeclaration*>(pDeclaration);
    00493     }
    00494
    00495     //-----------------------------------------------------------------------
    00496     void COGLRenderSystem::DrawPrimitives(TPrimitiveType Type, ulong nFirstVertex, ulong nCount) const
    00497     {
    00498         // Display of the primitives
    00499         switch (Type)
    00500         {
    00501             case PT_TRIANGLELIST :  glDrawArrays(GL_TRIANGLES,      nFirstVertex, nCount * 3); break;
    00502             case PT_TRIANGLESTRIP : glDrawArrays(GL_TRIANGLE_STRIP, nFirstVertex, nCount + 2); break;
    00503             case PT_TRIANGLEFAN :   glDrawArrays(GL_TRIANGLE_FAN,   nFirstVertex, nCount + 1); break;
    00504             case PT_LINELIST :      glDrawArrays(GL_LINES,          nFirstVertex, nCount * 2); break;
    00505             case PT_LINESTRIP :     glDrawArrays(GL_LINE_STRIP,     nFirstVertex, nCount + 1); break;
    00506             case PT_POINTLIST :     glDrawArrays(GL_POINTS,         nFirstVertex, nCount);     break;
    00507         }
    00508     }
    00509
    00510     //-----------------------------------------------------------------------
    00511     void COGLRenderSystem::DrawIndexedPrimitives(TPrimitiveType Type, ulong nFirstIndex, ulong nCount) const
    00512     {
    00513         ulong nIndicesType = (m_nIndexStride == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT);
    00514         const void*   Offset      = BUFFER_OFFSET(nFirstIndex * m_nIndexStride);
    00515
    00516         // Display of the primitives
    00517         switch (Type)
    00518         {
    00519             case PT_TRIANGLELIST :  glDrawElements(GL_TRIANGLES,      nCount * 3, nIndicesType, Offset); break;
    00520             case PT_TRIANGLESTRIP : glDrawElements(GL_TRIANGLE_STRIP, nCount + 2, nIndicesType, Offset); break;
    00521             case PT_TRIANGLEFAN :   glDrawElements(GL_TRIANGLE_FAN,   nCount + 1, nIndicesType, Offset); break;
    00522             case PT_LINELIST :      glDrawElements(GL_LINES,          nCount * 2, nIndicesType, Offset); break;
    00523             case PT_LINESTRIP :     glDrawElements(GL_LINE_STRIP,     nCount + 1, nIndicesType, Offset); break;
    00524             case PT_POINTLIST :     glDrawElements(GL_POINTS,         nCount,     nIndicesType, Offset); break;
    00525         }
    00526     }
    00527
    00528     //-----------------------------------------------------------------------
    00529     void COGLRenderSystem::PushMatrix(TMatrixType Type)
    00530     {
    00531         if (Type >= MAT_TEXTURE_0)
    00532             glActiveTextureARB(GL_TEXTURE0_ARB + Type - MAT_TEXTURE_0);
    00533
    00534         glMatrixMode(COGLEnum::Get(Type));
    00535         glPushMatrix();
    00536     }
    00537
    00538     //-----------------------------------------------------------------------
    00539     void COGLRenderSystem::PopMatrix(TMatrixType Type)
    00540     {
    00541         if (Type >= MAT_TEXTURE_0)
    00542             glActiveTextureARB(GL_TEXTURE0_ARB + Type - MAT_TEXTURE_0);
    00543
    00544         glMatrixMode(COGLEnum::Get(Type));
    00545         glPopMatrix();
    00546     }
    00547
    00548     //-----------------------------------------------------------------------
    00549     void COGLRenderSystem::LoadMatrix(TMatrixType Type, const CMatrix4& Matrix)
    00550     {
    00551         if (Type >= MAT_TEXTURE_0)
    00552             glActiveTextureARB(GL_TEXTURE0_ARB + Type - MAT_TEXTURE_0);
    00553
    00554         glMatrixMode(COGLEnum::Get(Type));
    00555         glLoadMatrixf(Matrix);
    00556     }
    00557
    00558     //-----------------------------------------------------------------------
    00559     void COGLRenderSystem::LoadMatrixMult(TMatrixType Type, const CMatrix4& Matrix)
    00560     {
    00561         if (Type >= MAT_TEXTURE_0)
    00562             glActiveTextureARB(GL_TEXTURE0_ARB + Type - MAT_TEXTURE_0);
    00563
    00564         glMatrixMode(COGLEnum::Get(Type));
    00565         glMultMatrixf(Matrix);
    00566     }
    00567
    00568     //-----------------------------------------------------------------------
    00569     void COGLRenderSystem::GetMatrix(TMatrixType Type, CMatrix4& Matrix) const
    00570     {
    00571         if (Type >= MAT_TEXTURE_0)
    00572             glActiveTextureARB(GL_TEXTURE0_ARB + Type - MAT_TEXTURE_0);
    00573
    00574         glGetFloatv(COGLEnum::GetMatrix(Type), Matrix);
    00575     }
    00576
    00577     //-----------------------------------------------------------------------
    00578     ulong COGLRenderSystem::ConvertColor(const CColor& Color) const
    00579     {
    00580         return Color.ToABGR();
    00581     }
    00582
    00583     //-----------------------------------------------------------------------
    00584     ITextureBase* COGLRenderSystem::CreateTexture(const TVector2I& Size, TPixelFormat Format, ulong nFlags) const
    00585     {
    00586         uint nTexture;
    00587         glGenTextures(1, &nTexture);
    00588
    00589         glBindTexture(GL_TEXTURE_2D, nTexture);
    00590
    00591         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    00592         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    00593         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    00594         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
    00595
    00596         // @todo ya pas un prob la
    00597         //int NbMipmaps = nFlags & TEX_NOMIPMAP ? GetNbMipLevels(Size.x, Size.y) : 0;
    00598         int NbMipmaps = nFlags & TEX_NOMIPMAP ? 0 : GetNbMipLevels(Size.x, Size.y);
    00599
    00600         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, NbMipmaps);
    00601
    00602         if ((NbMipmaps > 0) && (GetCapabilities()->HasCapability(CAP_HW_MIPMAPPING)))
    00603             glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
    00604
    00605         int Width  = Size.x;
    00606         int Height = Size.y;
    00607         for (int i = 0; i <= NbMipmaps; ++i)
    00608         {
    00609             glTexImage2D(GL_TEXTURE_2D, i, COGLEnum::Get(Format).Internal, Width, Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
    00610
    00611             if (Width > 1)  Width  /= 2;
    00612             if (Height > 1) Height /= 2;
    00613         }
    00614
    00615         glBindTexture(GL_TEXTURE_2D, 0);
    00616
    00617         return new COGLTexture(Size, Format, NbMipmaps > 0, GetCapabilities()->HasCapability(CAP_HW_MIPMAPPING), nTexture);
    00618     }
    00619
    00620     //-----------------------------------------------------------------------
    00621     void COGLRenderSystem::SetTexture(uint nUnit, const ITextureBase* Texture) const
    00622     {
    00623         glActiveTextureARB(GL_TEXTURE0_ARB + nUnit);
    00624         const COGLTexture* OGLTexture = static_cast<const COGLTexture*>(Texture);
    00625
    00626         if (Texture)
    00627         {
    00628             glEnable(GL_TEXTURE_2D);
    00629             glBindTexture(GL_TEXTURE_2D, OGLTexture->GetOGLTexture());
    00630         }
    00631         else
    00632         {
    00633             glDisable(GL_TEXTURE_2D);
    00634             glBindTexture(GL_TEXTURE_2D, 0);
    00635         }
    00636     }
    00637
    00638     //-----------------------------------------------------------------------
    00639     void COGLRenderSystem::SetupAlphaBlending(TBlend Src, TBlend Dest) const
    00640     {
    00641         glBlendFunc(COGLEnum::Get(Src), COGLEnum::Get(Dest));
    00642     }
    00643
    00644     //-----------------------------------------------------------------------
    00645     void COGLRenderSystem::SetupTextureUnit(uint nUnit, TTextureOp Op, TTextureArg Arg1, TTextureArg Arg2, const CColor& Constant) const
    00646     {
    00647         // Activate the unit texture
    00648             glEnable(GL_TEXTURE_2D);
    00649         glActiveTextureARB(GL_TEXTURE0_ARB + nUnit);
    00650         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
    00651
    00652         // Operators and arguments
    00653         if (Op < TXO_ALPHA_FIRSTARG)
    00654         {
    00655             glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, COGLEnum::Get(Op));
    00656             glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, COGLEnum::Get(Arg1));
    00657             glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, COGLEnum::Get(Arg2));
    00658             glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR);
    00659             glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_COLOR);
    00660         }
    00661         else
    00662         {
    00663             glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, COGLEnum::Get(Op));
    00664             glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, COGLEnum::Get(Arg1));
    00665             glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, COGLEnum::Get(Arg2));
    00666             glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_EXT, GL_SRC_ALPHA);
    00667             glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_EXT, GL_SRC_ALPHA);
    00668         }
    00669
    00670         // Constants
    00671         if ((Arg1 == TXA_CONSTANT) || (Arg2 == TXA_CONSTANT))
    00672         {
    00673             float Color[4];
    00674             Constant.ToFloat(Color);
    00675             glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, Color);
    00676         }
    00677     }
    00678
    00679     //-----------------------------------------------------------------------
    00680     void COGLRenderSystem::Enable(TRenderParameter Param, bool bValue) const
    00681     {
    00682         switch (Param)
    00683         {
    00684             case RENDER_ZWRITE :
    00685             {
    00686                 glDepthMask(bValue);
    00687                 break;
    00688             }
    00689
    00690             default :
    00691             {
    00692                 if (bValue)
    00693                     glEnable(COGLEnum::Get(Param));
    00694                 else
    00695                     glDisable(COGLEnum::Get(Param));
    00696             }
    00697         }
    00698     }
    00699
    00700         //-----------------------------------------------------------------------
    00701         IShaderBase* COGLRenderSystem::CreateShader(CGprogram Program, TShaderType Type) const
    00702         {
    00703                 return new COGLShader(Program, Type);
    00704         }
    00705
    00706         //-----------------------------------------------------------------------
    00707         void COGLRenderSystem::SetVertexShader(const IShaderBase* pShader)
    00708         {
    00709                 const COGLShader* pOGLShader = static_cast<const COGLShader*>(pShader);
    00710
    00711                 if (pOGLShader)
    00712                 {
    00713                         if (pOGLShader->GetType() != SHADER_VERTEX)
    00714                                 OGL_EXCEPT("Incorrect shader type (Pixel Shader)", "COGLRenderSystem::SetVertexShader");
    00715
    00716                         cgGLBindProgram(pOGLShader->GetProgram());
    00717                         cgGLEnableProfile(m_VSProfile);
    00718                 }
    00719                 else
    00720                 {
    00721                         cgGLDisableProfile(m_VSProfile);
    00722                         cgGLUnbindProgram(m_VSProfile);
    00723                 }
    00724         }
    00725
    00726         //-----------------------------------------------------------------------
    00727         void COGLRenderSystem::SetPixelShader(const IShaderBase* pShader)
    00728         {
    00729                 const COGLShader* pOGLShader = static_cast<const COGLShader*>(pShader);
    00730
    00731                 if (pOGLShader)
    00732                 {
    00733                         if (pOGLShader->GetType() != SHADER_PIXEL)
    00734                                 OGL_EXCEPT("Incorrect shader type (Vertex Shader)", "COGLRenderSystem::SetPixelShader");
    00735
    00736                         cgGLBindProgram(pOGLShader->GetProgram());
    00737                         cgGLEnableProfile(m_PSProfile);
    00738                 }
    00739                 else
    00740                 {
    00741                         cgGLDisableProfile(m_PSProfile);
    00742                         cgGLUnbindProgram(m_PSProfile);
    00743                 }
    00744         }
    00745
    00746         //-----------------------------------------------------------------------
    00747         void COGLRenderSystem::SetClearColor(const CColor& Color)
    00748         {
    00749                 float rgba[4];
    00750                 Color.ToFloat(rgba);
    00751
    00752                 m_ClearColor = Color;
    00753
    00754                 glClearColor(rgba[0], rgba[1], rgba[2], rgba[3]);
    00755         }
    00756
    00757 } // namespace Keos