Browse Source

Clean up glShaderContext, separate GLSL shader context from Cg shader context

rdb 11 years ago
parent
commit
ce6f243019

+ 67 - 0
panda/src/glstuff/glCgShaderContext_src.I

@@ -0,0 +1,67 @@
+// Filename: glCgShaderContext_src.h
+// Created by: rdb (27Jun14)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) Carnegie Mellon University.  All rights reserved.
+//
+// All use of this software is subject to the terms of the revised BSD
+// license.  You should have received a copy of this license along
+// with this source code in a file named "LICENSE."
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef OPENGLES_1
+
+////////////////////////////////////////////////////////////////////
+//     Function: GLCgShaderContext::valid
+//       Access: Public
+//  Description: Returns true if the shader is "valid", ie, if the
+//               compilation was successful.  The compilation could
+//               fail if there is a syntax error in the shader, or
+//               if the current video card isn't shader-capable,
+//               or if no shader languages are compiled into panda.
+////////////////////////////////////////////////////////////////////
+INLINE bool CLP(CgShaderContext)::
+valid() {
+  if (_shader->get_error_flag()) return false;
+  if (_shader->get_language() != Shader::SL_Cg) return false;
+  if (_cg_context) return true;
+  return false;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GLCgShaderContext::uses_standard_vertex_arrays
+//       Access: Public
+//  Description: Returns true if the shader may need to access
+//               standard vertex attributes as passed by
+//               glVertexPointer and the like.
+////////////////////////////////////////////////////////////////////
+INLINE bool CLP(CgShaderContext)::
+uses_standard_vertex_arrays() {
+  return _uses_standard_vertex_arrays;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GLCgShaderContext::uses_custom_vertex_arrays
+//       Access: Public
+//  Description: Always true, for now.
+////////////////////////////////////////////////////////////////////
+INLINE bool CLP(CgShaderContext)::
+uses_custom_vertex_arrays() {
+  return true;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GLCgShaderContext::uses_custom_texture_bindings
+//       Access: Public
+//  Description: Always true, for now.
+////////////////////////////////////////////////////////////////////
+INLINE bool CLP(CgShaderContext)::
+uses_custom_texture_bindings() {
+  return true;
+}
+
+#endif  // OPENGLES_1
+

+ 589 - 0
panda/src/glstuff/glCgShaderContext_src.cxx

@@ -0,0 +1,589 @@
+// Filename: glCgShaderContext_src.cxx
+// Created by: jyelon (01Sep05)
+// Updated by: fperazzi, PandaSE (29Apr10) (updated CLP with note that some
+//   parameter types only supported under Cg)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) Carnegie Mellon University.  All rights reserved.
+//
+// All use of this software is subject to the terms of the revised BSD
+// license.  You should have received a copy of this license along
+// with this source code in a file named "LICENSE."
+//
+////////////////////////////////////////////////////////////////////
+
+#if defined(HAVE_CG) && !defined(OPENGLES)
+
+#include "Cg/cgGL.h"
+
+#include "pStatTimer.h"
+
+TypeHandle CLP(CgShaderContext)::_type_handle;
+
+#ifndef NDEBUG
+#define cg_report_errors() { \
+  CGerror err = cgGetError(); \
+  if (err != CG_NO_ERROR) { \
+    GLCAT.error() << __FILE__ ", line " << __LINE__ << ": " << cgGetErrorString(err) << "\n"; \
+  } }
+#else
+#define cg_report_errors()
+#endif
+
+////////////////////////////////////////////////////////////////////
+//     Function: GLCgShaderContext::Constructor
+//       Access: Public
+//  Description: xyz
+////////////////////////////////////////////////////////////////////
+CLP(CgShaderContext)::
+CLP(CgShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderContext(s) {
+  _glgsg = glgsg;
+  _uses_standard_vertex_arrays = false;
+  _cg_context = 0;
+  _cg_vprofile = CG_PROFILE_UNKNOWN;
+  _cg_fprofile = CG_PROFILE_UNKNOWN;
+  _cg_gprofile = CG_PROFILE_UNKNOWN;
+
+  nassertv(s->get_language() == Shader::SL_Cg);
+
+  // Ask the shader to compile itself for us and 
+  // to give us the resulting Cg program objects.
+  if (!s->cg_compile_for(_glgsg->_shader_caps,
+                         _cg_context,
+                         _cg_vprogram,
+                         _cg_fprogram,
+                         _cg_gprogram,
+                         _cg_parameter_map)) {
+    return;
+  }
+
+  // Load the program.
+  if (_cg_vprogram != 0) {
+    _cg_vprofile = cgGetProgramProfile(_cg_vprogram);
+    cgGLLoadProgram(_cg_vprogram);
+    CGerror verror = cgGetError();
+    if (verror != CG_NO_ERROR) {
+      const char *str = cgGetErrorString(verror);
+      GLCAT.error()
+        << "Could not load Cg vertex program: " << s->get_filename(Shader::ST_vertex)
+        << " (" << cgGetProfileString(_cg_vprofile) << " " << str << ")\n";
+      release_resources();
+    }
+  }
+
+  if (_cg_fprogram != 0) {
+    _cg_fprofile = cgGetProgramProfile(_cg_fprogram);
+    cgGLLoadProgram(_cg_fprogram);
+    CGerror ferror = cgGetError();
+    if (ferror != CG_NO_ERROR) {
+      const char *str = cgGetErrorString(ferror);
+      GLCAT.error()
+        << "Could not load Cg fragment program: " << s->get_filename(Shader::ST_fragment)
+        << " (" << cgGetProfileString(_cg_fprofile) << " " << str << ")\n";
+      release_resources();
+    }
+  }
+
+  if (_cg_gprogram != 0) {
+    _cg_gprofile = cgGetProgramProfile(_cg_gprogram);
+    cgGLLoadProgram(_cg_gprogram);
+    CGerror gerror = cgGetError();
+    if (gerror != CG_NO_ERROR) {
+      const char *str = cgGetErrorString(gerror);
+      GLCAT.error()
+        << "Could not load Cg geometry program: " << s->get_filename(Shader::ST_geometry)
+        << " (" << cgGetProfileString(_cg_gprofile) << " " << str << ")\n";
+      release_resources();
+    }
+  }
+
+  _glgsg->report_my_gl_errors();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GLCgShaderContext::Destructor
+//       Access: Public
+//  Description: xyz
+////////////////////////////////////////////////////////////////////
+CLP(CgShaderContext)::
+~CLP(CgShaderContext)() {
+  release_resources();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GLCgShaderContext::release_resources
+//       Access: Public
+//  Description: Should deallocate all system resources (such as
+//               vertex program handles or Cg contexts).
+////////////////////////////////////////////////////////////////////
+void CLP(CgShaderContext)::
+release_resources() {
+  if (_cg_context) {
+    cgDestroyContext(_cg_context);
+    _cg_context  = 0;
+    // Do *NOT* destroy the programs here! It causes problems.
+//  if (_cg_vprogram != 0) cgDestroyProgram(_cg_vprogram);
+//  if (_cg_fprogram != 0) cgDestroyProgram(_cg_fprogram);
+//  if (_cg_gprogram != 0) cgDestroyProgram(_cg_gprogram);
+    _cg_vprogram = 0;
+    _cg_fprogram = 0;
+    _cg_gprogram = 0;
+    _cg_parameter_map.clear();
+  }
+  if (_glgsg) {
+    _glgsg->report_my_gl_errors();
+  } else if (glGetError() != GL_NO_ERROR) {
+    GLCAT.error() << "GL error in ShaderContext destructor\n";
+  }
+
+  if (!_glgsg) {
+    return;
+  }
+  _glgsg->report_my_gl_errors();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GLCgShaderContext::bind
+//       Access: Public
+//  Description: This function is to be called to enable a new
+//               shader.  It also initializes all of the shader's
+//               input parameters.
+////////////////////////////////////////////////////////////////////
+void CLP(CgShaderContext)::
+bind(bool reissue_parameters) {
+  if (reissue_parameters) {
+    // Pass in k-parameters and transform-parameters
+    issue_parameters(Shader::SSD_general);
+  }
+
+  if (_cg_context != 0) {
+    // Bind the shaders.
+    if (_cg_vprogram != 0) {
+      cgGLEnableProfile(_cg_vprofile);
+      cgGLBindProgram(_cg_vprogram);
+    }
+    if (_cg_fprogram != 0) {
+      cgGLEnableProfile(_cg_fprofile);
+      cgGLBindProgram(_cg_fprogram);
+    }
+    if (_cg_gprogram != 0) {
+      cgGLEnableProfile(_cg_gprofile);
+      cgGLBindProgram(_cg_gprogram);
+    }
+
+    cg_report_errors();
+    _glgsg->report_my_gl_errors();
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GLCgShaderContext::unbind
+//       Access: Public
+//  Description: This function disables a currently-bound shader.
+////////////////////////////////////////////////////////////////////
+void CLP(CgShaderContext)::
+unbind() {
+  if (_cg_context != 0) {
+    if (_cg_vprogram != 0) {
+      cgGLUnbindProgram(_cg_vprofile);
+      cgGLDisableProfile(_cg_vprofile);
+    }
+    if (_cg_fprogram != 0) {
+      cgGLUnbindProgram(_cg_fprofile);
+      cgGLDisableProfile(_cg_fprofile);
+    }
+    if (_cg_gprogram != 0) {
+      cgGLUnbindProgram(_cg_gprofile);
+      cgGLDisableProfile(_cg_gprofile);
+    }
+
+    cg_report_errors();
+    _glgsg->report_my_gl_errors();
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GLCgShaderContext::issue_parameters
+//       Access: Public
+//  Description: This function gets called whenever the RenderState
+//               or TransformState has changed, but the Shader
+//               itself has not changed.  It loads new values into the
+//               shader's parameters.
+//
+//               If "altered" is false, that means you promise that
+//               the parameters for this shader context have already
+//               been issued once, and that since the last time the
+//               parameters were issued, no part of the render
+//               state has changed except the external and internal
+//               transforms.
+////////////////////////////////////////////////////////////////////
+void CLP(CgShaderContext)::
+issue_parameters(int altered) {
+  PStatTimer timer(_glgsg->_draw_set_state_shader_parameters_pcollector);
+
+  if (!valid()) {
+    return;
+  }
+
+  // Iterate through _ptr parameters
+  for (int i=0; i<(int)_shader->_ptr_spec.size(); i++) {
+    if (altered & (_shader->_ptr_spec[i]._dep[0] | _shader->_ptr_spec[i]._dep[1])) {
+      const Shader::ShaderPtrSpec& _ptr = _shader->_ptr_spec[i];
+      Shader::ShaderPtrData* ptr_data = 
+        const_cast< Shader::ShaderPtrData*>(_glgsg->fetch_ptr_parameter(_ptr));
+      
+      if (ptr_data == NULL){ //the input is not contained in ShaderPtrData
+        release_resources();
+        return;
+      }
+      //check if the data must be shipped to the GPU
+      /*if (!ptr_data->_updated)
+        continue;
+        ptr_data->_updated = false;*/
+
+      //Check if the size of the shader input and ptr_data match
+      int input_size = _ptr._dim[0] * _ptr._dim[1] * _ptr._dim[2];
+
+      // dimension is negative only if the parameter had the (deprecated)k_ prefix.
+      if ((input_size > ptr_data->_size) && (_ptr._dim[0] > 0)) { 
+        GLCAT.error() << _ptr._id._name << ": incorrect number of elements, expected " 
+                      <<  input_size <<" got " <<  ptr_data->_size << "\n";
+        release_resources();
+        return;
+      }
+      CGparameter p = _cg_parameter_map[_ptr._id._seqno];
+      
+      switch (ptr_data->_type) {
+      case Shader::SPT_float:
+        switch(_ptr._info._class) {
+        case Shader::SAC_scalar: cgSetParameter1fv(p,(float*)ptr_data->_ptr); continue;
+        case Shader::SAC_vector:
+          switch(_ptr._info._type) {
+          case Shader::SAT_vec1: cgSetParameter1fv(p,(float*)ptr_data->_ptr); continue;
+          case Shader::SAT_vec2: cgSetParameter2fv(p,(float*)ptr_data->_ptr); continue;
+          case Shader::SAT_vec3: cgSetParameter3fv(p,(float*)ptr_data->_ptr); continue;
+          case Shader::SAT_vec4: cgSetParameter4fv(p,(float*)ptr_data->_ptr); continue;
+          }
+        case Shader::SAC_matrix: cgGLSetMatrixParameterfc(p,(float*)ptr_data->_ptr); continue;
+        case Shader::SAC_array: {
+          switch(_ptr._info._subclass) {
+          case Shader::SAC_scalar: 
+            cgGLSetParameterArray1f(p,0,_ptr._dim[0],(float*)ptr_data->_ptr); continue;
+          case Shader::SAC_vector:
+            switch(_ptr._dim[2]) {
+            case 1: cgGLSetParameterArray1f(p,0,_ptr._dim[0],(float*)ptr_data->_ptr); continue;
+            case 2: cgGLSetParameterArray2f(p,0,_ptr._dim[0],(float*)ptr_data->_ptr); continue;
+            case 3: cgGLSetParameterArray3f(p,0,_ptr._dim[0],(float*)ptr_data->_ptr); continue;
+            case 4: cgGLSetParameterArray4f(p,0,_ptr._dim[0],(float*)ptr_data->_ptr); continue;
+            }
+          case Shader::SAC_matrix:
+            cgGLSetMatrixParameterArrayfc(p,0,_ptr._dim[0],(float*)ptr_data->_ptr); continue;
+          }
+        } 
+        }
+      case Shader::SPT_double:
+        switch(_ptr._info._class) {
+        case Shader::SAC_scalar: cgSetParameter1dv(p,(double*)ptr_data->_ptr); continue;
+        case Shader::SAC_vector:
+          switch(_ptr._info._type) {
+          case Shader::SAT_vec1: cgSetParameter1dv(p,(double*)ptr_data->_ptr); continue;
+          case Shader::SAT_vec2: cgSetParameter2dv(p,(double*)ptr_data->_ptr); continue;
+          case Shader::SAT_vec3: cgSetParameter3dv(p,(double*)ptr_data->_ptr); continue;
+          case Shader::SAT_vec4: cgSetParameter4dv(p,(double*)ptr_data->_ptr); continue;
+          }
+        case Shader::SAC_matrix: cgGLSetMatrixParameterdc(p,(double*)ptr_data->_ptr); continue;
+        case Shader::SAC_array: {
+          switch(_ptr._info._subclass) {
+          case Shader::SAC_scalar: 
+            cgGLSetParameterArray1d(p,0,_ptr._dim[0],(double*)ptr_data->_ptr); continue;
+          case Shader::SAC_vector:
+            switch(_ptr._dim[2]) {
+            case 1: cgGLSetParameterArray1d(p,0,_ptr._dim[0],(double*)ptr_data->_ptr); continue;
+            case 2: cgGLSetParameterArray2d(p,0,_ptr._dim[0],(double*)ptr_data->_ptr); continue;
+            case 3: cgGLSetParameterArray3d(p,0,_ptr._dim[0],(double*)ptr_data->_ptr); continue;
+            case 4: cgGLSetParameterArray4d(p,0,_ptr._dim[0],(double*)ptr_data->_ptr); continue;
+            }
+          case Shader::SAC_matrix:
+            cgGLSetMatrixParameterArraydc(p,0,_ptr._dim[0],(double*)ptr_data->_ptr); continue;
+          }
+        } 
+        }
+      default: GLCAT.error() << _ptr._id._name << ":" << "unrecognized parameter type\n"; 
+        release_resources(); 
+        return;
+      }
+    }
+  }
+
+  //FIXME: this could be much faster if we used deferred parameter setting.
+
+  for (int i=0; i<(int)_shader->_mat_spec.size(); i++) {
+    if (altered & (_shader->_mat_spec[i]._dep[0] | _shader->_mat_spec[i]._dep[1])) {
+      const LMatrix4 *val = _glgsg->fetch_specified_value(_shader->_mat_spec[i], altered);
+      if (!val) continue;
+#ifndef STDFLOAT_DOUBLE
+      // In this case, the data is already single-precision.
+      const PN_float32 *data = val->get_data();
+#else
+      // In this case, we have to convert it.
+      LMatrix4f valf = LCAST(PN_float32, *val);
+      const PN_float32 *data = valf.get_data();
+#endif
+
+      CGparameter p = _cg_parameter_map[_shader->_mat_spec[i]._id._seqno];
+      switch (_shader->_mat_spec[i]._piece) {
+      case Shader::SMP_whole: GLfc(cgGLSetMatrixParameter)(p, data); continue;
+      case Shader::SMP_transpose: GLfr(cgGLSetMatrixParameter)(p, data); continue;
+      case Shader::SMP_col0: GLf(cgGLSetParameter4)(p, data[0], data[4], data[ 8], data[12]); continue;
+      case Shader::SMP_col1: GLf(cgGLSetParameter4)(p, data[1], data[5], data[ 9], data[13]); continue;
+      case Shader::SMP_col2: GLf(cgGLSetParameter4)(p, data[2], data[6], data[10], data[14]); continue;
+      case Shader::SMP_col3: GLf(cgGLSetParameter4)(p, data[3], data[7], data[11], data[15]); continue;
+      case Shader::SMP_row0: GLfv(cgGLSetParameter4)(p, data+ 0); continue;
+      case Shader::SMP_row1: GLfv(cgGLSetParameter4)(p, data+ 4); continue;
+      case Shader::SMP_row2: GLfv(cgGLSetParameter4)(p, data+ 8); continue;
+      case Shader::SMP_row3: GLfv(cgGLSetParameter4)(p, data+12); continue;
+      case Shader::SMP_row3x1: GLfv(cgGLSetParameter1)(p, data+12); continue;
+      case Shader::SMP_row3x2: GLfv(cgGLSetParameter2)(p, data+12); continue;
+      case Shader::SMP_row3x3: GLfv(cgGLSetParameter3)(p, data+12); continue;
+      case Shader::SMP_upper3x3:
+        {
+          LMatrix3f upper3 = val->get_upper_3();
+          GLfc(cgGLSetMatrixParameter)(p, upper3.get_data());
+          continue;
+        }
+      case Shader::SMP_transpose3x3:
+        {
+          LMatrix3f upper3 = val->get_upper_3();
+          GLfr(cgGLSetMatrixParameter)(p, upper3.get_data());
+          continue;
+        }
+      }
+    }
+  }
+
+  _glgsg->report_my_gl_errors();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GLCgShaderContext::disable_shader_vertex_arrays
+//       Access: Public
+//  Description: Disable all the vertex arrays used by this shader.
+////////////////////////////////////////////////////////////////////
+void CLP(CgShaderContext)::
+disable_shader_vertex_arrays() {
+  if (!valid()) {
+    return;
+  }
+
+  for (int i=0; i<(int)_shader->_var_spec.size(); i++) {
+    CGparameter p = _cg_parameter_map[_shader->_var_spec[i]._id._seqno];
+    if (p == 0) continue;
+    cgGLDisableClientState(p);
+  }
+
+  cg_report_errors();
+  _glgsg->report_my_gl_errors();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GLCgShaderContext::update_shader_vertex_arrays
+//       Access: Public
+//  Description: Disables all vertex arrays used by the previous
+//               shader, then enables all the vertex arrays needed
+//               by this shader.  Extracts the relevant vertex array
+//               data from the gsg.
+//               The current implementation is inefficient, because
+//               it may unnecessarily disable arrays then immediately
+//               reenable them.  We may optimize this someday.
+////////////////////////////////////////////////////////////////////
+bool CLP(CgShaderContext)::
+update_shader_vertex_arrays(ShaderContext *prev, bool force) {
+  if (prev) prev->disable_shader_vertex_arrays();
+  if (!valid()) {
+    return true;
+  }
+  cg_report_errors();
+
+#ifdef SUPPORT_IMMEDIATE_MODE
+  if (_glgsg->_use_sender) {
+    GLCAT.error() << "immediate mode shaders not implemented yet\n";
+  } else
+#endif // SUPPORT_IMMEDIATE_MODE
+  {
+    const GeomVertexArrayDataHandle *array_reader;
+    Geom::NumericType numeric_type;
+    int start, stride, num_values;
+    int nvarying = _shader->_var_spec.size();
+    for (int i = 0; i < nvarying; ++i) {
+      if (_cg_parameter_map[_shader->_var_spec[i]._id._seqno] == 0) {
+        continue;
+      }
+
+      InternalName *name = _shader->_var_spec[i]._name;
+      int texslot = _shader->_var_spec[i]._append_uv;
+      if (texslot >= 0 && texslot < _glgsg->_state_texture->get_num_on_stages()) {
+        TextureStage *stage = _glgsg->_state_texture->get_on_stage(texslot);
+        InternalName *texname = stage->get_texcoord_name();
+
+        if (name == InternalName::get_texcoord()) {
+          name = texname;
+        } else if (texname != InternalName::get_texcoord()) {
+          name = name->append(texname->get_basename());
+        }
+      }
+      if (_glgsg->_data_reader->get_array_info(name,
+                                            array_reader, num_values, numeric_type,
+                                            start, stride)) {
+        const unsigned char *client_pointer;
+        if (!_glgsg->setup_array_data(client_pointer, array_reader, force)) {
+          return false;
+        }
+
+        CGparameter p = _cg_parameter_map[_shader->_var_spec[i]._id._seqno];
+        cgGLSetParameterPointer(p,
+                                num_values, _glgsg->get_numeric_type(numeric_type),
+                                stride, client_pointer + start);
+        cgGLEnableClientState(p);
+      } else  {
+        CGparameter p = _cg_parameter_map[_shader->_var_spec[i]._id._seqno];
+        cgGLDisableClientState(p);
+      }
+    }
+  }
+
+  cg_report_errors();
+  _glgsg->report_my_gl_errors();
+  
+  return true;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GLCgShaderContext::disable_shader_texture_bindings
+//       Access: Public
+//  Description: Disable all the texture bindings used by this shader.
+////////////////////////////////////////////////////////////////////
+void CLP(CgShaderContext)::
+disable_shader_texture_bindings() {
+  if (!valid()) {
+    return;
+  }
+
+#ifndef OPENGLES_2
+  for (int i=0; i<(int)_shader->_tex_spec.size(); i++) {
+    CGparameter p = _cg_parameter_map[_shader->_tex_spec[i]._id._seqno];
+    if (p == 0) continue;
+    int texunit = cgGetParameterResourceIndex(p);
+    _glgsg->_glActiveTexture(GL_TEXTURE0 + texunit);
+
+#ifndef OPENGLES
+    glBindTexture(GL_TEXTURE_1D, 0);
+#endif  // OPENGLES
+    glBindTexture(GL_TEXTURE_2D, 0);
+#ifndef OPENGLES_1
+    if (_glgsg->_supports_3d_texture) {
+      glBindTexture(GL_TEXTURE_3D, 0);
+    }
+#endif  // OPENGLES_1
+#ifndef OPENGLES
+    if (_glgsg->_supports_2d_texture_array) {
+      glBindTexture(GL_TEXTURE_2D_ARRAY_EXT, 0);
+    }
+#endif
+    if (_glgsg->_supports_cube_map) {
+      glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
+    }
+    // This is probably faster - but maybe not as safe?
+    // cgGLDisableTextureParameter(p);
+  }
+#endif  // OPENGLES_2
+  _stage_offset = 0;
+
+  cg_report_errors();
+  _glgsg->report_my_gl_errors();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GLCgShaderContext::update_shader_texture_bindings
+//       Access: Public
+//  Description: Disables all texture bindings used by the previous
+//               shader, then enables all the texture bindings needed
+//               by this shader.  Extracts the relevant vertex array
+//               data from the gsg.
+//               The current implementation is inefficient, because
+//               it may unnecessarily disable textures then immediately
+//               reenable them.  We may optimize this someday.
+////////////////////////////////////////////////////////////////////
+void CLP(CgShaderContext)::
+update_shader_texture_bindings(ShaderContext *prev) {
+  if (prev) {
+    prev->disable_shader_texture_bindings();
+  }
+
+  if (!valid()) {
+    return;
+  }
+
+  // We get the TextureAttrib directly from the _target_rs, not the
+  // filtered TextureAttrib in _target_texture.
+  const TextureAttrib *texattrib = DCAST(TextureAttrib, _glgsg->_target_rs->get_attrib_def(TextureAttrib::get_class_slot()));
+  nassertv(texattrib != (TextureAttrib *)NULL);
+  _stage_offset = texattrib->get_num_on_stages();
+
+  for (int i = 0; i < (int)_shader->_tex_spec.size(); ++i) {
+    InternalName *id = _shader->_tex_spec[i]._name;
+
+    CGparameter p = _cg_parameter_map[_shader->_tex_spec[i]._id._seqno];
+    if (p == 0) {
+      continue;
+    }
+    int texunit = cgGetParameterResourceIndex(p);
+
+    Texture *tex = 0;
+    int view = _glgsg->get_current_tex_view_offset();
+    if (id != 0) {
+      const ShaderInput *input = _glgsg->_target_shader->get_shader_input(id);
+      tex = input->get_texture();
+    } else {
+      if (_shader->_tex_spec[i]._stage >= texattrib->get_num_on_stages()) {
+        continue;
+      }
+      TextureStage *stage = texattrib->get_on_stage(_shader->_tex_spec[i]._stage);
+      tex = texattrib->get_on_texture(stage);
+      view += stage->get_tex_view_offset();
+    }
+    if (_shader->_tex_spec[i]._suffix != 0) {
+      // The suffix feature is inefficient. It is a temporary hack.
+      if (tex == 0) {
+        continue;
+      }
+      tex = tex->load_related(_shader->_tex_spec[i]._suffix);
+    }
+    if ((tex == 0) || (tex->get_texture_type() != _shader->_tex_spec[i]._desired_type)) {
+      continue;
+    }
+
+    _glgsg->_glActiveTexture(GL_TEXTURE0 + texunit);
+
+    TextureContext *tc = tex->prepare_now(view, _glgsg->_prepared_objects, _glgsg);
+    if (tc == (TextureContext*)NULL) {
+      continue;
+    }
+
+    GLenum target = _glgsg->get_texture_target(tex->get_texture_type());
+    if (target == GL_NONE) {
+      // Unsupported texture mode.
+      continue;
+    }
+
+    if (!_glgsg->update_texture(tc, false)) {
+      continue;
+    }
+  }
+
+  cg_report_errors();
+  _glgsg->report_my_gl_errors();
+}
+
+#endif  // OPENGLES_1

+ 92 - 0
panda/src/glstuff/glCgShaderContext_src.h

@@ -0,0 +1,92 @@
+// Filename: glShaderContext_src.h
+// Created by: jyelon (01Sep05)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) Carnegie Mellon University.  All rights reserved.
+//
+// All use of this software is subject to the terms of the revised BSD
+// license.  You should have received a copy of this license along
+// with this source code in a file named "LICENSE."
+//
+////////////////////////////////////////////////////////////////////
+
+#if defined(HAVE_CG) && !defined(OPENGLES)
+
+#include "pandabase.h"
+#include "string_utils.h"
+#include "internalName.h"
+#include "shader.h"
+#include "shaderContext.h"
+#include "deletedChain.h"
+
+#include <Cg/cg.h>
+
+class CLP(GraphicsStateGuardian);
+
+////////////////////////////////////////////////////////////////////
+//       Class : GLShaderContext
+// Description : xyz
+////////////////////////////////////////////////////////////////////
+class EXPCL_GL CLP(CgShaderContext) : public ShaderContext {
+public:
+  friend class CLP(GraphicsStateGuardian);
+
+  CLP(CgShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s);
+  ~CLP(CgShaderContext)();
+  ALLOC_DELETED_CHAIN(CLP(CgShaderContext));
+
+  INLINE bool valid(void);
+  void bind(bool reissue_parameters = true);
+  void unbind();
+  void issue_parameters(int altered);
+  void disable_shader_vertex_arrays();
+  bool update_shader_vertex_arrays(ShaderContext *prev, bool force);
+  void disable_shader_texture_bindings();
+  void update_shader_texture_bindings(ShaderContext *prev);
+
+  INLINE bool uses_standard_vertex_arrays(void);
+  INLINE bool uses_custom_vertex_arrays(void);
+  INLINE bool uses_custom_texture_bindings(void);
+
+private:
+  CGcontext _cg_context;
+  CGprogram _cg_vprogram;
+  CGprogram _cg_fprogram;
+  CGprogram _cg_gprogram;
+  CGprofile _cg_vprofile;
+  CGprofile _cg_fprofile;
+  CGprofile _cg_gprofile;
+
+  pvector <CGparameter> _cg_parameter_map;
+
+  int _stage_offset;
+  CLP(GraphicsStateGuardian) *_glgsg;
+
+  bool _uses_standard_vertex_arrays;
+
+  void release_resources();
+
+public:
+  static TypeHandle get_class_type() {
+    return _type_handle;
+  }
+  static void init_type() {
+    TypedObject::init_type();
+    register_type(_type_handle, CLASSPREFIX_QUOTED "CgShaderContext",
+                  TypedObject::get_class_type());
+  }
+  virtual TypeHandle get_type() const {
+    return get_class_type();
+  }
+  virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
+
+private:
+  static TypeHandle _type_handle;
+};
+
+#include "glCgShaderContext_src.I"
+
+#endif  // OPENGLES_1
+

+ 48 - 29
panda/src/glstuff/glGraphicsStateGuardian_src.cxx

@@ -2431,17 +2431,17 @@ end_frame(Thread *current_thread) {
 #ifndef OPENGLES_1
 #ifndef OPENGLES_1
   // This breaks shaders across multiple regions.
   // This breaks shaders across multiple regions.
   if (_vertex_array_shader_context != 0) {
   if (_vertex_array_shader_context != 0) {
-    _vertex_array_shader_context->disable_shader_vertex_arrays(this);
+    _vertex_array_shader_context->disable_shader_vertex_arrays();
     _vertex_array_shader = (Shader *)NULL;
     _vertex_array_shader = (Shader *)NULL;
     _vertex_array_shader_context = (CLP(ShaderContext) *)NULL;
     _vertex_array_shader_context = (CLP(ShaderContext) *)NULL;
   }
   }
   if (_texture_binding_shader_context != 0) {
   if (_texture_binding_shader_context != 0) {
-    _texture_binding_shader_context->disable_shader_texture_bindings(this);
+    _texture_binding_shader_context->disable_shader_texture_bindings();
     _texture_binding_shader = (Shader *)NULL;
     _texture_binding_shader = (Shader *)NULL;
     _texture_binding_shader_context = (CLP(ShaderContext) *)NULL;
     _texture_binding_shader_context = (CLP(ShaderContext) *)NULL;
   }
   }
   if (_current_shader_context != 0) {
   if (_current_shader_context != 0) {
-    _current_shader_context->unbind(this);
+    _current_shader_context->unbind();
     _current_shader = (Shader *)NULL;
     _current_shader = (Shader *)NULL;
     _current_shader_context = (CLP(ShaderContext) *)NULL;
     _current_shader_context = (CLP(ShaderContext) *)NULL;
   }
   }
@@ -2737,7 +2737,7 @@ begin_draw_primitives(const GeomPipelineReader *geom_reader,
   if (_current_shader_context == 0) {
   if (_current_shader_context == 0) {
     // No shader.
     // No shader.
     if (_vertex_array_shader_context != 0) {
     if (_vertex_array_shader_context != 0) {
-      _vertex_array_shader_context->disable_shader_vertex_arrays(this);
+      _vertex_array_shader_context->disable_shader_vertex_arrays();
     }
     }
     if (!update_standard_vertex_arrays(force)) {
     if (!update_standard_vertex_arrays(force)) {
       return false;
       return false;
@@ -2759,11 +2759,11 @@ begin_draw_primitives(const GeomPipelineReader *geom_reader,
     if (_current_shader_context->uses_custom_vertex_arrays()) {
     if (_current_shader_context->uses_custom_vertex_arrays()) {
       // The current shader also uses custom vertex arrays.
       // The current shader also uses custom vertex arrays.
       if (!_current_shader_context->
       if (!_current_shader_context->
-          update_shader_vertex_arrays(_vertex_array_shader_context, this, force)) {
+          update_shader_vertex_arrays(_vertex_array_shader_context, force)) {
         return false;
         return false;
       }
       }
     } else {
     } else {
-      _vertex_array_shader_context->disable_shader_vertex_arrays(this);
+      _vertex_array_shader_context->disable_shader_vertex_arrays();
     }
     }
   }
   }
 
 
@@ -3834,29 +3834,48 @@ release_geom(GeomContext *gc) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: GLGraphicsStateGuardian::prepare_shader
 //     Function: GLGraphicsStateGuardian::prepare_shader
 //       Access: Public, Virtual
 //       Access: Public, Virtual
-//  Description: yadda.
+//  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 ShaderContext *CLP(GraphicsStateGuardian)::
 ShaderContext *CLP(GraphicsStateGuardian)::
 prepare_shader(Shader *se) {
 prepare_shader(Shader *se) {
 #ifndef OPENGLES_1
 #ifndef OPENGLES_1
-  CLP(ShaderContext) *result = new CLP(ShaderContext)(se, this);
-  if (result->valid()) return result;
-  delete result;
+  ShaderContext *result = NULL;
+
+  switch (se->get_language()) {
+  case Shader::SL_GLSL:
+    result = new CLP(ShaderContext)(this, se);
+    break;
+
+#if defined(HAVE_CG) && !defined(OPENGLES)
+  case Shader::SL_Cg:
+    result = new CLP(CgShaderContext)(this, se);
+    break;
 #endif
 #endif
+
+  default:
+    GLCAT.error()
+      << "Tried to load shader with unsupported shader language!\n";
+    return NULL;
+  }
+
+  if (result->valid()) {
+    return result;
+  }
+
+  delete result;
+#endif  // OPENGLES_1
+
   return NULL;
   return NULL;
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: GLGraphicsStateGuardian::release_shader
 //     Function: GLGraphicsStateGuardian::release_shader
 //       Access: Public, Virtual
 //       Access: Public, Virtual
-//  Description: yadda.
+//  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void CLP(GraphicsStateGuardian)::
 void CLP(GraphicsStateGuardian)::
 release_shader(ShaderContext *sc) {
 release_shader(ShaderContext *sc) {
-#ifndef OPENGLES_1
-  CLP(ShaderContext) *gsc = DCAST(CLP(ShaderContext), sc);
-  delete gsc;
-#endif
+  delete sc;
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -4807,7 +4826,7 @@ do_issue_transform() {
 
 
 #ifndef OPENGLES_1
 #ifndef OPENGLES_1
   if (_current_shader_context) {
   if (_current_shader_context) {
-    _current_shader_context->issue_parameters(this, Shader::SSD_transform);
+    _current_shader_context->issue_parameters(Shader::SSD_transform);
   }
   }
 #endif
 #endif
 
 
@@ -4868,7 +4887,7 @@ do_issue_shader(bool state_has_changed) {
   
   
   if (context == 0 || (context->valid() == false)) {
   if (context == 0 || (context->valid() == false)) {
     if (_current_shader_context != 0) {
     if (_current_shader_context != 0) {
-      _current_shader_context->unbind(this);
+      _current_shader_context->unbind();
       _current_shader = 0;
       _current_shader = 0;
       _current_shader_context = 0;
       _current_shader_context = 0;
     }
     }
@@ -4877,19 +4896,19 @@ do_issue_shader(bool state_has_changed) {
       // Use a completely different shader than before.
       // Use a completely different shader than before.
       // Unbind old shader, bind the new one.
       // Unbind old shader, bind the new one.
       if (_current_shader_context != 0) {
       if (_current_shader_context != 0) {
-        _current_shader_context->unbind(this);
+        _current_shader_context->unbind();
       }
       }
-      context->bind(this);
+      context->bind();
       _current_shader = shader;
       _current_shader = shader;
       _current_shader_context = context;
       _current_shader_context = context;
-      context->issue_parameters(this, Shader::SSD_shaderinputs);
+      context->issue_parameters(Shader::SSD_shaderinputs);
     } else {
     } else {
 #ifdef OPENGLES_2
 #ifdef OPENGLES_2
-      context->bind(this, false);
+      context->bind(false);
 #endif
 #endif
       if (state_has_changed) {
       if (state_has_changed) {
         // Use the same shader as before, but with new input arguments.
         // Use the same shader as before, but with new input arguments.
-        context->issue_parameters(this, Shader::SSD_shaderinputs);
+        context->issue_parameters(Shader::SSD_shaderinputs);
       }
       }
     }
     }
   }
   }
@@ -7856,8 +7875,8 @@ set_state_and_transform(const RenderState *target,
     _state_mask.set_bit(color_scale_slot);
     _state_mask.set_bit(color_scale_slot);
 #ifndef OPENGLES_1
 #ifndef OPENGLES_1
     if (_current_shader_context) {
     if (_current_shader_context) {
-      _current_shader_context->issue_parameters(this, Shader::SSD_color);
-      _current_shader_context->issue_parameters(this, Shader::SSD_colorscale);
+      _current_shader_context->issue_parameters(Shader::SSD_color);
+      _current_shader_context->issue_parameters(Shader::SSD_colorscale);
     }
     }
 #endif
 #endif
   }
   }
@@ -8008,7 +8027,7 @@ set_state_and_transform(const RenderState *target,
     _state_mask.set_bit(material_slot);
     _state_mask.set_bit(material_slot);
 #ifndef OPENGLES_1
 #ifndef OPENGLES_1
     if (_current_shader_context) {
     if (_current_shader_context) {
-      _current_shader_context->issue_parameters(this, Shader::SSD_material);
+      _current_shader_context->issue_parameters(Shader::SSD_material);
     }
     }
 #endif
 #endif
   }
   }
@@ -8037,7 +8056,7 @@ set_state_and_transform(const RenderState *target,
     _state_mask.set_bit(fog_slot);
     _state_mask.set_bit(fog_slot);
 #ifndef OPENGLES_1
 #ifndef OPENGLES_1
     if (_current_shader_context) {
     if (_current_shader_context) {
-      _current_shader_context->issue_parameters(this, Shader::SSD_fog);
+      _current_shader_context->issue_parameters(Shader::SSD_fog);
     }
     }
 #endif
 #endif
   }
   }
@@ -8136,16 +8155,16 @@ do_issue_texture() {
   if (_current_shader_context == 0 || !_current_shader_context->uses_custom_texture_bindings()) {
   if (_current_shader_context == 0 || !_current_shader_context->uses_custom_texture_bindings()) {
     // No shader, or a non-Cg shader.
     // No shader, or a non-Cg shader.
     if (_texture_binding_shader_context != 0) {
     if (_texture_binding_shader_context != 0) {
-      _texture_binding_shader_context->disable_shader_texture_bindings(this);
+      _texture_binding_shader_context->disable_shader_texture_bindings();
     }
     }
     update_standard_texture_bindings();
     update_standard_texture_bindings();
   } else {
   } else {
     if (_texture_binding_shader_context == 0) {
     if (_texture_binding_shader_context == 0) {
       disable_standard_texture_bindings();
       disable_standard_texture_bindings();
-      _current_shader_context->update_shader_texture_bindings(NULL,this);
+      _current_shader_context->update_shader_texture_bindings(NULL);
     } else {
     } else {
       _current_shader_context->
       _current_shader_context->
-        update_shader_texture_bindings(_texture_binding_shader_context,this);
+        update_shader_texture_bindings(_texture_binding_shader_context);
     }
     }
   }
   }
 
 

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

@@ -775,6 +775,7 @@ private:
   friend class CLP(VertexBufferContext);
   friend class CLP(VertexBufferContext);
   friend class CLP(IndexBufferContext);
   friend class CLP(IndexBufferContext);
   friend class CLP(ShaderContext);
   friend class CLP(ShaderContext);
+  friend class CLP(CgShaderContext);
   friend class CLP(GraphicsBuffer);
   friend class CLP(GraphicsBuffer);
   friend class CLP(OcclusionQueryContext);
   friend class CLP(OcclusionQueryContext);
 };
 };

+ 4 - 9
panda/src/glstuff/glShaderContext_src.I

@@ -12,7 +12,6 @@
 //
 //
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 
 
-#ifndef OPENGLES_1
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: GLShaderContext::valid
 //     Function: GLShaderContext::valid
@@ -26,11 +25,10 @@
 INLINE bool CLP(ShaderContext)::
 INLINE bool CLP(ShaderContext)::
 valid() {
 valid() {
   if (_shader->get_error_flag()) return false;
   if (_shader->get_error_flag()) return false;
-  if (_shader->get_language() == Shader::SL_none) return false;
-#if defined(HAVE_CG) && !defined(OPENGLES)
-  if (_cg_context) return true;
-#endif
-  if (_shader->get_language() == Shader::SL_GLSL && _glsl_program != 0) {
+  if (_shader->get_language() != Shader::SL_GLSL) {
+    return false;
+  }
+  if (_glsl_program != 0) {
     return true;
     return true;
   }
   }
   return false;
   return false;
@@ -67,6 +65,3 @@ INLINE bool CLP(ShaderContext)::
 uses_custom_texture_bindings() {
 uses_custom_texture_bindings() {
   return true;
   return true;
 }
 }
-
-#endif  // OPENGLES_1
-

File diff suppressed because it is too large
+ 383 - 562
panda/src/glstuff/glShaderContext_src.cxx


+ 15 - 37
panda/src/glstuff/glShaderContext_src.h

@@ -21,53 +21,34 @@
 #include "shaderContext.h"
 #include "shaderContext.h"
 #include "deletedChain.h"
 #include "deletedChain.h"
 
 
-#if defined(HAVE_CG) && !defined(OPENGLES)
-#include <Cg/cg.h>
-#endif
-
 class CLP(GraphicsStateGuardian);
 class CLP(GraphicsStateGuardian);
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //       Class : GLShaderContext
 //       Class : GLShaderContext
 // Description : xyz
 // Description : xyz
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-class EXPCL_GL CLP(ShaderContext): public ShaderContext {
+class EXPCL_GL CLP(ShaderContext) : public ShaderContext {
 public:
 public:
   friend class CLP(GraphicsStateGuardian);
   friend class CLP(GraphicsStateGuardian);
-  typedef CLP(GraphicsStateGuardian) GSG;
 
 
-  CLP(ShaderContext)(Shader *s, GSG *gsg);
+  CLP(ShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s);
   ~CLP(ShaderContext)();
   ~CLP(ShaderContext)();
   ALLOC_DELETED_CHAIN(CLP(ShaderContext));
   ALLOC_DELETED_CHAIN(CLP(ShaderContext));
 
 
   INLINE bool valid(void);
   INLINE bool valid(void);
-  void bind(GSG *gsg, bool reissue_parameters = true);
-  void unbind(GSG *gsg);
-  void issue_parameters(GSG *gsg, int altered);
-  void disable_shader_vertex_arrays(GSG *gsg);
-  bool update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg,
-                                   bool force);
-  void disable_shader_texture_bindings(GSG *gsg);
-  void update_shader_texture_bindings(CLP(ShaderContext) *prev, GSG *gsg);
+  void bind(bool reissue_parameters = true);
+  void unbind();
+  void issue_parameters(int altered);
+  void disable_shader_vertex_arrays();
+  bool update_shader_vertex_arrays(ShaderContext *prev, bool force);
+  void disable_shader_texture_bindings();
+  void update_shader_texture_bindings(ShaderContext *prev);
 
 
   INLINE bool uses_standard_vertex_arrays(void);
   INLINE bool uses_standard_vertex_arrays(void);
   INLINE bool uses_custom_vertex_arrays(void);
   INLINE bool uses_custom_vertex_arrays(void);
   INLINE bool uses_custom_texture_bindings(void);
   INLINE bool uses_custom_texture_bindings(void);
 
 
 private:
 private:
-
-#if defined(HAVE_CG) && !defined(OPENGLES)
-  CGcontext _cg_context;
-  CGprogram _cg_vprogram;
-  CGprogram _cg_fprogram;
-  CGprogram _cg_gprogram;
-  CGprofile _cg_vprofile;
-  CGprofile _cg_fprofile;
-  CGprofile _cg_gprofile;
-
-  pvector <CGparameter> _cg_parameter_map;
-#endif
-
   GLuint _glsl_program;
   GLuint _glsl_program;
   GLuint _glsl_vshader;
   GLuint _glsl_vshader;
   GLuint _glsl_fshader;
   GLuint _glsl_fshader;
@@ -81,18 +62,16 @@ private:
   pvector<CPT(InternalName)> _glsl_img_inputs;
   pvector<CPT(InternalName)> _glsl_img_inputs;
 
 
   int _stage_offset;
   int _stage_offset;
-  // Avoid using this! It merely exists so the
-  // destructor has access to the extension functions.
-  WPT(GSG) _last_gsg;
+  CLP(GraphicsStateGuardian) *_glgsg;
 
 
   bool _uses_standard_vertex_arrays;
   bool _uses_standard_vertex_arrays;
 
 
-  void glsl_report_shader_errors(GSG *gsg, unsigned int shader);
-  void glsl_report_program_errors(GSG *gsg, unsigned int program);
-  unsigned int glsl_compile_entry_point(GSG *gsg, Shader::ShaderType type);
-  bool glsl_compile_shader(GSG *gsg);
+  void glsl_report_shader_errors(unsigned int shader);
+  void glsl_report_program_errors(unsigned int program);
+  unsigned int glsl_compile_entry_point(Shader::ShaderType type);
+  bool glsl_compile_shader();
   bool parse_and_set_short_hand_shader_vars(Shader::ShaderArgId &arg_id, Shader *s);
   bool parse_and_set_short_hand_shader_vars(Shader::ShaderArgId &arg_id, Shader *s);
-  void release_resources(GSG *gsg);
+  void release_resources();
 
 
 public:
 public:
   static TypeHandle get_class_type() {
   static TypeHandle get_class_type() {
@@ -115,4 +94,3 @@ private:
 #include "glShaderContext_src.I"
 #include "glShaderContext_src.I"
 
 
 #endif  // OPENGLES_1
 #endif  // OPENGLES_1
-

+ 1 - 2
panda/src/glstuff/glstuff_src.cxx

@@ -25,8 +25,7 @@
 #include "glGeomContext_src.cxx"
 #include "glGeomContext_src.cxx"
 #include "glGeomMunger_src.cxx"
 #include "glGeomMunger_src.cxx"
 #include "glShaderContext_src.cxx"
 #include "glShaderContext_src.cxx"
+#include "glCgShaderContext_src.cxx"
 #include "glImmediateModeSender_src.cxx"
 #include "glImmediateModeSender_src.cxx"
 #include "glGraphicsBuffer_src.cxx"
 #include "glGraphicsBuffer_src.cxx"
 #include "glGraphicsStateGuardian_src.cxx"
 #include "glGraphicsStateGuardian_src.cxx"
-
-

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

@@ -39,6 +39,7 @@
 #include "glGeomContext_src.h"
 #include "glGeomContext_src.h"
 #include "glGeomMunger_src.h"
 #include "glGeomMunger_src.h"
 #include "glShaderContext_src.h"
 #include "glShaderContext_src.h"
+#include "glCgShaderContext_src.h"
 #include "glImmediateModeSender_src.h"
 #include "glImmediateModeSender_src.h"
 #include "glGraphicsBuffer_src.h"
 #include "glGraphicsBuffer_src.h"
 #include "glGraphicsStateGuardian_src.h"
 #include "glGraphicsStateGuardian_src.h"

+ 14 - 1
panda/src/gobj/shaderContext.h

@@ -36,10 +36,23 @@ class EXPCL_PANDA_GOBJ ShaderContext: public SavedContext {
 public:
 public:
   INLINE ShaderContext(Shader *se);
   INLINE ShaderContext(Shader *se);
 
 
+  INLINE virtual bool valid() { return false; }
+  INLINE virtual void bind(bool reissue_parameters = true) {};
+  INLINE virtual void unbind() {};
+  INLINE virtual void issue_parameters(int altered) {};
+  INLINE virtual void disable_shader_vertex_arrays() {};
+  INLINE virtual bool update_shader_vertex_arrays(ShaderContext *prev, bool force) { return false; };
+  INLINE virtual void disable_shader_texture_bindings() {};
+  INLINE virtual void update_shader_texture_bindings(ShaderContext *prev) {};
+
+  INLINE virtual bool uses_standard_vertex_arrays(void) { return true; };
+  INLINE virtual bool uses_custom_vertex_arrays(void) { return false; };
+  INLINE virtual bool uses_custom_texture_bindings(void) { return false; };
+
 PUBLISHED:
 PUBLISHED:
   INLINE Shader *get_shader() const;
   INLINE Shader *get_shader() const;
 
 
-public:  
+public:
   Shader *_shader;
   Shader *_shader;
 
 
 public:
 public:

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