Hi,

I tried to run a direct volume rendering program in the *multiple display
window* environment.

I conisdered two demo programs within the OpenSG v1.8.0 distribution:
1) testVolumeShadersRender.cpp
2) Tutorial/12ClusterServer.cpp & Tutorial/13ClusterClient.cpp

Both programs work well seperately:
The volume can be rendered in a single window;
For the cluster programs, a torus geometry can be displayed in the server
window and be rotated via the client window.

however, when I combine together the *ClusterClient.cpp* code and *
testVolumeShaderRender.cpp* code,
we can successfully build the new program (namely *VolumeClient.exe*), but
failed to run it, below are more detailed descriptions.

========================================
OS: Windows Vista Home Premium
OpenSG Version: v1.8.0
Video Card: NVidia Geforce 9600m GT

We simply utilize the demo code in 12ClusterServer.cpp to build our server
program, it works well in previous test;
Running the server:
server.exe -geometry 500x500+0+0 -m -w test


Running the client:
VolumeClient.exe -m test

**we dont appoint the data file path in the starting parameters since it is
hardcoded in our program

Then the server crashed immediately, an exception were catched,
its expression: vector subscript out of range

When I aborted the server program, the client crashed too.
==============================================

I attached my VolumeClient.cpp file within this email,
if anyone could check my code, I would like to greatly appreciate your
help~~

The source file is typical OpenSG style, so it might not be so hard to read~

I really need your help, thanks again.

-- 
Jie Liu
Visualization Research Group
Center for Information Science, School of EECS,
Room 2104, Science Building No.2,
Peking University, Beijing 100871, China
/********************************************************************
	created:	2009/07/12
	file name:	main.cpp
	author:
	
	remarks:	volume clinet: combination of volume and client
*********************************************************************/

#include <OpenSG/OSGConfig.h>	// we need this file in every OpenSG project

#include <OpenSG/OSGGLUT.h>
#include <OpenSG/OSGGLUTWindow.h>

#include <OpenSG/OSGSimpleSceneManager.h>

//#include <OpenSG/OSGSceneFileHandler.h>	// For loading files
#include <OpenSG/OSGLog.h>

// OpenSG Volume Rendering 
#include <OpenSG/OSGDVRVolume.h>
#include <OpenSG/OSGDVRVolumeTexture.h>
#include <OpenSG/OSGDVRAppearance.h>
#include <OpenSG/OSGDVRIsoSurface.h>
#include <OpenSG/OSGDVRLookupTable.h>

// MultiDisplay support
#include <OpenSG/OSGMultiDisplayWindow.h>

#include <string.h>
#include <iostream>

OSG_USING_NAMESPACE

SimpleSceneManager *g_SceneManager;

// Some fieldcontainer pointers that we require for interaction
NodePtr      g_SceneRoot	= NullFC;	
DVRVolumePtr g_VolNode		= NullFC;
DVRShaderPtr g_osgShader	= NullFC;	// it's not NodeCore

// animation settings
int   animate  = 1;
float aniSpeed = 0.5;
float lastFrame;

// List of shaders to be tested
char* shaderList[] = {
	"DVRSimpleShader",
	"DVRSimpleLUTShader",
	"DVRIsoShader",
	"DVRMtexLUTShader"
};
int numShaders = sizeof(shaderList) / sizeof(char *);
int curShader = -1;

// Desired Shader Mode
int newShader = 0;

// Volume TF
unsigned char lutData[1024] = {
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 72, 72, 72,
	76, 76, 76, 76, 76, 76, 76, 76, 77, 77, 77, 77, 77, 77, 77, 77,
	77, 77, 77, 77, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 103, 0, 0, 103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 108, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 113, 113,
	0, 0, 113, 113, 0, 0, 0, 0, 0, 0, 0, 0, 138, 138, 138, 138,
	138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138,
	138, 138, 138, 138, 138, 138, 138, 138, 139, 139, 139, 139,
	139, 139, 139, 139, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};

//=====================================================
//	forward declaration of global function
//=====================================================
NodePtr makeVolume( const char * datFile);
int setupGLUT( int *argc, char *argv[] );

