Browse Source

Allow compiling out the fixed-function pipeline and request core context

rdb 10 years ago
parent
commit
555844f82a

+ 1 - 0
makepanda/makepanda.py

@@ -2052,6 +2052,7 @@ DTOOL_CONFIG=[
     ("DO_DCAST",                       'UNDEF',                  'UNDEF'),
     ("DO_DCAST",                       'UNDEF',                  'UNDEF'),
     ("DO_COLLISION_RECORDING",         'UNDEF',                  'UNDEF'),
     ("DO_COLLISION_RECORDING",         'UNDEF',                  'UNDEF'),
     ("SUPPORT_IMMEDIATE_MODE",         'UNDEF',                  'UNDEF'),
     ("SUPPORT_IMMEDIATE_MODE",         'UNDEF',                  'UNDEF'),
+    ("SUPPORT_FIXED_FUNCTION",         '1',                      '1'),
     ("TRACK_IN_INTERPRETER",           'UNDEF',                  'UNDEF'),
     ("TRACK_IN_INTERPRETER",           'UNDEF',                  'UNDEF'),
     ("DO_MEMORY_USAGE",                'UNDEF',                  'UNDEF'),
     ("DO_MEMORY_USAGE",                'UNDEF',                  'UNDEF'),
     ("DO_PIPELINING",                  '1',                      '1'),
     ("DO_PIPELINING",                  '1',                      '1'),

+ 3 - 0
panda/src/gles2gsg/gles2gsg.h

@@ -49,6 +49,9 @@
   #define OPENGLES_2
   #define OPENGLES_2
 #endif
 #endif
 
 
+// OpenGL ES 2 has no fixed-function pipeline.
+#undef SUPPORT_FIXED_FUNCTION
+
 #ifdef IS_OSX
 #ifdef IS_OSX
   #include <OpenGLES/ES2/gl.h>
   #include <OpenGLES/ES2/gl.h>
 //  #include <OpenGLES/ES2/glext.h>
 //  #include <OpenGLES/ES2/glext.h>

+ 5 - 0
panda/src/glesgsg/glesgsg.h

@@ -49,6 +49,11 @@
   #error OPENGLES_2 should not be defined!
   #error OPENGLES_2 should not be defined!
 #endif
 #endif
 
 
+// OpenGL ES 1 has only the fixed-function pipeline.
+#ifndef SUPPORT_FIXED_FUNCTION
+#define SUPPORT_FIXED_FUNCTION
+#endif
+
 // This prevents glext.h from getting included by gl.h
 // This prevents glext.h from getting included by gl.h
 // That way, we can provide our own, better version.
 // That way, we can provide our own, better version.
 #define __glext_h_
 #define __glext_h_

+ 25 - 19
panda/src/glstuff/glCgShaderContext_src.cxx

@@ -685,6 +685,7 @@ disable_shader_vertex_arrays() {
         _glgsg->_glVertexAttribDivisor(p, 0);
         _glgsg->_glVertexAttribDivisor(p, 0);
       }
       }
     } else {
     } else {
+#ifdef SUPPORT_FIXED_FUNCTION
       switch (p) {
       switch (p) {
       case CA_unknown:
       case CA_unknown:
         break;
         break;
@@ -705,6 +706,7 @@ disable_shader_vertex_arrays() {
         glDisableClientState(GL_TEXTURE_COORD_ARRAY);
         glDisableClientState(GL_TEXTURE_COORD_ARRAY);
         break;
         break;
       }
       }
+#endif  // SUPPORT_FIXED_FUNCTION
     }
     }
   }
   }
 
 
