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