home *** CD-ROM | disk | FTP | other *** search
- //
- // The Inventor 2.0 texture code can cause other classes to be
- // incorrectly deleted, leading to core dumps (a core dump in the
- // cache element class is an example). This code, taken directly from
- // the Inventor source for all Inventor releases after 2.0, corrects
- // the problem.
- //
- // To apply this patch, compile this file into a .o and then link
- // the .o before -lInventor. The linker will give a warning about
- // multiply defined symbols; that is normal and expected.
- //
-
- #include <GL/glu.h>
- #include <GL/gl.h>
- #include <Inventor/elements/SoCacheElement.h>
- #include <Inventor/elements/SoGLTextureEnabledElement.h>
- #include <Inventor/elements/SoGLTextureImageElement.h>
- #include <Inventor/elements/SoGLTextureQualityElement.h>
- #include <Inventor/errors/SoDebugError.h>
- #include <Inventor/misc/SoState.h>
-
- ////////////////////////////////////////////////////////////////////////
- //
- // Description:
- // Does the right GL stuff. This takes a GL display list that can
- // be used to render the texture; if -1 is passed in as the display
- // list, this will try to build a display list (if there are none
- // already open) and returns the display list, which must be freed
- // by the node that sets this element.
- //
- // Use: public, static
-
- int
- SoGLTextureImageElement::set(SoState *state, SoNode *node,
- const SbVec2s &size, int nc,
- const unsigned char *b,
- int dl)
- //
- ////////////////////////////////////////////////////////////////////////
- {
- SoGLTextureImageElement *elt;
-
- if (size[0] == 0 || size[1] == 0 || nc == 0) {
- // Disable texturing
- SoGLTextureEnabledElement::set(state, FALSE);
- return -1;
- }
-
- // Enable texturing IF textureQuality is > 0:
- // Note: the texture must still be sent to GL, because the
- // textureQuality may change (if it does, the texture quality
- // element enables texturing).
- if (SoGLTextureQualityElement::get(state) > 0) {
- SoGLTextureEnabledElement::set(state, TRUE);
- }
-
- // Get an instance we can change (pushing if necessary)
- elt = (SoGLTextureImageElement *) getElement(state, classStackIndex, node);
-
- if (elt != NULL) {
- elt->SoTextureImageElement::setElt(size, nc, b);
-
- elt->displayList = dl;
- elt->send(state);
- return elt->displayList;
- }
- return -1;
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // Description:
- // Sends down a 2D texture. Builds or uses a display list, if it
- // can.
- //
- // Use: private
-
- void
- SoGLTextureImageElement::send(SoState *state)
- //
- ////////////////////////////////////////////////////////////////////////
- {
- if (displayList != -1) {
- // use display list
- glCallList(displayList);
- return;
- }
-
- SbBool buildList = !SoCacheElement::anyOpen(state);
- if (buildList) {
- displayList = glGenLists(1);
- glNewList(displayList, GL_COMPILE_AND_EXECUTE);
- }
-
- // Optimization; don't change the default UNPACK_ALIGNMENT if the
- // texture's width happens to work out to a multiple of 4:
- if ((size[0]*numComponents)%4 != 0)
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // Not default
-
- // Set all pixel transfer modes. Not only does this guarantee that
- // they are set correctly, but OpenGL implementations may be
- // better able to optimize display lists if all of these commands
- // are in the list.
- glPixelTransferf(GL_RED_SCALE, 1.0); // Default
- glPixelTransferf(GL_GREEN_SCALE, 1.0); // Default
- glPixelTransferf(GL_BLUE_SCALE, 1.0); // Default
- glPixelTransferf(GL_ALPHA_SCALE, 1.0); // Default
- glPixelTransferf(GL_RED_BIAS, 0.0); // Default
- glPixelTransferf(GL_GREEN_BIAS, 0.0); // Default
- glPixelTransferf(GL_BLUE_BIAS, 0.0); // Default
- glPixelTransferf(GL_ALPHA_BIAS, 0.0); // Default
-
-
- int format;
- if (numComponents == 1) format = GL_LUMINANCE;
- else if (numComponents == 2) format = GL_LUMINANCE_ALPHA;
- else if (numComponents == 3) format = GL_RGB;
- else if (numComponents == 4) format = GL_RGBA;
-
- gluBuild2DMipmaps(GL_TEXTURE_2D, numComponents,
- size[0], size[1], format, GL_UNSIGNED_BYTE,
- (const void *)bytes);
- if ((size[0]*numComponents)%4 != 0)
- glPixelStorei(GL_UNPACK_ALIGNMENT, 4); // Reset to default
-
- if (buildList) {
- glEndList();
- }
- }
-