@@ -801,6 +803,7 @@ update_shader_vertex_arrays(ShaderContext *prev, bool force) {
 
 
         } else {
         } else {
           // It's a conventional vertex attribute.  Ugh.
           // It's a conventional vertex attribute.  Ugh.
+#ifdef SUPPORT_FIXED_FUNCTION
           switch (p) {
           switch (p) {
           case CA_unknown:
           case CA_unknown:
             break;
             break;
@@ -836,9 +839,11 @@ update_shader_vertex_arrays(ShaderContext *prev, bool force) {
             glEnableClientState(GL_TEXTURE_COORD_ARRAY);
             glEnableClientState(GL_TEXTURE_COORD_ARRAY);
             break;
             break;
           }
           }
+#endif  // SUPPORT_FIXED_FUNCTION
         }
         }
       } else {
       } else {
         // There is no vertex column with this name; disable the attribute array.
         // There is no vertex column with this name; disable the attribute array.
+#ifdef SUPPORT_FIXED_FUNCTION
         if (p == 0) {
         if (p == 0) {
           //NOTE: if we disable attribute 0 in compatibility profile, the object
           //NOTE: if we disable attribute 0 in compatibility profile, the object
           // will disappear.  In GLSL we fix this by forcing the vertex column
           // will disappear.  In GLSL we fix this by forcing the vertex column
@@ -852,7 +857,9 @@ update_shader_vertex_arrays(ShaderContext *prev, bool force) {
             _glgsg->_glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
             _glgsg->_glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
           }
           }
 
 
-        } else if (p > 0) {
+        } else
+#endif  // SUPPORT_FIXED_FUNCTION
+        if (p >= 0) {
           _glgsg->_glDisableVertexAttribArray(p);
           _glgsg->_glDisableVertexAttribArray(p);
 
 
           if (p == _color_attrib_index) {
           if (p == _color_attrib_index) {
@@ -863,6 +870,7 @@ update_shader_vertex_arrays(ShaderContext *prev, bool force) {
 #endif
 #endif
           }
           }
         } else {
         } else {
+#ifdef SUPPORT_FIXED_FUNCTION
           switch (p) {
           switch (p) {
           case CA_unknown:
           case CA_unknown:
             break;
             break;
@@ -888,6 +896,7 @@ update_shader_vertex_arrays(ShaderContext *prev, bool force) {
             glDisableClientState(GL_TEXTURE_COORD_ARRAY);
             glDisableClientState(GL_TEXTURE_COORD_ARRAY);
             break;
             break;
           }
           }
+#endif  // SUPPORT_FIXED_FUNCTION
         }
         }
       }
       }
     }
     }
@@ -920,35 +929,27 @@ disable_shader_texture_bindings() {
     return;
     return;
   }
   }
 
 
-#ifndef OPENGLES_2
-  for (int i=0; i<(int)_shader->_tex_spec.size(); i++) {
+  for (int i = 0; i < (int)_shader->_tex_spec.size(); ++i) {
     CGparameter p = _cg_parameter_map[_shader->_tex_spec[i]._id._seqno];
     CGparameter p = _cg_parameter_map[_shader->_tex_spec[i]._id._seqno];
     if (p == 0) continue;
     if (p == 0) continue;
 
 
     int texunit = cgGetParameterResourceIndex(p);
     int texunit = cgGetParameterResourceIndex(p);
     _glgsg->_glActiveTexture(GL_TEXTURE0 + texunit);
     _glgsg->_glActiveTexture(GL_TEXTURE0 + texunit);
 
 
-#ifndef OPENGLES
     glBindTexture(GL_TEXTURE_1D, 0);
     glBindTexture(GL_TEXTURE_1D, 0);
-#endif  // OPENGLES
     glBindTexture(GL_TEXTURE_2D, 0);
     glBindTexture(GL_TEXTURE_2D, 0);
-#ifndef OPENGLES_1
     if (_glgsg->_supports_3d_texture) {
     if (_glgsg->_supports_3d_texture) {
       glBindTexture(GL_TEXTURE_3D, 0);
       glBindTexture(GL_TEXTURE_3D, 0);
     }
     }
-#endif  // OPENGLES_1
-#ifndef OPENGLES
     if (_glgsg->_supports_2d_texture_array) {
     if (_glgsg->_supports_2d_texture_array) {
       glBindTexture(GL_TEXTURE_2D_ARRAY_EXT, 0);
       glBindTexture(GL_TEXTURE_2D_ARRAY_EXT, 0);
     }
     }
-#endif
     if (_glgsg->_supports_cube_map) {
     if (_glgsg->_supports_cube_map) {
       glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
       glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
     }
     }
     // This is probably faster - but maybe not as safe?
     // This is probably faster - but maybe not as safe?
     //cgGLDisableTextureParameter(p);
     //cgGLDisableTextureParameter(p);
   }
   }
-#endif  // OPENGLES_2
 
 
   cg_report_errors();
   cg_report_errors();
   _glgsg->report_my_gl_errors();
   _glgsg->report_my_gl_errors();
