00001
00002
00003
00004
00005
00006
00007
00008
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
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
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
00163
00164
00165
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
00175
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
00190
00191
00192
00193
00194 case GLPath_NV30:
00195
00196 return false;
00197
00198
00199
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 )
00257 return fragmentProc;
00258 else
00259 return NULL;
00260 }