Exemple #1
0
// Doc in parent
void
SoVRMLGroup::GLRenderBelowPath(SoGLRenderAction * action)
{
  SoState * state = action->getState();
  state->push();
  SbBool didcull = FALSE;
  SoGLCacheList * createcache = NULL;
  if ((this->renderCaching.getValue() != OFF) && 
      (SoVRMLGroup::getNumRenderCaches() > 0)) {
    if (!state->isCacheOpen()) {
      didcull = TRUE;
      if (this->cullTest(state)) {
        // we're outside the view frustum
        state->pop();
        return;
      }
    }
    
    PRIVATE(this)->lock();
    SoGLCacheList * glcachelist = PRIVATE(this)->getGLCacheList(TRUE);
    PRIVATE(this)->unlock();
    if (glcachelist->call(action)) {
#if GLCACHE_DEBUG && 1 // debug
      SoDebugError::postInfo("SoVRMLGroup::GLRenderBelowPath",
                             "Executing GL cache: %p", this);
#endif // debug
      state->pop();
      return;
    }
    if (!SoCacheElement::anyOpen(state)) {
#if GLCACHE_DEBUG // debug
      SoDebugError::postInfo("SoVRMLGroup::GLRenderBelowPath",
                             "Creating GL cache: %p", this);
#endif // debug
      createcache = glcachelist;
    }
  }

  if (createcache) createcache->open(action);
  
  SbBool outsidefrustum = (createcache || state->isCacheOpen() || didcull) ? 
    FALSE : this->cullTest(state);
  
  if (createcache || !outsidefrustum) {
    int n = this->getChildren()->getLength();
    SoNode ** childarray = (SoNode**) this->getChildren()->getArrayPtr();
    action->pushCurPath();
    for (int i = 0; i < n && !action->hasTerminated(); i++) {
      action->popPushCurPath(i, childarray[i]);
      if (action->abortNow()) {
        // only cache if we do a full traversal
        SoCacheElement::invalidate(state);
        break;
      }
      SoNodeProfiling profiling;
      profiling.preTraversal(action);
      childarray[i]->GLRenderBelowPath(action);
      profiling.postTraversal(action);

#if COIN_DEBUG
      // The GL error test is default disabled for this optimized
      // path.  If you get a GL error reporting an error in the
      // Separator node, enable this code by setting the environment
      // variable COIN_GLERROR_DEBUGGING to "1" to see exactly which
      // node caused the error.
      static SbBool chkglerr = sogl_glerror_debugging();
      if (chkglerr) {
        cc_string str;
        cc_string_construct(&str);
        const unsigned int errs = coin_catch_gl_errors(&str);
        if (errs > 0) {
          SoDebugError::post("SoVRMLGroup::GLRenderBelowPath",
                             "glGetError()s => '%s', nodetype: '%s'",
                             cc_string_get_text(&str),
                             (*this->getChildren())[i]->getTypeId().getName().getString());
        }
        cc_string_clean(&str);
      }
#endif // COIN_DEBUG
    }
    action->popCurPath();
  }
  state->pop();
  if (createcache) {
    createcache->close(action);
  }
}
// Documented in superclass.
void
SoSceneTextureCubeMap::GLRender(SoGLRenderAction * action)
{
  SoState * state = action->getState();

  if (SoTextureOverrideElement::getImageOverride(state))
    return;

  float quality = SoTextureQualityElement::get(state);

  const cc_glglue * glue = cc_glglue_instance(SoGLCacheContextElement::get(state));
  SoNode * root = this->scene.getValue();

  LOCK_GLIMAGE(this);

  if (root && (!PRIVATE(this)->glimagevalid || !PRIVATE(this)->pbuffervalid)) {
    PRIVATE(this)->updatePBuffer(state, quality);
    
    // don't cache when we change the glimage
    SoCacheElement::setInvalid(TRUE);
    if (state->isCacheOpen()) {
      SoCacheElement::invalidate(state);
    }
  }  
  UNLOCK_GLIMAGE(this);
  
  SoMultiTextureImageElement::Model glmodel = (SoMultiTextureImageElement::Model) 
    this->model.getValue();
  
  if (glmodel == SoMultiTextureImageElement::REPLACE) {
    if (!cc_glglue_glversion_matches_at_least(glue, 1, 1, 0)) {
      static int didwarn = 0;
      if (!didwarn) {
        SoDebugError::postWarning("SoSceneTextureCubeMap::GLRender",
                                  "Unable to use the GL_REPLACE texture model. "
                                  "Your OpenGL version is < 1.1. "
                                  "Using GL_MODULATE instead.");
        didwarn = 1;
      }
      // use MODULATE and not DECAL, since DECAL only works for RGB
      // and RGBA textures
      glmodel = SoMultiTextureImageElement::MODULATE;
    }
  }
  
  int unit = SoTextureUnitElement::get(state);
  int maxunits = cc_glglue_max_texture_units(glue);
  if (unit < maxunits) {
    SoGLMultiTextureImageElement::set(state, this, unit,
                                      PRIVATE(this)->glimage,
                                      glmodel,
                                      this->blendColor.getValue());
    if (quality > 0.0f && PRIVATE(this)->glimagevalid) {
      SoGLMultiTextureEnabledElement::enableCubeMap(state, this, unit);
    }
  }
  else {
    // we already warned in SoTextureUnit. I think it's best to just
    // ignore the texture here so that all texture for non-supported
    // units will be ignored. pederb, 2003-11-04
  }
}