@@ -981,9 +982,10 @@ update_shader_texture_bindings(ShaderContext *prev) {
   nassertv(texattrib != (TextureAttrib *)NULL);
   nassertv(texattrib != (TextureAttrib *)NULL);
 
 
   for (int i = 0; i < (int)_shader->_tex_spec.size(); ++i) {
   for (int i = 0; i < (int)_shader->_tex_spec.size(); ++i) {
-    InternalName *id = _shader->_tex_spec[i]._name;
+    Shader::ShaderTexSpec &spec = _shader->_tex_spec[i];
+    const InternalName *id = spec._name;
 
 
-    CGparameter p = _cg_parameter_map[_shader->_tex_spec[i]._id._seqno];
+    CGparameter p = _cg_parameter_map[spec._id._seqno];
     if (p == 0) {
     if (p == 0) {
       continue;
       continue;
     }
     }
@@ -997,23 +999,27 @@ update_shader_texture_bindings(ShaderContext *prev) {
       tex = _glgsg->_target_shader->get_shader_input_texture(id, &sampler);
       tex = _glgsg->_target_shader->get_shader_input_texture(id, &sampler);
 
 
     } else {
     } else {
-      if (_shader->_tex_spec[i]._stage >= texattrib->get_num_on_stages()) {
+      if (spec._stage >= texattrib->get_num_on_stages()) {
+        // Apply a white texture in order to make it easier to use a shader
+        // that takes a texture on a model that doesn't have a texture applied.
+        _glgsg->_glActiveTexture(GL_TEXTURE0 + texunit);
+        _glgsg->apply_white_texture();
         continue;
         continue;
       }
       }
-      TextureStage *stage = texattrib->get_on_stage(_shader->_tex_spec[i]._stage);
+      TextureStage *stage = texattrib->get_on_stage(spec._stage);
       tex = texattrib->get_on_texture(stage);
       tex = texattrib->get_on_texture(stage);
       sampler = texattrib->get_on_sampler(stage);
       sampler = texattrib->get_on_sampler(stage);
       view += stage->get_tex_view_offset();
       view += stage->get_tex_view_offset();
     }
     }
 
 
-    if (_shader->_tex_spec[i]._suffix != 0) {
+    if (spec._suffix != 0) {
       // The suffix feature is inefficient. It is a temporary hack.
       // The suffix feature is inefficient. It is a temporary hack.
       if (tex == 0) {
       if (tex == 0) {
         continue;
         continue;
       }
       }
-      tex = tex->load_related(_shader->_tex_spec[i]._suffix);
+      tex = tex->load_related(spec._suffix);
     }
     }
-    if ((tex == 0) || (tex->get_texture_type() != _shader->_tex_spec[i]._desired_type)) {
+    if ((tex == 0) || (tex->get_texture_type() != spec._desired_type)) {
       continue;
       continue;
     }
     }
 
 
@@ -1035,11 +1041,11 @@ update_shader_texture_bindings(ShaderContext *prev) {
     }
     }
 
 
     _glgsg->apply_texture(tc);
     _glgsg->apply_texture(tc);
-    _glgsg->apply_sampler(i, sampler, tc);
+    _glgsg->apply_sampler(texunit, sampler, tc);
   }
   }
 
 
   cg_report_errors();
   cg_report_errors();
   _glgsg->report_my_gl_errors();
   _glgsg->report_my_gl_errors();
 }
 }
 
 
-#endif  // OPENGLES_1
+#endif  // !OPENGLES

+ 4 - 2
panda/src/glstuff/glGeomContext_src.cxx

