示例#1
0
文件: glutiv.cpp 项目: Alexpux/Coin3D
// Reconfigure on changes to window dimensions.
void
reshape_cb(int w, int h)
{
  int idx = winid2idx(glutGetWindow());

  scenemanager[idx]->setWindowSize(SbVec2s(w, h));
  scenemanager[idx]->setSize(SbVec2s(w, h));
  scenemanager[idx]->setViewportRegion(SbViewportRegion(w, h));
  scenemanager[idx]->scheduleRedraw();
}
示例#2
0
void QXipIvWidget::resizeGL(int width, int height)
{
	m_width = width;
	m_height = height;

	m_GLWidget->resize(m_width, m_height);

	m_sceneManager->setWindowSize(SbVec2s(m_width, m_height));
	m_sceneManager->setSize(SbVec2s(m_width, m_height));
	m_sceneManager->setViewportRegion(SbViewportRegion(m_width, m_height));
}
void QCtkXipSGWidget::resizeGL(int width, int height)
{
  mWidth = width;
  mHeight = height;

  glViewport(0,0,width, height);

  if(mSceneManager)
  {
    mSceneManager->setWindowSize(SbVec2s(mWidth, mHeight));
    mSceneManager->setSize(SbVec2s(mWidth, mHeight));
    mSceneManager->setViewportRegion(SbViewportRegion(mWidth, mHeight));
  }
}
示例#4
0
void
SoWinFullViewer::setDecoration(SbBool enable)
{
#if SOWIN_DEBUG
  if ((enable && this->isDecoration()) ||
       (! enable && ! this->isDecoration())) {
    SoDebugError::postWarning("SoWinFullViewer::setDecoration",
                               "decorations already turned %s",
                              enable ? "on" : "off");
    return;
  }
#endif // SOWIN_DEBUG

  PRIVATE(this)->decorations = enable;
  PRIVATE(this)->showDecorationWidgets(enable);

  // reposition all widgets
  RECT rect;
  Win32::GetClientRect(this->getParentWidget(), & rect);
  PRIVATE(this)->layoutWidgets(rect.right, rect.bottom);
  if (enable) {
    rect.right -= DECORATION_SIZE * 2;
    rect.bottom -= DECORATION_SIZE;
  }
  SoWinRenderArea::sizeChanged(SbVec2s((short)rect.right, (short)rect.bottom));
  Win32::InvalidateRect(this->getParentWidget(), NULL, TRUE);
}
示例#5
0
//////////////////////////////////////////////////////////////////////////////
//
//  Constructor which takes no params
//
SoLineHighlightRenderAction::SoLineHighlightRenderAction()
	: SoGLRenderAction(SbVec2s(1, 1)) // pass a dummy viewport region