int main(int argc, char **argv)
{
	ChangeList::setReadWriteDefault();
	osgInit(argc,argv);

	int winid = setupGLUT(&argc, argv);
	
	MultiDisplayWindowPtr MDWndPtr = MultiDisplayWindow::create();

	// edit MultiDisplayWindow
	char*	opt;	//options
	std::string	strFileName("volume.dat");

	beginEditCP(MDWndPtr);
	{
		// check parameters
		for( int i = 1; i < argc; ++i )
		{
			if ( argv[i][0] != '-')
			{
				std::cout<<"main function: push "<<argv[i]<<" to server list..."<<std::endl;
				MDWndPtr->getServers().push_back(argv[i]);
				continue;
			}

			switch(argv[i][1])
			{
			case 'm':	// to support multicast
				MDWndPtr->setConnectionType("Multicast");
				std::cout<<"use Multicast connection..."<<std::endl;
				break;
			case 'p':
				MDWndPtr->setConnectionType("SocketPipeline");
				std::cout<<"use SocketPipeline connection..."<<std::endl;
				break;
			case 'i': opt = argv[i][2] ? argv[i]+2 : argv[++i];
				if(opt != argv[argc])
					MDWndPtr->setConnectionInterface(opt);
				break;
			case 'f':
				opt = argv[i][2] ? argv[i]+2 : argv[++i];
				if ( opt != argv[argc] )
				{
					strFileName = opt;
					std::cout<<"Use customized file: "<<strFileName.c_str()<<std::endl;
				}
				break;
			case 'x':
				opt = argv[i][2] ? argv[i]+2 : argv[++i];
				if ( opt !=  argv[argc] )
					MDWndPtr->setHServers(atoi(opt));
				break;
			case 'y':
				opt = argv[i][2] ? argv[i]+2 : argv[++i];
				if ( opt != argv[argc] )
					MDWndPtr->setVServers(atoi(opt));
				break;
			default:  
				std::cout << argv[0]  
					  << " -m multicast"
						  << " -p pear to pear"
						  << " -i interface"
						  << " -f file"
						  << " -x horizontal server cnt"
						  << " -y vertical server cnt"
						  << endLog;
				return 0;
			}
		}
	}

	MDWndPtr->setSize(300, 300);	// dummy size for navigator
	endEditCP(MDWndPtr);

	std::cout<<"use data file: "<<strFileName.c_str()<<std::endl;
	g_SceneRoot = makeVolume(strFileName.c_str());

	g_SceneManager = new SimpleSceneManager;
	g_SceneManager->setWindow   (MDWndPtr);
	g_SceneManager->setRoot     (g_SceneRoot);
	g_SceneManager->setHighlight(g_SceneRoot);

	g_SceneManager->showAll();
	
	Pnt3f from = g_SceneManager->getNavigator()->getFrom();
	from[2] = 3 * from[2];
	g_SceneManager->getNavigator()->setFrom(from);

	MDWndPtr->init();

	glutMainLoop();

	return 0;
}

void display(void)
{
	if (animate)
	{
		// Eventually switch between different hardware modes
		float ctime   = glutGet(GLUT_ELAPSED_TIME);
		int   dtime   = (int)ctime / 1000 / 2;

		newShader = dtime % numShaders;

		// Make the volume rotate
		int movement = ((ctime - lastFrame) * aniSpeed);
		if (movement != 0) lastFrame = ctime;

		g_SceneManager->mouseButtonPress  (GLUT_LEFT_BUTTON,  0, 0);
		g_SceneManager->mouseMove         (movement, 0);
		g_SceneManager->mouseButtonRelease(GLUT_LEFT_BUTTON, movement, 0);
	}

	// Switch shader mode if desired
	if (newShader != curShader)
	{
		DVRShaderPtr shd = DVRShaderPtr::dcast(
			FieldContainerFactory::the()->createFieldContainer(shaderList[newShader]));

		// change to new shader object
		beginEditCP(g_VolNode, DVRVolume::ShaderFieldMask);            
		g_VolNode->setShader(shd);
		endEditCP(g_VolNode, DVRVolume::ShaderFieldMask);
	}

	g_SceneManager->redraw();

	OSG::Thread::getCurrentChangeList()->clearAll();
	glClear(GL_COLOR_BUFFER_BIT);
	glutSwapBuffers();

	// Output active shader mode - field is valid after redraw only
	if (newShader != curShader)
	{
		SLOG << "Active Shader " << newShader << ": "
			<< (g_VolNode->getShader() != NullFC ?
			g_VolNode->getShader()->getTypeName() : "NullFC")
			<< std::endl;

		curShader = newShader;
	}
}