@@ -37,7 +37,7 @@ CLP(GeomContext)::
 bool CLP(GeomContext)::
 bool CLP(GeomContext)::
 get_display_list(GLuint &index, const CLP(GeomMunger) *munger,
 get_display_list(GLuint &index, const CLP(GeomMunger) *munger,
                  UpdateSeq modified) {
                  UpdateSeq modified) {
-#ifdef OPENGLES
+#if defined(OPENGLES) || !defined(SUPPORT_FIXED_FUNCTION)
   // Display lists not supported by OpenGL ES.
   // Display lists not supported by OpenGL ES.
   nassertr(false, false);
   nassertr(false, false);
   return false;
   return false;
@@ -68,7 +68,7 @@ get_display_list(GLuint &index, const CLP(GeomMunger) *munger,
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void CLP(GeomContext)::
 void CLP(GeomContext)::
 release_display_lists() {
 release_display_lists() {
-#ifdef OPENGLES
+#if defined(OPENGLES) || !defined(SUPPORT_FIXED_FUNCTION)
   // Display lists not supported by OpenGL ES.
   // Display lists not supported by OpenGL ES.
   nassertv(_display_lists.empty());
   nassertv(_display_lists.empty());
 
 
@@ -103,6 +103,7 @@ release_display_lists() {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void CLP(GeomContext)::
 void CLP(GeomContext)::
 remove_munger(CLP(GeomMunger) *munger) {
 remove_munger(CLP(GeomMunger) *munger) {
+#if !defined(OPENGLES) && defined(SUPPORT_FIXED_FUNCTION)
   DisplayLists::iterator dli = _display_lists.find(munger);
   DisplayLists::iterator dli = _display_lists.find(munger);
   nassertv(dli != _display_lists.end());
   nassertv(dli != _display_lists.end());
 
 
@@ -116,4 +117,5 @@ remove_munger(CLP(GeomMunger) *munger) {
   // running in any thread.  Instead, enqueue the display list index
   // running in any thread.  Instead, enqueue the display list index
   // and let it get deleted at the end of the current or next frame.
   // and let it get deleted at the end of the current or next frame.
   glgsg->record_deleted_display_list(index);
   glgsg->record_deleted_display_list(index);
+#endif
 }
 }

+ 1 - 1
panda/src/glstuff/glGraphicsBuffer_src.cxx

@@ -1054,7 +1054,7 @@ attach_tex(int layer, int view, Texture *attach, GLenum attachpoint) {
   // to a framebuffer attachment.
   // to a framebuffer attachment.
   glgsg->apply_texture(gtc);
   glgsg->apply_texture(gtc);
 
 
-#ifndef OPENGLES
+#if !defined(OPENGLES) && defined(SUPPORT_FIXED_FUNCTION)
   GLclampf priority = 1.0f;
   GLclampf priority = 1.0f;
   glPrioritizeTextures(1, &gtc->_index, &priority);
   glPrioritizeTextures(1, &gtc->_index, &priority);
 #endif
 #endif

+ 11 - 11
panda/src/glstuff/glGraphicsStateGuardian_src.I

@@ -354,7 +354,7 @@ enable_line_smooth(bool val) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE void CLP(GraphicsStateGuardian)::
 INLINE void CLP(GraphicsStateGuardian)::
 enable_point_smooth(bool val) {
 enable_point_smooth(bool val) {
-#ifndef OPENGLES_2
+#ifdef SUPPORT_FIXED_FUNCTION
   if (_point_smooth_enabled != val) {
   if (_point_smooth_enabled != val) {
     _state_mask.clear_bit(TransparencyAttrib::get_class_slot());
     _state_mask.clear_bit(TransparencyAttrib::get_class_slot());
     _point_smooth_enabled = val;
     _point_smooth_enabled = val;
@@ -532,7 +532,7 @@ enable_depth_test(bool val) {
   }
   }
 }
 }
 
 
-#ifndef OPENGLES_2
+#ifdef SUPPORT_FIXED_FUNCTION
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: GLGraphicsStateGuardian::enable_fog
 //     Function: GLGraphicsStateGuardian::enable_fog
 //       Access:
 //       Access:
@@ -559,7 +559,7 @@ enable_fog(bool val) {
 }
 }
 #endif
 #endif
 
 
-#ifndef OPENGLES_2
+#ifdef SUPPORT_FIXED_FUNCTION
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: GLGraphicsStateGuardian::enable_alpha_test
 //     Function: GLGraphicsStateGuardian::enable_alpha_test
 //       Access:
 //       Access:
@@ -644,7 +644,7 @@ clear_color_write_mask() {
   }
   }
 }
 }
 
 
-#ifndef OPENGLES_2
+#ifdef SUPPORT_FIXED_FUNCTION
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: GLGraphicsStateGuardian::call_glFogfv
 //     Function: GLGraphicsStateGuardian::call_glFogfv
 //       Access: Public
 //       Access: Public
@@ -662,7 +662,7 @@ call_glFogfv(GLenum pname, const LColor &color) {
 }
 }
 #endif
 #endif
 
 
-#ifndef OPENGLES_2
+#ifdef SUPPORT_FIXED_FUNCTION
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: GLGraphicsStateGuardian::call_glMaterialfv
 //     Function: GLGraphicsStateGuardian::call_glMaterialfv
 //       Access: Public
 //       Access: Public
@@ -680,7 +680,7 @@ call_glMaterialfv(GLenum face, GLenum pname, const LColor &color) {
 }
 }
 #endif
 #endif
 
 
-#ifndef OPENGLES_2
+#ifdef SUPPORT_FIXED_FUNCTION
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: GLGraphicsStateGuardian::call_glLightfv
 //     Function: GLGraphicsStateGuardian::call_glLightfv
 //       Access: Public
 //       Access: Public
@@ -698,7 +698,7 @@ call_glLightfv(GLenum light, GLenum pname, const LVecBase4 &value) {
 }
 }
 #endif
 #endif
 
 
-#ifndef OPENGLES_2
+#ifdef SUPPORT_FIXED_FUNCTION
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: GLGraphicsStateGuardian::call_glLightfv
 //     Function: GLGraphicsStateGuardian::call_glLightfv
 //       Access: Public
 //       Access: Public
@@ -716,7 +716,7 @@ call_glLightfv(GLenum light, GLenum pname, const LVecBase3 &value) {
 }
 }
 #endif
 #endif
 
 
-#ifndef OPENGLES_2
+#ifdef SUPPORT_FIXED_FUNCTION
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: GLGraphicsStateGuardian::call_glLightModelfv
 //     Function: GLGraphicsStateGuardian::call_glLightModelfv
 //       Access: Public
 //       Access: Public
@@ -734,7 +734,7 @@ call_glLightModelfv(GLenum pname, const LVecBase4 &value) {
 }
 }
 #endif
 #endif
 
 