//
//////////////////////////////////////////////////////////////////////////////
{
    constructorCommon();
}
示例#6
0
void
SoXipAnnotation::updateEnumerationPosition( SoSFVec3f& position )
{
	if( mIsViewInitialized && point.getNum() >= 2 )
	{
		const SbVec3f& p0 = point[0];
		const SbVec3f& p1 = point[1];
		
		SbVec3f u = SbVec3f( 1, 0, 0 );
		SbVec3f v = p1 - p0;
		SbVec3f normal = mViewVolume.getPlane(0).getNormal();

		double a = angleBetweenVectors( u, v, normal );
		bool pos_cos = cos(a) > 0;
		bool pos_sin = sin(a) > 0;

		mEnumerationText->justification.setValue( pos_cos ? SoXipText2::LEFT : SoXipText2::RIGHT );
		mEnumerationText->vAlignment.setValue( pos_sin ? SoXipText2::TOP : SoXipText2::BOTTOM );

		SbVec3f offset = projectScreenOffsetToWorld( SbVec2s( 5, 5 ) );
		SbVec3f middle;
		middle[0] = (  pos_cos ? offset[0] : -offset[0] ) + ( p0[0] + p1[0] ) / 2.;
		middle[1] = ( !pos_sin ? offset[1] : -offset[1] ) + ( p0[1] + p1[1] ) / 2.;
		middle[2] = ( p0[2] + p1[2] ) / 2.;

		position.setValue( middle );
	}
}
示例#7
0
Cvr2DTexPage *
SoOrthoSliceP::getPage(const SoGLRenderAction * action,
                       const int axis, const int slice)
{
  while (this->cachedpages[axis].getLength() <= slice) {
    this->cachedpages[axis].append(NULL);
  }

  SoState * state = action->getState();
  const CvrVoxelBlockElement * vbelem = CvrVoxelBlockElement::getInstance(state);

  SoOrthoSliceP::CachedPage * cp = this->cachedpages[axis][slice];

  // Check validity.
  //
  // FIXME: this would probably be better replaced by a "BrickCache"
  // dependency tracker. 20041112 mortene.
  if (cp && (cp->volumedataid != vbelem->getNodeId())) { delete cp; cp = NULL; }

  if (!cp) {
    const SbVec3s & pagesize = CvrPageSizeElement::get(state);
    // Pagesize according to axis: X => [Z, Y], Y => [X, Z], Z => [X, Y].
    SbVec2s subpagesize =
      SbVec2s(pagesize[(axis == 0) ? 2 : 0], pagesize[(axis == 1) ? 2 : 1]);

    Cvr2DTexPage * page = new Cvr2DTexPage(action, axis, slice, subpagesize);

    this->cachedpages[axis][slice] = cp =
      new SoOrthoSliceP::CachedPage(page, PUBLIC(this));
    cp->volumedataid = vbelem->getNodeId();
  }

  return cp->getPage();
}
示例#8
0
/*!
  Any events from the native window system that goes to the OpenGL
  canvas gets piped through this method.

  It is overloaded in the subclasses to catch user interaction with
  the render canvas in the viewers, aswell as forwarding relevant
  events to the scenegraph.
*/
void
SoXtGLWidget::processEvent(XAnyEvent * event)
{
  switch (event->type) {
  case MapNotify:
    if ( !PRIVATE(this)->normalcontext ) {
      PRIVATE(this)->initNormalContext();
    }
    break;

  case Expose:
    if ( !PRIVATE(this)->normalcontext ) {
      PRIVATE(this)->initNormalContext();
    }
    this->waitForExpose = FALSE; // Gets flipped from TRUE on first expose.
    if (!this->glScheduleRedraw()) {
      this->redraw();
    }
    break;

  case ConfigureNotify:
    if (PRIVATE(this)->glxwidget != (Widget) NULL) {
      Dimension width, height;
      // XtVaGetValues(PRIVATE(this)->glxwidget,
      //               XmNwidth, &width, XmNheight, &height, NULL);
      XtVaGetValues(this->getWidget(),
                    XmNwidth, &width, XmNheight, &height, NULL);
      this->sizeChanged(SbVec2s(width, height));
    }
    break;

  } // switch (event->type)

}
SoGesturePinchEvent::SoGesturePinchEvent(QPinchGesture* qpinch, QWidget *widget)
{
    int h = widget->height();
    QPointF widgetCorner = QPointF(widget->mapToGlobal(QPoint(0,0)));
    qreal scaleToWidget = (widget->mapFromGlobal(QPoint(800,800))-widget->mapFromGlobal(QPoint(0,0))).x()/800.0;
    QPointF pnt;//temporary
    pnt = qpinch->startCenterPoint();
    pnt = (pnt-widgetCorner)*scaleToWidget;//translate screen coord. into widget coord.
    startCenter = SbVec2f(pnt.x(), h - pnt.y());

    pnt = qpinch->centerPoint();
    pnt = (pnt-widgetCorner)*scaleToWidget;
    curCenter = SbVec2f(pnt.x(), h - pnt.y());

    pnt = qpinch->lastCenterPoint();
    pnt = (pnt-widgetCorner)*scaleToWidget;
    deltaCenter = curCenter - SbVec2f(pnt.x(), h - pnt.y());

    deltaZoom = qpinch->scaleFactor();
    totalZoom = qpinch->totalScaleFactor();

    deltaAngle = qpinch->rotationAngle();
    totalAngle = qpinch->totalRotationAngle();

    state = SbGestureState(qpinch->state());

    this->setPosition(SbVec2s(curCenter));
    Qt::KeyboardModifiers mods = QApplication::keyboardModifiers();
    this->setAltDown(mods.testFlag(Qt::AltModifier));
    this->setCtrlDown(mods.testFlag(Qt::ControlModifier));
    this->setShiftDown(mods.testFlag(Qt::ShiftModifier));
    this->setTime(SbTime::getTimeOfDay());
}
示例#10
0
// This contains the real constructor code (the two constructors are
// only entry points for this method).
void
SoWinExaminerViewerP::constructor(SbBool build)
{
  this->genericConstructor();

  PUBLIC(this)->setClassName("SoWinExaminerViewer");
  PUBLIC(this)->setPopupMenuString("Examiner Viewer");

  if (! build) return;

  HWND widget = PUBLIC(this)->buildWidget(PUBLIC(this)->getParentWidget());
  PUBLIC(this)->setBaseWidget(widget);

  PUBLIC(this)->setLeftWheelString("RotX");
  PUBLIC(this)->setBottomWheelString("RotY");

  PUBLIC(this)->setCursorEnabled(TRUE);
  PUBLIC(this)->setAnimationEnabled(TRUE);

  PUBLIC(this)->setSize(SbVec2s(500, 421));
  // FIXME: If the new size is the same as the old size, Windows will
  // never size the widget, and layoutWidgets() will never be
  // called. mariusbu 20010823.

}
示例#11
0
void QXipIvWidget::wheelEvent(QWheelEvent* event)
{
// TODO: Find a solution for Linux and Mac
#if WIN32
    SbTime time;
    time.setToTimeOfDay();
    SoMouseWheelEvent e;
    e.setTime(time);
    if (event->modifiers() & Qt::ShiftModifier)
        e.setShiftDown(TRUE);
    if (event->modifiers() & Qt::ControlModifier)
        e.setCtrlDown(TRUE);
//#if WIN32
    e.setDelta(event->delta());
    e.setDelta(event->delta() / 120);
	e.setPosition( SbVec2s(event->pos().x(), this->height() - event->pos().y() ) );
//#endif
    if (m_sceneManager->processEvent(&e))
    {
        processDelayQueue();
        updateCursor(true);
    }
    else
    {
        updateCursor(false);
    }
#endif
}
示例#12
0
SoTexture2Convert::SoTexture2Convert(void)
{
  SO_ENGINE_INTERNAL_CONSTRUCTOR(SoTexture2Convert);

  SO_ENGINE_ADD_INPUT(sourceImage, (SbVec2s(0,0), 1, NULL));

  SO_ENGINE_ADD_OUTPUT(image, SoSFImage);
}
示例#13
0
SceneTexture2::SceneTexture2(void)
{
  this->api = NULL;
  this->prevsize = SbVec2s(-1, -1);
  this->renderer = NULL;
  this->size_sensor = NULL;
  this->render_sensor = NULL;
}
// Function that loads a texture from memory, and return a pointer to a
// SoTexture2 node containing this texture..
// Return:
//  SoTexture2 *
SoTexture2 *
texture()
{
  SoTexture2 * texture = new SoTexture2;
  texture->image.setValue(SbVec2s(texturewidth, textureheight), 1, bitmap);
  texture->model = SoTexture2::MODULATE;
  texture->blendColor.setValue(1.0, 0.0, 0.0);
  return texture;
}
void QCtkXipSGWidget::mousePressEvent(QMouseEvent *event)
{
  if(mInteractingField)
    mInteractingField->setValue(1);

  // store old pos for delta mode
  mOldPos = SbVec2s(event->pos().x(), event->pos().y());



  event->accept();

  // Pass the QT mouse button event to open inventor
  SbTime time;
  time.setToTimeOfDay();
  SoMouseButtonEvent e;
  e.setTime(time);

  switch (event->button())
  {
  default:
  case Qt::LeftButton:    e.setButton(SoMouseButtonEvent::BUTTON1); break;
  case Qt::MidButton:        e.setButton(SoMouseButtonEvent::BUTTON2); break;
  case Qt::RightButton:    e.setButton(SoMouseButtonEvent::BUTTON3); break;
  }
  if (event->modifiers() & Qt::ShiftModifier)
    e.setShiftDown(TRUE);
  if (event->modifiers() & Qt::ControlModifier)
    e.setCtrlDown(TRUE);
  e.setState(SoButtonEvent::DOWN);
  e.setPosition(SbVec2s(event->pos().x(), mHeight - event->pos().y()));

  if (mSceneManager->processEvent(&e))
  {
    //processDelayQueue();
    //repaint();
    updateCursor(true);
  }
  else
  {
    updateCursor(false);
  }
}
int SoXipSegmentationOverlayManager::SetupOverlayAction ( SoHandleEventAction* action, SoXipShape *pshape )
{
	// Maximal distance between two consecutive mouse down positions
	// allowed to generate a double-click.
	int DoubleClickMaxJump = 2;
	// Maximal time between two mouse clicks to be considered as a
	// double-click.
	SbTime DoubleClickTime = SbTime(0.5);
	// Time corresponding to a click
	SbTime ClickTime = SbTime(0.1);

	if (pshape == NULL) return ( 0 ) ;
	const SbString& classname = shapeClassName.getValue();
	char *szName = (char*)classname.getString () ;
	if (szName == NULL) return ( 0 ) ;

	SoDebugError::postInfo ( szName, "test" ) ;

	SbVec3f pos;
	const SbVec2s& mousePosition = action->getEvent()->getPosition() ;
	
	//if( SO_MOUSE_RELEASE_EVENT( action->getEvent(), BUTTON1 ) && action->getGrabber() == this ) 
	if( SO_MOUSE_RELEASE_EVENT( action->getEvent(), BUTTON1 )) 
	{
		SoDebugError::postInfo ( szName, "test" ) ;
		mMouseUpTime = action->getEvent()->getTime();
		{
		}
	}
	else if( SO_MOUSE_PRESS_EVENT( action->getEvent(), BUTTON1 ) )
	{
		SbTime tim = action->getEvent()->getTime();

		// Compute the distance between the last mouse press event and this one
		SbVec2s v = (mMouseDownPos - mousePosition);
		float mouseJump = sqrtf( v.dot(v) );

		// Do not perform a double-click if the time between two mouse press
		// events is higher than the default time set for double-clicks, or if
		// the mouse jumped further than the tolerance set (without tolerance
		// it is more difficult to get a double-click.
		if ( (tim - mMouseDownTime) < DoubleClickTime && mouseJump < DoubleClickMaxJump )
		{
			mMouseDownTime = SbTime::zero();
			mMouseDownPos = SbVec2s(-1, -1);
		}
		else
		{
			mMouseDownTime = action->getEvent()->getTime() ;
		}
	}

	return ( 1 ) ;
}
示例#17
0
void
SoXtGLWidget::initGraphic(void)
{
  assert(PRIVATE(this)->glxwidget != (Widget) NULL);

  glLockNormal();
  Dimension width, height;
  XtVaGetValues(PRIVATE(this)->glxwidget, XmNwidth, &width, XmNheight, &height, NULL);
  PRIVATE(this)->glsize = SbVec2s(width, height);
  glEnable(GL_DEPTH_TEST);
  glUnlockNormal();
}
示例#18
0
/*!
  This method is provided for easier porting/compatibility with the
  Open Inventor SoXt component classes. It will call GetWindowExtEx()
  on the provided \a widget window handle's device context (returning
  an SbVec2s).

  \sa setWidgetSize()
*/
SbVec2s
SoWin::getWidgetSize(HWND widget)
{
  HDC hdc = GetDC(widget);

  SIZE size;
  if (! GetWindowExtEx(hdc, & size)) {
    size.cx = -1;
    size.cy = -1;
  }
  return SbVec2s((short) size.cx, (short) size.cy);
}
示例#19
0
SoXipCPUMprRender::SoXipCPUMprRender()
{
	SO_NODE_CONSTRUCTOR(SoXipCPUMprRender);

	SO_NODE_ADD_FIELD(minMaxSize, (SbVec2s(128, 1024)));
	SO_NODE_ADD_FIELD(volume, (NULL));
	SO_NODE_ADD_FIELD(blendOn, (FALSE));

	mMPRTexId = 0;
	mMPRSize = SbVec2s(0, 0);
	mMPRCache = 0;
	mNumCacheElems = 0;
	mMPRBuf = 0;
	mVolDataId = 0;
	mUpdateFlag = 0;
	mVolBuf = 0;
	mLutBuf = 0;
	mLutSize = 0;
	mLutDataId = 0;
    mTexInternalFormat = 0;
    mTexType = 0;
}
示例#20
0
void
SoXtGLWidgetP::exposeCB(Widget widget, XtPointer closure, XtPointer call_data)
{
  SoXtGLWidgetP * thisp = (SoXtGLWidgetP *) closure;
  assert(thisp);

  if (thisp->needrebuild) {
    thisp->cleanupContext();
    thisp->cleanupGLWidget();
    thisp->cleanupVisual();
    thisp->createVisual();
    thisp->buildGLWidget();
    thisp->buildContext();
    thisp->firstexpose = TRUE;
  }
  Dimension width = 0, height = 0;
  XtVaGetValues(widget, XtNwidth, &width, XtNheight, &height, NULL);
  thisp->glsize = SbVec2s(width, height);
  if (thisp->firstexpose) {
    PUBLIC(thisp)->sizeChanged(SbVec2s(width, height));
    thisp->firstexpose = FALSE;
  }
}
示例#21
0
void
SoXipAnnotation::updateAnnotationPosition( SoSFVec3f& position )
{
	if( mIsViewInitialized && point.getNum() == 2 )
	{
		SbVec3f screenPt[2];
		mViewVolume.projectToScreen( point[0], screenPt[0] );
		mViewVolume.projectToScreen( point[1], screenPt[1] );

		if( screenPt[0][0] < screenPt[1][0] )
		{
			mAnnotation->justification.setValue( SoXipText2::LEFT );
			position.setValue( point[1] + projectScreenOffsetToWorld( SbVec2s( 5, 0 ) ) );
		}
		else
		{
			mAnnotation->justification.setValue( SoXipText2::RIGHT );
			position.setValue( point[1] - projectScreenOffsetToWorld( SbVec2s( 5, 0 ) ) );
		}

		mAnnotation->vAlignment.setValue( SoXipText2::TOP );
	}
}
SoXipSegmentationOverlayManager::SoXipSegmentationOverlayManager()
{
	SO_NODE_CONSTRUCTOR( SoXipSegmentationOverlayManager );

	SO_NODE_ADD_FIELD( OverlayOption, ("") );
	//SO_NODE_ADD_FIELD( OverlayAction, (0) );
	//SO_NODE_ADD_FIELD( OverlayEnable, (true) );

	//!
	mMouseDownTime			= SbTime::zero();
	mMouseUpTime			= SbTime::zero();
	mMouseDownPos			= SbVec2s(-1, -1);

}
示例#23
0
void
SoXtMaterialList::constructor(// private
  const char * const dir,
  const SbBool build)
{
  this->common = new SoAnyMaterialList(dir);
  this->setSize(SbVec2s(200, 300));

  if (build) {
    this->setClassName("SoXtMaterialList");
    Widget materials = this->buildWidget(this->getParentWidget());
    this->setBaseWidget(materials);
  }
} // constructor()
示例#24
0
void 
SoXipAnnotation::GLRender( SoGLRenderAction* action )
{
	if( mIsViewInitialized && point.getNum() == 2 && point[0] != point[1] )
	{
		float angleValue = angle.getValue() * M_PI / 180.;

		SbVec3f screenPt[2];
		mViewVolume.projectToScreen( point[0], screenPt[0] );
		mViewVolume.projectToScreen( point[1], screenPt[1] );

		float lineAngle = angleBetweenVectors( SbVec3f(1, 0, 0), (screenPt[1] - screenPt[0]) );
		if( screenPt[0][1] > screenPt[1][1] )
			lineAngle = 2 * M_PI - lineAngle;

		float arrowLengthPix = length.getValue();

		SbVec3f offsetUp = projectScreenOffsetToWorld( SbVec2s( 
			arrowLengthPix * cos( lineAngle - angleValue ),
			arrowLengthPix * sin( lineAngle - angleValue ) ) );

		SbVec3f offsetDown = projectScreenOffsetToWorld( SbVec2s( 
			arrowLengthPix * cos( lineAngle + angleValue ),
			arrowLengthPix * sin( lineAngle + angleValue ) ) );

		mArrowCoords->point.setNum(3);
		mArrowCoords->point.set1Value( 0, point[0] );
		mArrowCoords->point.set1Value( 1, point[0] + offsetUp );
		mArrowCoords->point.set1Value( 2, point[0] + offsetDown );
		
		int indices[6] = {0, 1, -1, 0, 2, -1};
		mArrowIndices->coordIndex.setNum(6);
		mArrowIndices->coordIndex.setValues( 0, 6, indices );
	}

	SoXipManipulableShape::GLRender( action );
}
示例#25
0
// doc in super
void
SoWinFullViewer::sizeChanged(const SbVec2s & size)
{
  if (! IsWindow(this->getBaseWidget())) return;
  
  if (PRIVATE(this)->decorations) {
    SoWinRenderArea::sizeChanged(SbVec2s(size[0] - (2 * DECORATION_SIZE),
                                         size[1] - DECORATION_SIZE));
  }
  else {
    SoWinRenderArea::sizeChanged(size);
  }
  PRIVATE(this)->layoutWidgets(size[0], size[1]);
  Win32::InvalidateRect(this->getParentWidget(), NULL, TRUE);
}
示例#26
0
int main(int, char ** argv)
{
	
	HWND window = SoWin::init("Oil Well");
	if (window == NULL) exit(1);
	SoWinExaminerViewer * viewer = new SoWinExaminerViewer(window);
	viewer->setDecoration(false);
	viewer->setSize(SbVec2s(800, 600));
	SoSeparator *root = new SoSeparator;
	root->ref();
	SoSeparator *obelisk = new SoSeparator();

	// Define the normals used:
	SoNormal *myNormals = new SoNormal;
	myNormals->vector.setValues(0, 8, norms);
	obelisk->addChild(myNormals);
	SoNormalBinding *myNormalBinding = new SoNormalBinding;
	myNormalBinding->value = SoNormalBinding::PER_FACE;
	obelisk->addChild(myNormalBinding);
	// Define material for obelisk
	SoMaterial *myMaterial = new SoMaterial;
	myMaterial->diffuseColor.setValue(.4, .4, .4);
	obelisk->addChild(myMaterial);
	// Define coordinates for vertices
	SoCoordinate3 *myCoords = new SoCoordinate3;
	myCoords->point.setValues(0, 28, vertices);
	obelisk->addChild(myCoords);
	// Define the FaceSet
	SoFaceSet *myFaceSet = new SoFaceSet;
	myFaceSet->numVertices.setValues(0, 8, numvertices);
	obelisk->addChild(myFaceSet);

	root->addChild(obelisk);

	viewer->setSceneGraph(root);
	viewer->setTitle("Oil Well");
	viewer->show();
	SoWin::show(window);
	SoWin::mainLoop();
	delete viewer;
	root->unref();
	return 0;
}
示例#27
0
// convert normalized screen space coordinates into pixel screen
// space. Values that are too far from the viewport are culled.
static SbBool get_screenpoint_pixels(const SbVec3f & screenpoint,
                                     const SbVec2s & vpsize,
                                     SbVec2s & sp)
{
  float sx = screenpoint[0] * vpsize[0];
  float sy = screenpoint[1] * vpsize[1];

  // FIXME: just assume we won't have strings larger than 3000 pixels
  const float limit = 3000.0f;

  if ((sx > -limit) &&
      (sy > -limit) &&
      (sx < limit) &&
      (sy < limit)) {
    sp = SbVec2s(static_cast<short>(sx), static_cast<short>(sy));
    return TRUE;
  }
  return FALSE;
}
示例#28
0
void
SoXtExaminerViewerP::constructor(const SbBool build)
{
  this->genericConstructor();

  PUBLIC(this)->setClassName(PUBLIC(this)->getWidgetName());
  this->camerabutton = (Widget) NULL;

  if (build) {
    Widget viewer = PUBLIC(this)->buildWidget(PUBLIC(this)->getParentWidget());
    PUBLIC(this)->setBaseWidget(viewer);
    PUBLIC(this)->fitSize(SbVec2s(500, 300));

    char * dollyString = NULL;
    SoXtResource rsc(PUBLIC(this)->getRightWheelLabelWidget());
    if (rsc.getResource("dollyString", XmRString, dollyString) &&
         dollyString != NULL)
      PUBLIC(this)->setRightWheelString(dollyString);
  }
}
示例#29
0
SoTexture2::SoTexture2()
//
////////////////////////////////////////////////////////////////////////
{
    SO_NODE_CONSTRUCTOR(SoTexture2);

    SO_NODE_ADD_FIELD(filename, (""));
    SO_NODE_ADD_FIELD(image, (SbVec2s(0, 0), 0, 0));
    SO_NODE_ADD_FIELD(wrapS, (REPEAT));
    SO_NODE_ADD_FIELD(wrapT, (REPEAT));
    SO_NODE_ADD_FIELD(model, (MODULATE));
    SO_NODE_ADD_FIELD(blendColor, (SbColor(0,0,0)));

    // Set up enumerations for texture model
    SO_NODE_DEFINE_ENUM_VALUE(Model, MODULATE);
    SO_NODE_DEFINE_ENUM_VALUE(Model, DECAL);
    SO_NODE_DEFINE_ENUM_VALUE(Model, BLEND);

    SO_NODE_DEFINE_ENUM_VALUE(Wrap, REPEAT);
    SO_NODE_DEFINE_ENUM_VALUE(Wrap, CLAMP);
    
    // Set up info in enumerated type field
    SO_NODE_SET_SF_ENUM_TYPE(model, Model);
    SO_NODE_SET_SF_ENUM_TYPE(wrapS, Wrap);
    SO_NODE_SET_SF_ENUM_TYPE(wrapT, Wrap);

    // Set up sensors to keep the image/filename fields agreeing.
    // Sensors are used instead of field to field connections or raw
    // notification so that the fields can still be attached to/from
    // other fields.
    imageSensor = new SoFieldSensor(imageChangedCB, this);
    imageSensor->setPriority(0);
    imageSensor->attach(&image);
    filenameSensor = new SoFieldSensor(filenameChangedCB, this);
    filenameSensor->setPriority(0);
    filenameSensor->attach(&filename);

    renderList = NULL;  // Display list used for rendering

    isBuiltIn = TRUE;
}
示例#30
0
void
SoTexture2::filenameChangedCB(void *data, SoSensor *)
//
////////////////////////////////////////////////////////////////////////
{
    SoTexture2 *tex = (SoTexture2 *)data;

    if (tex->filename.isIgnored()) {
	tex->setReadStatus(FALSE);
	return;
    }

    // Read in image file right away...
    int nx, ny, nc;
    unsigned char *bytes;
    SbBool result = readImage(tex->filename.getValue(), nx, ny, nc, bytes);
    if (!result) {
	// Read error is taken care of by readImage() call
	nx = ny = nc = 0;
	bytes = NULL;
    }
    // Detach the image sensor temporarily...
    tex->imageSensor->detach();

    // Set the image to the right value:
    tex->image.setValue(SbVec2s(nx, ny), nc, bytes);

    // And set its default bit so it isn't written out
    tex->image.setDefault(TRUE);

    if (bytes != NULL) delete [] bytes;

    if (tex->renderList) {
	tex->renderList->unref();
	tex->renderList = NULL;
    }
    tex->imageSensor->attach(&tex->image);

    tex->setReadStatus(result);
}