// // Vrml 97 library // Copyright (C) 1998 Chris Morley // // %W% %G% // VrmlNodePixelTexture.cpp #include "VrmlNodePixelTexture.h" #include "VrmlNodeType.h" #include "VrmlScene.h" static VrmlNode *creator( VrmlScene *s ) { return new VrmlNodePixelTexture(s); } VrmlNodePixelTexture* VrmlNodePixelTexture::toPixelTexture() const { return (VrmlNodePixelTexture*) this; } // Define the built in VrmlNodeType:: "PixelTexture" fields VrmlNodeType *VrmlNodePixelTexture::defineType(VrmlNodeType *t) { static VrmlNodeType *st = 0; if (! t) { if (st) return st; t = st = new VrmlNodeType("PixelTexture", creator); } VrmlNodeTexture::defineType(t); // Parent class t->addExposedField("image", VrmlField::SFIMAGE); t->addField("repeatS", VrmlField::SFBOOL); t->addField("repeatT", VrmlField::SFBOOL); return t; } VrmlNodeType *VrmlNodePixelTexture::nodeType() const { return defineType(0); } VrmlNodePixelTexture::VrmlNodePixelTexture(VrmlScene *scene) : VrmlNodeTexture(scene), d_repeatS(true), d_repeatT(true), d_texObject(0) { } VrmlNodePixelTexture::~VrmlNodePixelTexture() { // viewer->removeTextureObject( d_texObject ); ... } VrmlNode *VrmlNodePixelTexture::cloneMe() const { return new VrmlNodePixelTexture(*this); } ostream& VrmlNodePixelTexture::printFields(ostream& os, int indent) { if (! d_repeatS.get()) PRINT_FIELD(repeatS); if (! d_repeatT.get()) PRINT_FIELD(repeatT); if (d_image.width() > 0 && d_image.height() > 0 && d_image.nComponents() > 0 && d_image.pixels() != 0) PRINT_FIELD(image); return os; } void VrmlNodePixelTexture::render(Viewer *viewer) { unsigned char *pixels = d_image.pixels(); if ( isModified() ) { if (d_texObject) { viewer->removeTextureObject(d_texObject); d_texObject = 0; } } if (pixels) { if (d_texObject) { viewer->insertTextureReference(d_texObject, d_image.nComponents()); } else { // Ensure the image dimensions are powers of two const int sizes[] = { 2, 4, 8, 16, 32, 64, 128, 256 }; const int nSizes = sizeof(sizes) / sizeof(int); int w = d_image.width(); int h = d_image.height(); int i, j; for (i=0; i 0 && j > 0) { // Always scale images down in size and reuse the same pixel memory. if (w != sizes[i-1] || h != sizes[j-1]) { viewer->scaleTexture( w, h, sizes[i-1], sizes[j-1], d_image.nComponents(), pixels ); d_image.setSize( sizes[i-1], sizes[j-1] ); } d_texObject = viewer->insertTexture(d_image.width(), d_image.height(), d_image.nComponents(), d_repeatS.get(), d_repeatT.get(), pixels, true); } } } clearModified(); } int VrmlNodePixelTexture::nComponents() { return d_image.nComponents(); } int VrmlNodePixelTexture::width() { return d_image.width(); } int VrmlNodePixelTexture::height() { return d_image.height(); } int VrmlNodePixelTexture::nFrames() { return 0; } unsigned char* VrmlNodePixelTexture::pixels() { return d_image.pixels(); } // Set the value of one of the node fields. void VrmlNodePixelTexture::setField(const char *fieldName, const VrmlField &fieldValue) { if TRY_FIELD(image, SFImage) else if TRY_FIELD(repeatS, SFBool) else if TRY_FIELD(repeatT, SFBool) else VrmlNode::setField(fieldName, fieldValue); }