-#ifndef OPENGLES_2
+#ifdef SUPPORT_FIXED_FUNCTION
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: GLGraphicsStateGuardian::call_glTexEnvfv
 //     Function: GLGraphicsStateGuardian::call_glTexEnvfv
 //       Access: Public
 //       Access: Public
@@ -768,7 +768,7 @@ call_glTexParameterfv(GLenum target, GLenum pname, const LVecBase4 &value) {
 #endif  //  STDFLOAT_DOUBLE
 #endif  //  STDFLOAT_DOUBLE
 }
 }
 
 
-#ifndef OPENGLES_2
+#ifdef SUPPORT_FIXED_FUNCTION
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: GLGraphicsStateGuardian::get_light_id
 //     Function: GLGraphicsStateGuardian::get_light_id
 //       Access: Public
 //       Access: Public
@@ -780,7 +780,7 @@ get_light_id(int index) const {
 }
 }
 #endif
 #endif
 
 
-#ifndef OPENGLES_2
+#ifdef SUPPORT_FIXED_FUNCTION
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: GLGraphicsStateGuardian::get_clip_plane_id
 //     Function: GLGraphicsStateGuardian::get_clip_plane_id
 //       Access: Public
 //       Access: Public

File diff suppressed because it is too large
+ 339 - 136
panda/src/glstuff/glGraphicsStateGuardian_src.cxx


+ 36 - 18
panda/src/glstuff/glGraphicsStateGuardian_src.h

@@ -57,6 +57,7 @@ typedef double GLdouble;
 // functions are defined, and the system gl.h sometimes doesn't
 // functions are defined, and the system gl.h sometimes doesn't
 // declare these typedefs.
 // declare these typedefs.
 #if !defined( __EDG__ ) || defined( __INTEL_COMPILER )  // Protect the following from the Tau instrumentor and expose it for the intel compiler.
 #if !defined( __EDG__ ) || defined( __INTEL_COMPILER )  // Protect the following from the Tau instrumentor and expose it for the intel compiler.
+typedef const GLubyte * (APIENTRYP PFNGLGETSTRINGIPROC) (GLenum name, GLuint index);
 typedef void (APIENTRY *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,GLvoid *userParam);
 typedef void (APIENTRY *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,GLvoid *userParam);
 typedef void (APIENTRYP PFNGLDEBUGMESSAGECALLBACKPROC) (GLDEBUGPROC callback, const void *userParam);
 typedef void (APIENTRYP PFNGLDEBUGMESSAGECALLBACKPROC) (GLDEBUGPROC callback, const void *userParam);
 typedef void (APIENTRYP PFNGLDEBUGMESSAGECONTROLPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled);
 typedef void (APIENTRYP PFNGLDEBUGMESSAGECONTROLPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled);