void reshape(int w, int h)
{
	g_SceneManager->resize(w, h);
	glutPostRedisplay();
}

void mouse(int button, int state, int x, int y)
{
	if (state)
		g_SceneManager->mouseButtonRelease(button, x, y);
	else
		g_SceneManager->mouseButtonPress(button, x, y);

	glutPostRedisplay();
}

void motion(int x, int y)
{
	g_SceneManager->mouseMove(x, y);
	glutPostRedisplay();
}

void keyboard(unsigned char k, int OSG_CHECK_ARG(x), int OSG_CHECK_ARG(y))
{
	switch(k)
	{
	case 27:        
		{
			OSG::osgExit();
			exit(0);
		}
		break;

	case 'a':
		{
			animate = 1 - animate;
		}
		break;

	case '+':
		{
			newShader = (newShader + 1) % numShaders;
		}
		break;

	case '-':
		{
			newShader = (newShader > 1) ? (newShader - 1) % numShaders : numShaders - 1;
		}
		break;
	}
}

int setupGLUT(int *argc, char *argv[])
{
	glutInit(argc, argv);
	glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE | GLUT_STENCIL);

	int winid = glutCreateWindow("OpenSG Volume Rendering - Client");

	glutReshapeFunc(reshape);
	glutDisplayFunc(display);
	glutMouseFunc(mouse);
	glutMotionFunc(motion);
	glutKeyboardFunc(keyboard);

	glutIdleFunc(display);

	return winid;
}

NodePtr makeVolume( const char * datFile)
{  
	DVRVolumePtr         vol         = DVRVolume::create();
	DVRAppearancePtr     app         = DVRAppearance::create(); 
	DVRVolumeTexturePtr  tex         = DVRVolumeTexture::create();
	DVRLookupTablePtr    lut         = DVRLookupTable::create();
	DVRIsoSurfacePtr     iso         = DVRIsoSurface::create();

	g_VolNode = vol;

	ImagePtr datImage = Image::create();
	if (false == datImage->read(datFile)) 
	{
		SLOG << "File: " << datFile << " not found" << std::endl;
		exit (-1);
	}
	beginEditCP(tex);
	tex->setImage(datImage);
	tex->setFileName(datFile);
	endEditCP(tex);

	//!! FIXME - Initialize the lookup table
	//!! This should not be neccessary if the OpenSG reader works correctly
	beginEditCP(lut, DVRLookupTable::TouchedFieldMask);
	lut->setTouched(true);
	endEditCP(lut, DVRLookupTable::TouchedFieldMask);

	// Initialize the lookup table
	beginEditCP(lut, DVRLookupTable::DataFieldMask);
	for (int i = 0; i < 1024; i++)
		lut->getData()[i] = lutData[i];
	endEditCP(lut, DVRLookupTable::DataFieldMask);

	// Initialize the isovalue
	beginEditCP(iso, DVRIsoSurface::IsoValueFieldMask);
	iso->setIsoValue(0.2);
	endEditCP(iso, DVRIsoSurface::IsoValueFieldMask);

	// Attach the volume texture and isosurface to the appearance
	beginEditCP(app, Node::AttachmentsFieldMask);
	app->addAttachment(tex);
	app->addAttachment(lut);
	app->addAttachment(iso);
	endEditCP(app, Node::AttachmentsFieldMask);

	// Assign the appearance and shader to the volume core
	beginEditCP(vol);
	vol->setFileName(datFile);
	vol->setAppearance(app);
	vol->setShader(g_osgShader);
	endEditCP(vol);

	// Create a node for the volume core
	NodePtr newGeom = Node::create();
	beginEditCP(newGeom);
	newGeom->setCore(vol);
	endEditCP(newGeom);

	return newGeom;
}

------------------------------------------------------------------------------
Enter the BlackBerry Developer Challenge  
This is your chance to win up to $100,000 in prizes! For a limited time, 
vendors submitting new applications to BlackBerry App World(TM) will have
the opportunity to enter the BlackBerry Developer Challenge. See full prize  
details at: http://p.sf.net/sfu/Challenge
_______________________________________________
Opensg-core mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensg-core

Reply via email to