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); } }
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; }