@@ -137,6 +138,9 @@ typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC) (GLen
 typedef void (APIENTRYP PFNGLTEXSTORAGE1DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width);
 typedef void (APIENTRYP PFNGLTEXSTORAGE1DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width);
 typedef void (APIENTRYP PFNGLTEXSTORAGE2DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
 typedef void (APIENTRYP PFNGLTEXSTORAGE2DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
 typedef void (APIENTRYP PFNGLTEXSTORAGE3DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
 typedef void (APIENTRYP PFNGLTEXSTORAGE3DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+typedef void (APIENTRYP PFNGLBINDVERTEXARRAYPROC) (GLuint array);
+typedef void (APIENTRYP PFNGLDELETEVERTEXARRAYSPROC) (GLsizei n, const GLuint *arrays);
+typedef void (APIENTRYP PFNGLGENVERTEXARRAYSPROC) (GLsizei n, GLuint *arrays);
 
 
 #ifndef OPENGLES_1
 #ifndef OPENGLES_1
 // GLSL shader functions
 // GLSL shader functions
@@ -341,7 +345,7 @@ public:
   virtual bool framebuffer_copy_to_ram
   virtual bool framebuffer_copy_to_ram
     (Texture *tex, int view, int z, const DisplayRegion *dr, const RenderBuffer &rb);
     (Texture *tex, int view, int z, const DisplayRegion *dr, const RenderBuffer &rb);
 
 
-#ifndef OPENGLES_2
+#ifdef SUPPORT_FIXED_FUNCTION
   void apply_fog(Fog *fog);
   void apply_fog(Fog *fog);
 
 
   virtual void bind_light(PointLight *light_obj, const NodePath &light,
   virtual void bind_light(PointLight *light_obj, const NodePath &light,
@@ -352,8 +356,6 @@ public:
                           int light_id);
                           int light_id);
 #endif
 #endif
 
 
-  void print_gfx_visual();
-
   LVecBase4 get_light_color(Light *light) const;
   LVecBase4 get_light_color(Light *light) const;
 
 
 #ifdef SUPPORT_IMMEDIATE_MODE
 #ifdef SUPPORT_IMMEDIATE_MODE
@@ -386,23 +388,25 @@ protected:
   void do_issue_rescale_normal();
   void do_issue_rescale_normal();
   void do_issue_color_write();
   void do_issue_color_write();
   void do_issue_depth_test();
   void do_issue_depth_test();
-#ifndef OPENGLES_2
+#ifdef SUPPORT_FIXED_FUNCTION
   void do_issue_alpha_test();
   void do_issue_alpha_test();
 #endif
 #endif
   void do_issue_depth_write();
   void do_issue_depth_write();
   void do_issue_cull_face();
   void do_issue_cull_face();
-#ifndef OPENGLES_2
+#ifdef SUPPORT_FIXED_FUNCTION
   void do_issue_fog();
   void do_issue_fog();
 #endif
 #endif
   void do_issue_depth_offset();
   void do_issue_depth_offset();
   void do_issue_shade_model();
   void do_issue_shade_model();
+#ifndef OPENGLES_1
   void do_issue_shader(bool state_has_changed = false);
   void do_issue_shader(bool state_has_changed = false);
-#ifndef OPENGLES_2
+#endif
+#ifdef SUPPORT_FIXED_FUNCTION
   void do_issue_material();
   void do_issue_material();
 #endif
 #endif
   void do_issue_texture();
   void do_issue_texture();
   void do_issue_blending();
   void do_issue_blending();
-#ifndef OPENGLES_2
+#ifdef SUPPORT_FIXED_FUNCTION
   void do_issue_tex_gen();
   void do_issue_tex_gen();
   void do_issue_tex_matrix();
   void do_issue_tex_matrix();
 #endif
 #endif
@@ -418,10 +422,11 @@ protected:
   static string get_error_string(GLenum error_code);
   static string get_error_string(GLenum error_code);
   string show_gl_string(const string &name, GLenum id);
   string show_gl_string(const string &name, GLenum id);
   virtual void query_gl_version();
   virtual void query_gl_version();
+  void query_glsl_version();
   void save_extensions(const char *extensions);
   void save_extensions(const char *extensions);
   virtual void get_extra_extensions();
   virtual void get_extra_extensions();
   void report_extensions() const;
   void report_extensions() const;
-  INLINE virtual bool has_extension(const string &extension) const FINAL;
+  INLINE virtual bool has_extension(const string &extension) const;
   INLINE bool is_at_least_gl_version(int major_version, int minor_version) const;
   INLINE bool is_at_least_gl_version(int major_version, int minor_version) const;
   INLINE bool is_at_least_gles_version(int major_version, int minor_version) const;
   INLINE bool is_at_least_gles_version(int major_version, int minor_version) const;
   void *get_extension_func(const char *name);
   void *get_extension_func(const char *name);
@@ -429,7 +434,7 @@ protected:
 
 
   virtual void reissue_transforms();
   virtual void reissue_transforms();
 
 
-#ifndef OPENGLES_2
+#ifdef SUPPORT_FIXED_FUNCTION
   virtual void enable_lighting(bool enable);
   virtual void enable_lighting(bool enable);
   virtual void set_ambient_light(const LColor &color);
   virtual void set_ambient_light(const LColor &color);
   virtual void enable_light(int light_id, bool enable);
   virtual void enable_light(int light_id, bool enable);
@@ -464,7 +469,7 @@ protected:
   INLINE void set_color_write_mask(int mask);
   INLINE void set_color_write_mask(int mask);
   INLINE void clear_color_write_mask();
   INLINE void clear_color_write_mask();
 
 
-#ifndef OPENGLES_2
+#ifdef SUPPORT_FIXED_FUNCTION
   INLINE void call_glFogfv(GLenum pname, const LColor &color);
   INLINE void call_glFogfv(GLenum pname, const LColor &color);
   INLINE void call_glMaterialfv(GLenum face, GLenum pname, const LColor &color);
   INLINE void call_glMaterialfv(GLenum face, GLenum pname, const LColor &color);
   INLINE void call_glLightfv(GLenum light, GLenum pname, const LVecBase4 &value);
   INLINE void call_glLightfv(GLenum light, GLenum pname, const LVecBase4 &value);
@@ -475,7 +480,7 @@ protected:
 
 
   INLINE void call_glTexParameterfv(GLenum target, GLenum pname, const LVecBase4 &value);
   INLINE void call_glTexParameterfv(GLenum target, GLenum pname, const LVecBase4 &value);
 
 
-#ifndef OPENGLES_2
+#ifdef SUPPORT_FIXED_FUNCTION
   INLINE GLenum get_light_id(int index) const;
   INLINE GLenum get_light_id(int index) const;
   INLINE GLenum get_clip_plane_id(int index) const;
   INLINE GLenum get_clip_plane_id(int index) const;
 #endif
 #endif
@@ -507,13 +512,15 @@ protected:
   static GLenum get_usage(Geom::UsageHint usage_hint);
   static GLenum get_usage(Geom::UsageHint usage_hint);
 
 
   void unbind_buffers();
   void unbind_buffers();
-#ifndef OPENGLES_2
+#ifdef SUPPORT_FIXED_FUNCTION
   void disable_standard_vertex_arrays();
   void disable_standard_vertex_arrays();
   bool update_standard_vertex_arrays(bool force);
   bool update_standard_vertex_arrays(bool force);
   void disable_standard_texture_bindings();
   void disable_standard_texture_bindings();
   void update_standard_texture_bindings();
   void update_standard_texture_bindings();
 #endif
 #endif
 
 
+  void apply_white_texture();
+
 #ifndef NDEBUG
 #ifndef NDEBUG
   void update_show_usage_texture_bindings(int show_stage_index);
   void update_show_usage_texture_bindings(int show_stage_index);
   void upload_usage_texture(int width, int height);
   void upload_usage_texture(int width, int height);
@@ -590,8 +597,7 @@ protected:
   ShaderContext *_vertex_array_shader_context;
   ShaderContext *_vertex_array_shader_context;
   PT(Shader) _texture_binding_shader;
   PT(Shader) _texture_binding_shader;
   ShaderContext *_texture_binding_shader_context;
   ShaderContext *_texture_binding_shader_context;
-#endif
-#ifdef OPENGLES_2
+
   static PT(Shader) _default_shader;
   static PT(Shader) _default_shader;
 #endif
 #endif
 
 
@@ -655,7 +661,7 @@ public:
   bool _explicit_primitive_restart;
   bool _explicit_primitive_restart;
 #endif
 #endif
 
 
-#ifndef OPENGLES
+#if defined(SUPPORT_FIXED_FUNCTION) && !defined(OPENGLES)
   PFNGLSECONDARYCOLORPOINTERPROC _glSecondaryColorPointer;
   PFNGLSECONDARYCOLORPOINTERPROC _glSecondaryColorPointer;
 #endif
 #endif
 
 
@@ -692,14 +698,18 @@ public:
   PFNGLGETCOMPRESSEDTEXIMAGEPROC _glGetCompressedTexImage;
   PFNGLGETCOMPRESSEDTEXIMAGEPROC _glGetCompressedTexImage;
 
 
   bool _supports_bgr;
   bool _supports_bgr;
-  bool _supports_rescale_normal;
   bool _supports_packed_dabc;
   bool _supports_packed_dabc;
   bool _supports_packed_ufloat;
   bool _supports_packed_ufloat;
 
 
+#ifdef SUPPORT_FIXED_FUNCTION
+  bool _supports_rescale_normal;
+#endif
+
   PFNGLACTIVETEXTUREPROC _glActiveTexture;
   PFNGLACTIVETEXTUREPROC _glActiveTexture;
-#ifndef OPENGLES_2
-  bool _supports_multitexture;
+#ifdef SUPPORT_FIXED_FUNCTION
   PFNGLCLIENTACTIVETEXTUREPROC _glClientActiveTexture;
   PFNGLCLIENTACTIVETEXTUREPROC _glClientActiveTexture;
+#endif
+#ifdef SUPPORT_IMMEDIATE_MODE
   PFNGLMULTITEXCOORD1FPROC _glMultiTexCoord1f;
   PFNGLMULTITEXCOORD1FPROC _glMultiTexCoord1f;
   PFNGLMULTITEXCOORD2FPROC _glMultiTexCoord2f;
   PFNGLMULTITEXCOORD2FPROC _glMultiTexCoord2f;
   PFNGLMULTITEXCOORD3FPROC _glMultiTexCoord3f;
   PFNGLMULTITEXCOORD3FPROC _glMultiTexCoord3f;
@@ -720,6 +730,12 @@ public:
   PFNGLBLENDEQUATIONPROC _glBlendEquation;
   PFNGLBLENDEQUATIONPROC _glBlendEquation;
   PFNGLBLENDCOLORPROC _glBlendColor;
   PFNGLBLENDCOLORPROC _glBlendColor;
 
 
+  bool _supports_vao;
+  GLuint _current_vao_index;
+  PFNGLBINDVERTEXARRAYPROC _glBindVertexArray;
+  PFNGLDELETEVERTEXARRAYSPROC _glDeleteVertexArrays;
+  PFNGLGENVERTEXARRAYSPROC _glGenVertexArrays;
+
   bool _supports_framebuffer_object;
   bool _supports_framebuffer_object;
   PFNGLISRENDERBUFFEREXTPROC _glIsRenderbuffer;
   PFNGLISRENDERBUFFEREXTPROC _glIsRenderbuffer;
   PFNGLBINDRENDERBUFFEREXTPROC _glBindRenderbuffer;
   PFNGLBINDRENDERBUFFEREXTPROC _glBindRenderbuffer;
@@ -888,6 +904,8 @@ public:
   bool _use_object_labels;
   bool _use_object_labels;
   PFNGLOBJECTLABELPROC _glObjectLabel;
   PFNGLOBJECTLABELPROC _glObjectLabel;
 
 
+  GLuint _white_texture;
+
 #ifndef NDEBUG
 #ifndef NDEBUG
   bool _show_texture_usage;
   bool _show_texture_usage;
   int _show_texture_usage_max_size;
   int _show_texture_usage_max_size;

+ 4 - 1
panda/src/glstuff/glShaderContext_src.cxx

@@ -2047,8 +2047,11 @@ update_shader_texture_bindings(ShaderContext *prev) {
       tex = _glgsg->_target_shader->get_shader_input_texture(id, &sampler);
       tex = _glgsg->_target_shader->get_shader_input_texture(id, &sampler);
 
 
     } else {
     } else {
-      // Numbered texture input.
       if (spec._stage >= texattrib->get_num_on_stages()) {
       if (spec._stage >= texattrib->get_num_on_stages()) {
+        // Apply a white texture in order to make it easier to use a shader
+        // that takes a texture on a model that doesn't have a texture applied.
+        _glgsg->_glActiveTexture(GL_TEXTURE0 + i);
+        _glgsg->apply_white_texture();
         continue;
         continue;
       }
       }
       TextureStage *stage = texattrib->get_on_stage(spec._stage);
       TextureStage *stage = texattrib->get_on_stage(spec._stage);

+ 4 - 0
panda/src/glstuff/glmisc_src.cxx

@@ -14,6 +14,10 @@
 
 
 #include "pandaSystem.h"
 #include "pandaSystem.h"
 
 
+ConfigVariableInt gl_version
+  ("gl-version", "",
+   PRC_DESC("Set this to get an OpenGL context with a specific version."));
+
 ConfigVariableBool gl_support_fbo
 ConfigVariableBool gl_support_fbo
   ("gl-support-fbo", true,
   ("gl-support-fbo", true,
    PRC_DESC("Configure this false if your GL's implementation of "
    PRC_DESC("Configure this false if your GL's implementation of "

+ 1 - 0
panda/src/glstuff/glmisc_src.h

@@ -41,6 +41,7 @@
 
 
 //#define GSG_VERBOSE 1
 //#define GSG_VERBOSE 1
 
 
+extern ConfigVariableInt gl_version;
 extern EXPCL_PANDAGL ConfigVariableBool gl_support_fbo;
 extern EXPCL_PANDAGL ConfigVariableBool gl_support_fbo;
 extern ConfigVariableBool gl_cheap_textures;
 extern ConfigVariableBool gl_cheap_textures;
 extern ConfigVariableBool gl_ignore_clamp;
 extern ConfigVariableBool gl_ignore_clamp;

+ 8 - 0
panda/src/glxdisplay/glxGraphicsStateGuardian.cxx

@@ -355,6 +355,14 @@ choose_pixel_format(const FrameBufferProperties &properties,
       n = 0;
       n = 0;
       attrib_list[n++] = GLX_RENDER_TYPE;
       attrib_list[n++] = GLX_RENDER_TYPE;
       attrib_list[n++] = render_type;
       attrib_list[n++] = render_type;
+      if (gl_version.get_num_words() > 0) {
+        attrib_list[n++] = GLX_CONTEXT_MAJOR_VERSION_ARB;
+        attrib_list[n++] = gl_version[0];
+        if (gl_version.get_num_words() > 1) {
+          attrib_list[n++] = GLX_CONTEXT_MINOR_VERSION_ARB;
+          attrib_list[n++] = gl_version[1];
+        }
+      }
       if (gl_debug) {
       if (gl_debug) {
         attrib_list[n++] = GLX_CONTEXT_FLAGS_ARB;
         attrib_list[n++] = GLX_CONTEXT_FLAGS_ARB;
         attrib_list[n++] = GLX_CONTEXT_DEBUG_BIT_ARB;
         attrib_list[n++] = GLX_CONTEXT_DEBUG_BIT_ARB;

Some files were not shown because too many files changed in this diff