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

glcontext.cpp

Go to the documentation of this file.
00001 // glcontext.h
00002 //
00003 // Copyright (C) 2003, Chris Laurel <claurel@shatters.net>
00004 //
00005 // This program is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU General Public License
00007 // as published by the Free Software Foundation; either version 2
00008 // of the License, or (at your option) any later version.
00009 
00010 #include <algorithm>
00011 #include <celutil/debug.h>
00012 #include "gl.h"
00013 #include "glext.h"
00014 #include "glcontext.h"
00015 
00016 using namespace std;
00017 
00018 
00019 static VertexProcessor* vpNV = NULL;
00020 static VertexProcessor* vpARB = NULL;
00021 static FragmentProcessor* fpNV = NULL;
00022 
00023 
00024 GLContext::GLContext() :
00025     renderPath(GLPath_Basic),
00026     vertexPath(VPath_Basic),
00027     vertexProc(NULL),
00028     maxSimultaneousTextures(1)
00029 {
00030 }
00031 
00032 GLContext::~GLContext()
00033 {
00034 }
00035 
00036 
00037 void GLContext::init(const vector<string>& ignoreExt)
00038 {
00039     char* extensionsString = (char*) glGetString(GL_EXTENSIONS);
00040     if (extensionsString != NULL)
00041     {
00042         char* next = extensionsString;
00043         
00044         while (*next != '\0')
00045         {
00046             while (*next != '\0' && *next != ' ')
00047                 next++;
00048 
00049             string ext(extensionsString, next - extensionsString);
00050 
00051             // scan the ignore list
00052             bool shouldIgnore = false;
00053             for (vector<string>::const_iterator iter = ignoreExt.begin();
00054                  iter != ignoreExt.end(); iter++)
00055             {
00056                 if (*iter == ext)
00057                 {
00058                     shouldIgnore = true;
00059                     break;
00060                 }
00061             }
00062 
00063             if (!shouldIgnore)
00064                 extensions.insert(extensions.end(), ext);
00065 
00066             if (*next == '\0')
00067                 break;
00068             next++;
00069             extensionsString = next;
00070         }
00071     }
00072 
00073     // Initialize all extensions used
00074     for (vector<string>::const_iterator iter = extensions.begin();
00075          iter != extensions.end(); iter++)
00076     {
00077         InitExtension(iter->c_str());
00078     }
00079 
00080     if (extensionSupported("GL_ARB_multitexture") &&
00081         glx::glActiveTextureARB != NULL)
00082     {
00083         glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB,
00084                       (GLint*) &maxSimultaneousTextures);
00085     }
00086 
00087     if (extensionSupported("GL_ARB_vertex_program") &&
00088         glx::glGenProgramsARB)
00089     {
00090         DPRINTF(1, "Renderer: ARB vertex programs supported.\n");
00091         if (vpARB == NULL)
00092             vpARB = vp::initARB();
00093         vertexProc = vpARB;
00094     }
00095     else if (extensionSupported("GL_NV_vertex_program") &&
00096              glx::glGenProgramsNV)
00097     {
00098         DPRINTF(1, "Renderer: nVidia vertex programs supported.\n");
00099         if (vpNV == NULL)
00100             vpNV = vp::initNV();
00101         vertexProc = vpNV;
00102     }
00103 
00104     if (extensionSupported("GL_NV_fragment_program") &&
00105         glx::glGenProgramsNV)
00106     {
00107         DPRINTF(1, "Renderer: nVidia fragment programs supported.\n");
00108         if (fpNV == NULL)
00109             fpNV = fp::initNV();
00110         fragmentProc = fpNV;
00111     }
00112 }
00113 
00114 
00115 bool GLContext::setRenderPath(GLRenderPath path)
00116 {
00117     if (!renderPathSupported(path))
00118         return false;
00119 
00120     switch (path)
00121     {
00122     case GLPath_Basic:
00123     case GLPath_Multitexture:
00124     case GLPath_NvCombiner:
00125         vertexPath = VPath_Basic;
00126         break;
00127     case GLPath_NvCombiner_NvVP:
00128         vertexPath = VPath_NV;
00129         break;
00130     case GLPath_DOT3_ARBVP:
00131     case GLPath_NvCombiner_ARBVP:
00132     case GLPath_ARBFP_ARBVP:
00133     case GLPath_NV30:
00134     case GLPath_GLSL:
00135         vertexPath = VPath_ARB;
00136         break;
00137     default:
00138         return false;
00139     }
00140 
00141     renderPath = path;
00142 
00143     return true;
00144 }
00145 
00146 
00147 bool GLContext::renderPathSupported(GLRenderPath path) const
00148 {
00149     switch (path)
00150     {
00151     case GLPath_Basic:
00152         return true;
00153 
00154     case GLPath_Multitexture:
00155         return (maxSimultaneousTextures > 1 &&
00156                ( extensionSupported("GL_EXT_texture_env_combine") ||
00157                  extensionSupported("GL_ARB_texture_env_combine")) );
00158 
00159     case GLPath_NvCombiner:
00160         return false;
00161         /*
00162         // No longer supported; all recent NVIDIA drivers also support
00163         // the vertex_program extension, so the combiners-only path
00164         // isn't necessary.
00165         return extensionSupported("GL_NV_register_combiners");
00166         */
00167 
00168     case GLPath_DOT3_ARBVP:
00169         return (extensionSupported("GL_ARB_texture_env_dot3") &&
00170                 extensionSupported("GL_ARB_vertex_program") &&
00171                 vertexProc != NULL);
00172 
00173     case GLPath_NvCombiner_NvVP:
00174         // If ARB_vertex_program is supported, don't report support for
00175         // this render path.
00176         return (extensionSupported("GL_NV_register_combiners") &&
00177                 extensionSupported("GL_NV_vertex_program") &&
00178                 !extensionSupported("GL_ARB_vertex_program") &&
00179                 vertexProc != NULL);
00180 
00181     case GLPath_NvCombiner_ARBVP:
00182         return (extensionSupported("GL_NV_register_combiners") &&
00183                 extensionSupported("GL_ARB_vertex_program") &&
00184                 vertexProc != NULL);
00185 
00186     case GLPath_ARBFP_ARBVP:
00187         return false;
00188         /*
00189         return (extensionSupported("GL_ARB_vertex_program") &&
00190                 extensionSupported("GL_ARB_fragment_program") &&
00191                 vertexProc != NULL);
00192         */
00193 
00194     case GLPath_NV30:
00195                 /* This render path is deprecated; GLSL is now preferred */
00196                 return false;
00197                 /*
00198         return (extensionSupported("GL_ARB_vertex_program") &&
00199                 extensionSupported("GL_NV_fragment_program"));
00200                 */
00201 
00202     case GLPath_GLSL:
00203         return (extensionSupported("GL_ARB_shader_objects") &&
00204                 extensionSupported("GL_ARB_shading_language_100") &&
00205                 extensionSupported("GL_ARB_vertex_shader") &&
00206                 extensionSupported("GL_ARB_fragment_shader"));
00207 
00208     default:
00209         return false;
00210     }
00211 }
00212 
00213 
00214 GLContext::GLRenderPath GLContext::nextRenderPath()
00215 {
00216     GLContext::GLRenderPath newPath = renderPath;
00217 
00218     do {
00219         newPath = (GLRenderPath) ((int) newPath + 1);;
00220         if (newPath > GLPath_GLSL)
00221             newPath = GLPath_Basic;
00222     } while (newPath != renderPath && !renderPathSupported(newPath));
00223 
00224     renderPath = newPath;
00225 
00226     return renderPath;
00227 }
00228 
00229 
00230 bool GLContext::extensionSupported(const string& ext) const
00231 {
00232     return (find(extensions.begin(), extensions.end(), ext) != extensions.end());
00233 }
00234 
00235 
00236 bool GLContext::bumpMappingSupported() const
00237 {
00238     return renderPath > GLPath_Multitexture;
00239 }
00240 
00241 
00242 GLContext::VertexPath GLContext::getVertexPath() const
00243 {
00244     return vertexPath;
00245 }
00246 
00247 
00248 VertexProcessor* GLContext::getVertexProcessor() const
00249 {
00250     return vertexPath == VPath_Basic ? NULL : vertexProc;
00251 }
00252 
00253 
00254 FragmentProcessor* GLContext::getFragmentProcessor() const
00255 {
00256     if (renderPath == GLPath_NV30 /* || renderPath == GLPath_ARGFP_ARBVP */ )
00257         return fragmentProc;
00258     else
00259         return NULL;
00260 }

Generated on Sat Jan 14 22:30:27 2006 for Celestia by  doxygen 1.4.1