void
SoGLMultiTextureImageElement::updateGL(const int unit)
{
  const GLUnitData & glud = 
    (unit < PRIVATE(this)->unitdata.getLength()) ? 
    PRIVATE(this)->unitdata[unit] :
    PRIVATE(this)->defaultdata;
  
  if (glud.glimage) {
    const cc_glglue * glue = cc_glglue_instance(PRIVATE(this)->cachecontext);
    cc_glglue_glActiveTexture(glue, (GLenum) (int(GL_TEXTURE0) + unit));

    const UnitData & ud = this->getUnitData(unit);
    SoState * state = PRIVATE(this)->state;
    SoGLDisplayList * dl = glud.glimage->getGLDisplayList(state);

    // tag image (for GLImage LRU cache).
    SoGLImage::tagImage(state, glud.glimage);

    if (SoTextureCombineElement::isDefault(state, unit)) {
      switch (ud.model) {
      case DECAL:
        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
        break;
      case MODULATE:
        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
        break;
      case BLEND:
        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);
        glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, ud.blendColor.getValue());
        break;
      case REPLACE:
        // GL_REPLACE mode was introduced with OpenGL 1.1. It is
        // considered the client code's responsibility to check
        // that it can use this mode.
        //
        // FIXME: ..but we should do a sanity check anyway.
        // 20030901 mortene.
        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
        break;
      default:
        assert(0 && "unknown model");
        break;
      }
    }
    else {
      SoTextureCombineElement::apply(state, unit);
    }
    if (dl) {
      dl->call(state);
    }
    cc_glglue_glActiveTexture(glue, (GLenum) GL_TEXTURE0);
  }
}
示例#2
0
SoGLDisplayList *
SoGLCubeMapImage::getGLDisplayList(SoState * state)
{
  PRIVATE(this)->lock();
  SoGLDisplayList * dl = PRIVATE(this)->findDL(state);
  if (!dl) {
    dl = new SoGLDisplayList(state,
                             SoGLDisplayList::TEXTURE_OBJECT);
    if (dl) {
      dl->ref();
      dl->setTextureTarget((int) GL_TEXTURE_CUBE_MAP);

      dl->open(state);

      for (int i = 0; i < 6; i++) {
        const SbImage * img = &PRIVATE(this)->image[i];
        if (img && img->hasData()) {
          SbVec2s size;
          int numcomponents;
          unsigned char * bytes = img->getValue(size, numcomponents);
          GLenum format;
          switch (numcomponents) {
          default: // avoid compiler warnings
          case 1: format = GL_LUMINANCE; break;
          case 2: format = GL_LUMINANCE_ALPHA; break;
          case 3: format = GL_RGB; break;
          case 4: format = GL_RGBA; break;
          }

          // FIXME: resize image if not power of two
          glTexImage2D(get_gltarget((Target) i),
                       0, numcomponents, size[0], size[1], 0,
                       format, GL_UNSIGNED_BYTE, bytes);

        }
      }

      // FIXME: make it possible to configure filter and mipmap on/off
      glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
      glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
      // FIXME: make it possible to configure wrap modes
      glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
      glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
      glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
      dl->close(state);
      PRIVATE(this)->dlists.append(SoGLCubeMapImageP::dldata(dl));
    }
  }
  PRIVATE(this)->unlock();
  return dl;
}