home *** CD-ROM | disk | FTP | other *** search
- //
- // This is a patch for the Inventor 2.0 SoTexture2 node, which will
- // use incorrect display lists when rendering to another gl rendering
- // context (most commonly done when rendering to an
- // SoOffScreenRenderer for printing).
- //
- //
- // To apply this patch, compile this file into a .o and then link
- // the .o before -lInventor. The linker may give a warning.
- // This is normal and expected.
- //
-
- #include <Inventor/actions/SoGLRenderAction.h>
- #include <Inventor/elements/SoGLCacheContextElement.h>
- #include <Inventor/elements/SoGLTextureBlendColorElement.h>
- #include <Inventor/elements/SoGLTextureEnabledElement.h>
- #include <Inventor/elements/SoGLTextureImageElement.h>
- #include <Inventor/elements/SoGLTextureModelElement.h>
- #include <Inventor/elements/SoGLTextureQualityElement.h>
- #include <Inventor/elements/SoGLTextureWrapSElement.h>
- #include <Inventor/elements/SoGLTextureWrapTElement.h>
- #include <Inventor/elements/SoTextureBlendColorElement.h>
- #include <Inventor/elements/SoTextureModelElement.h>
- #include <Inventor/elements/SoTextureWrapSElement.h>
- #include <Inventor/elements/SoTextureWrapTElement.h>
- #include <Inventor/errors/SoDebugError.h>
- #include <Inventor/nodes/SoTexture2.h>
-
- ////////////////////////////////////////////////////////////////////////
- //
- // Description:
- // Performs GL rendering on a texture node.
- //
- // Use: extender
-
- void
- SoTexture2::GLRender(SoGLRenderAction *action)
- //
- ////////////////////////////////////////////////////////////////////////
- {
- SoState *state = action->getState();
-
- if (! wrapS.isIgnored())
- SoTextureWrapSElement::set(state, this,
- (SoTextureWrapSElement::Wrap)wrapS.getValue());
-
- if (! wrapT.isIgnored())
- SoTextureWrapTElement::set(state, this,
- (SoTextureWrapTElement::Wrap)wrapT.getValue());
-
- if (! model.isIgnored())
- SoTextureModelElement::set(state, this,
- (SoTextureModelElement::Model)model.getValue());
-
- if (! blendColor.isIgnored())
- SoTextureBlendColorElement::set(state, this,
- blendColor.getValue());
- if (! image.isIgnored()) {
- SbVec2s size;
- int nc;
- const unsigned char *bytes = image.getValue(size, nc);
-
- // Check for special cases of 1/2 component texture and model
- // DECAL or 3/4 component texture and model BLEND; print out
- // errors in these cases:
-
- SoTextureModelElement::Model m =
- SoTextureModelElement::get(state);
- if (nc < 3 && m == SoTextureModelElement::DECAL) {
- #ifdef DEBUG
- SoDebugError::post("SoTexture2::GLRender",
- "Texture model is DECAL, but texture image"
- " has only %d components (must be 3 or 4). "
- "Use imgcopy to convert the image.", nc);
- #endif
- }
- else if (nc > 2 && m == SoTextureModelElement::BLEND) {
- #ifdef DEBUG
- SoDebugError::post("SoTexture2::GLRender",
- "Texture model is BLEND, but texture image"
- " has %d components (must be 1 or 2). "
- "Use imgcopy to convert the image.", nc);
- #endif
- } else {
- // This is kind of weird-- the element builds and uses the
- // display list (which is why we pass it in and assign
- // it) because it sends the GL calls, and needs to know
- // the list if the state is popped. But this node must
- // manage storage and deletion of the display list, since
- // the list must go away if the node is deleted or the
- // image is changed.
-
- // See if renderList is valid (in the right context):
- int context = SoGLCacheContextElement::get(state);
- if (renderList != -1 && listContext == context) {
- SoGLTextureImageElement::set(
- state, this, size, nc, bytes, renderList);
- }
- else { // Not valid, try to build
- // Free up old list, if necessary:
- if (renderList != -1) {
- SoGLCacheContextElement::freeList(state, listContext,
- renderList, 1);
- }
- renderList = SoGLTextureImageElement::set(
- state, this, size, nc, bytes, -1);
- listContext = context;
- }
- }
- }
- }
-