OpenSG "2.0.0-pre1" Microsoft Windows 7 64-bit We've been using this version of OpenSG for about 2 years now and have done some substantial things with it.
Now I have what I thought should be a very simple, basic scene graph, and it's not rendering properly. I'm stumped. In brief: * I have a graph with 3 Geometry leaves. * Each Geometry should render with a different ChunkMaterial. * Each ChunkMaterial has a MaterialChunk and a PolygonChunk. * What's happening is that all three Geometries are rendering with the first MaterialChunk. * It doesn't matter whether I set the material in the Geometry, or in a MaterialGroup above the Geometry. I've boiled it all down to a simple (I think) test program. It constructs the scene graph with 3 squares and writes an "OSB" file, then reads the file and renders it. After writing and again after reading, it also dumps the scene graph out to std::cerr. The text dump looks correct in that each Geometry includes or follows a different-colored Material. The squares should render as red, green, and blue. But, they all render red. One thing that mystifies me is that the Chunk reference counts are about twice what they should be: the MaterialChunks have a reference count of 2, though each appears only once in the graph. If I create a different PolygonChunk for each Material, they also each have a reference count of 2. If I share 1 PolygonChunk among the 3 Materials, it has a reference count of 6. (When writing the file it's actually 7 due to a ptr in the body of that function. When reading it back in, it's 6.) I'm attaching the source code, the text dump, and a screen shot, as separate files. Any insights will be greatly appreciated. -- Ted Hall
<<attachment: OSBViewer.png>>
Wrote scene graph: Node = <00000000021689F0>, refcount = 1 Core = <0000000002044AA0>, type = Transform, refcount = 2 Children: Node = <0000000002168B00>, refcount = 2 Core = <00000000020EDEE0>, type = Group, refcount = 2 Children: Node = <0000000002169050>, refcount = 1 Core = <00000000022116D0>, type = Geometry, refcount = 1 Material = <0000000002235AE0>, type = ChunkMaterial, refcount = 1 Chunk = <00000000020386A0>, type = MaterialChunk, refcount = 2 Ambient: 1, 0, 0, 1 Diffuse: 1, 0, 0, 1 Specular: 1, 0, 0, 1 Emission: 1, 0, 0, 1 Chunk = <0000000002038580>, type = PolygonChunk, refcount = 7 Node = <00000000021695A0>, refcount = 1 Core = <00000000022119D0>, type = Geometry, refcount = 1 Material = <0000000002235BC0>, type = ChunkMaterial, refcount = 1 Chunk = <0000000002211860>, type = MaterialChunk, refcount = 2 Ambient: 0, 1, 0, 1 Diffuse: 0, 1, 0, 1 Specular: 0, 1, 0, 1 Emission: 0, 1, 0, 1 Chunk = <0000000002038580>, type = PolygonChunk, refcount = 7 Node = <0000000002169AF0>, refcount = 1 Core = <0000000002285490>, type = Geometry, refcount = 1 Material = <0000000002235CA0>, type = ChunkMaterial, refcount = 1 Chunk = <0000000002211B60>, type = MaterialChunk, refcount = 2 Ambient: 0, 0, 1, 1 Diffuse: 0, 0, 1, 1 Specular: 0, 0, 1, 1 Emission: 0, 0, 1, 1 Chunk = <0000000002038580>, type = PolygonChunk, refcount = 7 Read scene graph: Node = <0000000002168B00>, refcount = 1 Core = <0000000002044AA0>, type = Transform, refcount = 1 Children: Node = <0000000002169AF0>, refcount = 1 Core = <00000000020EDEE0>, type = Group, refcount = 1 Children: Node = <00000000021699E0>, refcount = 1 Core = <0000000002285490>, type = Geometry, refcount = 1 Material = <0000000002235BC0>, type = ChunkMaterial, refcount = 1 Chunk = <0000000002289DB0>, type = MaterialChunk, refcount = 2 Ambient: 1, 0, 0, 1 Diffuse: 1, 0, 0, 1 Specular: 1, 0, 0, 1 Emission: 1, 0, 0, 1 Chunk = <00000000021C8FA0>, type = PolygonChunk, refcount = 6 Node = <0000000002169490>, refcount = 1 Core = <0000000002285620>, type = Geometry, refcount = 1 Material = <0000000002235AE0>, type = ChunkMaterial, refcount = 1 Chunk = <00000000022116D0>, type = MaterialChunk, refcount = 2 Ambient: 0, 1, 0, 1 Diffuse: 0, 1, 0, 1 Specular: 0, 1, 0, 1 Emission: 0, 1, 0, 1 Chunk = <00000000021C8FA0>, type = PolygonChunk, refcount = 6 Node = <0000000002168F40>, refcount = 1 Core = <00000000022857B0>, type = Geometry, refcount = 1 Material = <0000000002235D80>, type = ChunkMaterial, refcount = 1 Chunk = <0000000002211840>, type = MaterialChunk, refcount = 2 Ambient: 0, 0, 1, 1 Diffuse: 0, 0, 1, 1 Specular: 0, 0, 1, 1 Emission: 0, 0, 1, 1 Chunk = <00000000021C8FA0>, type = PolygonChunk, refcount = 6
#include "OSBViewer.h" //what follows here is the smallest OpenSG programm possible //most things used here are explained now or on the next few pages, so don't //worry if not everything is clear right at the beginning... //Some needed include files - these will become more, believe me ;) #include <OpenSG/OSGConfig.h> #include <OpenSG/OSGGLUT.h> #include <OpenSG/OSGGLUTWindow.h> #include <OpenSG/OSGChunkMaterial.h> #include <OpenSG/OSGGeometry.h> #include <OpenSG/OSGGeoProperties.h> #include <OpenSG/OSGMaterialChunk.h> #include <OpenSG/OSGMaterialGroup.h> #include <OpenSG/OSGMatrix.h> #include <OpenSG/OSGPolygonChunk.h> #include <OpenSG/OSGSimpleGeometry.h> #include <OpenSG/OSGSimpleSceneManager.h> #include <OpenSG/OSGSceneFileHandler.h> #include <OpenSG/OSGTransform.h> #include <cstdlib> #include <cstring> #include <iostream> //In most cases it is useful to add this line, otherwise every OpenSG command //must be preceeded by an extra OSG:: OSG_USING_NAMESPACE //The SimpleSceneManager is a useful class which helps us to //manage simple configurations. It will be discussed in detail later on SimpleSceneManager *mgr; //we have a forward declaration here, just to have a better order //of codepieces int setupGLUT( int *argc, char *argv[] ); bool isOSBFileName (const char * arg); NodeUnrecPtr loadScene (const char * osbfilename); void makeTestScene (const char * osbfilename); NodeUnrecPtr makeTestGeometry (Pnt3f ctr, Color4f clr, PolygonChunk * shared_polygon_chunk, bool use_material_group); PolygonChunkUnrecPtr makePolygonChunk (); void dump (OSG::Node * node, unsigned int indent); void dump (OSG::NodeCore * core, unsigned int indent); void dump (OSG::Geometry * core, unsigned int indent); void dump (OSG::MaterialGroup * core, unsigned int indent); void dump (OSG::Material * mtl, unsigned int indent); //============================================================================ int main(int argc, char *argv[]) { // Init the OpenSG subsystem preloadSharedObject ("OSGFileIO"); preloadSharedObject ("OSGImageFileIO"); osgInit(argc,argv); // We open a new scope here to make sure the pointers inside it go out of // scope before entering glutMainLoop. // This is necessary since in general glutMainLoop does not return and // therefore these pointers would never destroyed otherwise. { // We create a GLUT Window (that is almost the same for most applications) int winid = setupGLUT(&argc, argv); GLUTWindowUnrecPtr gwin = GLUTWindow::create(); gwin->setGlutId(winid); gwin->init(); NodeUnrecPtr scene; // We load a ".osb" file if one is specified. if (argc > 1 && isOSBFileName (argv[1])) scene = loadScene (argv[1]); // This will be our whole scene for now : an incredible torus else { // scene = makeTorus(.5, 2, 16, 16); const char * osbfilename = "OSBViewerTestScene.osb"; makeTestScene (osbfilename); scene = loadScene (osbfilename); } // Create and setup our little friend - the SSM mgr = new SimpleSceneManager; mgr->setWindow(gwin); mgr->setRoot(scene); mgr->showAll(); } // Give Control to the GLUT Main Loop glutMainLoop(); return EXIT_SUCCESS; } //============================================================================ // react to size changes void reshape(int w, int h) { mgr->resize(w, h); glutPostRedisplay(); } //============================================================================ // just redraw our scene if this GLUT callback is invoked void display(void) { mgr->redraw(); } //============================================================================ // react to mouse motions with pressed buttons void motion(int x, int y) { mgr->mouseMove(x, y); glutPostRedisplay(); } //============================================================================ // react to mouse button presses void mouse(int button, int state, int x, int y) { if (state) mgr->mouseButtonRelease(button, x, y); else mgr->mouseButtonPress(button, x, y); glutPostRedisplay(); } //============================================================================ // The GLUT subsystem is set up here. This is very similar to other GLUT // applications. If you have worked with GLUT before, you may have the // feeling of meeting old friends again, if you have not used GLUT before // that is no problem. GLUT will be introduced briefly on the next section int setupGLUT(int *argc, char *argv[]) { glutInit(argc, argv); glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); int winid = glutCreateWindow("OpenSG First Application"); // register the GLUT callback functions glutDisplayFunc(display); glutReshapeFunc(reshape); glutMotionFunc(motion); glutMouseFunc(mouse); return winid; } //============================================================================ bool isOSBFileName (const char * arg) { bool result (false); if (arg) { unsigned int arglen = std::strlen (arg); if (arglen > 4) { const char * sfx = arg + arglen - 4; if (std::strcmp (sfx, ".osb") == 0) result = true; } } return result; } //============================================================================ NodeUnrecPtr loadScene (const char * osbfilename) { NodeUnrecPtr file_root = OSG::SceneFileHandler::the()->read (osbfilename, NULL, NULL); commitChanges(); std::cerr << "\nRead scene graph:\n" << std::endl; dump (file_root, 1); file_root->updateVolume(); Vec3f min, max; file_root->getVolume().getBounds (min, max); Vec3f ctr = (max - min) * 0.5; Matrix4f mtx; mtx.setIdentity(); float area_xy = (max[0] - min[0]) * (max[1] - min[1]); float area_xz = (max[0] - min[0]) * (max[2] - min[2]); float area_yz = (max[1] - min[1]) * (max[2] - min[2]); if (area_xy >= area_xz && area_xy >= area_yz) { mtx[3][0] = -ctr[0]; mtx[3][1] = -ctr[1]; mtx[3][2] = -ctr[2]; } else if (area_xz >= area_yz) { mtx[1][1] = 0.f; mtx[2][1] = -1.f; // y' = -z mtx[1][2] = 1.f; // z' = y mtx[2][2] = 0.f; mtx[3][0] = -ctr[0]; mtx[3][1] = ctr[2]; mtx[3][2] = -ctr[1]; } else { mtx[0][0] = 0.f; mtx[2][0] = -1.f; // x' = -z mtx[0][2] = 1.f; // z' = x mtx[2][2] = 0.f; mtx[3][0] = ctr[2]; mtx[3][1] = -ctr[1]; mtx[3][2] = -ctr[0]; } TransformUnrecPtr trf = Transform::create(); trf->setMatrix (mtx); NodeUnrecPtr scene = Node::create(); scene->setCore (trf); scene->addChild (file_root); return scene; } //============================================================================ void makeTestScene (const char * osbfilename) { // This creates and writes a scene graph and OSB file with a structure // analogous to what JugularGIS creates, in an attempt to understand why // the materials don't render properly. // // This has simpler geometry with non-overlapping bounding boxes, and is // constructed in the most straightforward way possible. NodeUnrecPtr root_node = Node::create(); TransformUnrecPtr root_core = Transform::create(); root_node->setCore (root_core); Matrix4f mtx; mtx.setIdentity(); root_core->setMatrix (mtx); NodeUnrecPtr layer_node = Node::create(); GroupUnrecPtr layer_core = Group::create(); layer_node->setCore (layer_core); root_node->addChild (layer_node); bool USE_SHARED_POLYGON_CHUNK = true; bool USE_MATERIAL_GROUP = false; PolygonChunkUnrecPtr polygon_chunk = NULL; if (USE_SHARED_POLYGON_CHUNK) polygon_chunk = makePolygonChunk(); layer_node->addChild (makeTestGeometry (Pnt3f (-1.f, 0.f, 0.f), Color4f (1.f, 0.f, 0.f, 1.f), polygon_chunk, USE_MATERIAL_GROUP)); layer_node->addChild (makeTestGeometry (Pnt3f ( 0.f, 0.f, 0.f), Color4f (0.f, 1.f, 0.f, 1.f), polygon_chunk, USE_MATERIAL_GROUP)); layer_node->addChild (makeTestGeometry (Pnt3f ( 1.f, 0.f, 0.f), Color4f (0.f, 0.f, 1.f, 1.f), polygon_chunk, USE_MATERIAL_GROUP)); commitChanges (); OSG::SceneFileHandler::the()->write (root_node, osbfilename, false); std::cerr << "\nWrote scene graph:\n" << std::endl; dump (root_node, 1); } //============================================================================ NodeUnrecPtr makeTestGeometry (Pnt3f ctr, Color4f clr, PolygonChunk * shared_polygon_chunk, bool use_material_group) { GeoUInt8PropertyUnrecPtr type_prop = GeoUInt8Property ::create(); GeoUInt32PropertyUnrecPtr length_prop = GeoUInt32Property::create(); GeoPnt3fPropertyUnrecPtr position_prop = GeoPnt3fProperty ::create(); GeoUInt32PropertyUnrecPtr index_prop = GeoUInt32Property::create(); GeoPnt3fProperty::StoredFieldType * position = position_prop->editFieldPtr(); position->push_back (ctr + Vec3f (-0.4f, -0.4f, 0.f)); position->push_back (ctr + Vec3f ( 0.4f, -0.4f, 0.f)); position->push_back (ctr + Vec3f ( 0.4f, 0.4f, 0.f)); position->push_back (ctr + Vec3f (-0.4f, 0.4f, 0.f)); GeoUInt32Property::StoredFieldType * index = index_prop->editFieldPtr(); index->push_back (0); index->push_back (1); index->push_back (2); index->push_back (0); index->push_back (2); index->push_back (3); GeoUInt32Property::StoredFieldType * length = length_prop->editFieldPtr(); length->push_back (index->size()); GeoUInt8Property::StoredFieldType * type = type_prop->editFieldPtr(); type->push_back (GL_TRIANGLES); MaterialChunkUnrecPtr mc = MaterialChunk::create(); mc->setLit (false); mc->setColorMaterial (GL_NONE); mc->setDiffuse (clr); mc->setAmbient (clr); mc->setSpecular (clr); mc->setEmission (clr); mc->setShininess (1.f); mc->setBackMaterial (false); mc->setBackColorMaterial (GL_NONE); mc->setBackDiffuse (clr); mc->setBackAmbient (clr); mc->setBackSpecular (clr); mc->setBackEmission (clr); mc->setBackShininess (1.f); PolygonChunkUnrecPtr pc = shared_polygon_chunk; if (! pc) pc = makePolygonChunk(); ChunkMaterialUnrecPtr mtl = ChunkMaterial::create(); mtl->addChunk (mc); mtl->addChunk (pc); GeometryUnrecPtr geo = Geometry::create(); geo->setTypes (type_prop); geo->setLengths (length_prop); geo->setPositions (position_prop); geo->setIndices (index_prop); NodeUnrecPtr top_node = Node::create(); if (use_material_group) { NodeUnrecPtr geo_node = Node::create(); geo_node->setCore (geo); MaterialGroupUnrecPtr grp = MaterialGroup::create(); grp->setMaterial (mtl); top_node->setCore (grp); top_node->addChild (geo_node); } else { geo->setMaterial (mtl); top_node->setCore (geo); } return top_node; } //============================================================================ PolygonChunkUnrecPtr makePolygonChunk () { PolygonChunkUnrecPtr polygon_chunk = PolygonChunk::create(); polygon_chunk->setCullFace (GL_NONE); polygon_chunk->setFrontFace (GL_CCW); polygon_chunk->setFrontMode (GL_FILL); polygon_chunk->setBackMode (GL_FILL); polygon_chunk->setSmooth (true); polygon_chunk->setOffsetFactor (0.f); polygon_chunk->setOffsetBias (0.f); polygon_chunk->setOffsetPoint (false); polygon_chunk->setOffsetLine (false); polygon_chunk->setOffsetFill (false); return polygon_chunk; } //============================================================================ void dump (OSG::Node * node, unsigned int indent) { for (unsigned int i = 0 ; i < indent ; ++i) std::cerr << " "; if (! node) { std::cerr << "Node = <null>" << std::endl; return; } std::cerr << "Node = <" << node << ">, refcount = " << node->getRefCount() << std::endl; ++indent; dump (node->getCore(), indent); if (node->getNChildren() > 0) { for (unsigned int i = 0 ; i < indent ; ++i) std::cerr << " "; std::cerr << "Children:" << std::endl; for (unsigned int i = 0 ; i < node->getNChildren() ; ++i) dump (node->getChild(i), indent+1); } } //============================================================================ void dump (OSG::NodeCore * core, unsigned int indent) { for (unsigned int i = 0 ; i < indent ; ++i) std::cerr << " "; if (! core) { std::cerr << "Core = <null>" << std::endl; return; } std::cerr << "Core = <" << core << ">, type = " << core->getType().getName() << ", refcount = " << core->getRefCount() << std::endl; if (core->getType().isDerivedFrom (OSG::Geometry::getClassType())) dump (static_cast<OSG::Geometry *>(core), indent+1); else if (core->getType().isDerivedFrom (OSG::MaterialGroup::getClassType())) dump (static_cast<OSG::MaterialGroup *>(core), indent+1); } //============================================================================ void dump (OSG::Geometry * core, unsigned int indent) { if (! core) return; dump (core->getMaterial(), indent); } //============================================================================ void dump (OSG::MaterialGroup * core, unsigned int indent) { if (! core) return; dump (core->getMaterial(), indent); } //============================================================================ void dump (OSG::Material * mtl, unsigned int indent) { for (unsigned int i = 0 ; i < indent ; ++i) std::cerr << " "; if (! mtl) { std::cerr << "Material = <null>" << std::endl; return; } std::cerr << "Material = <" << mtl << ">, type = " << mtl->getType().getName() << ", refcount = " << mtl->getRefCount() << std::endl; if (mtl->getType().isDerivedFrom (OSG::ChunkMaterial::getClassType())) { ++indent; const OSG::MFUnrecStateChunkPtr * chunkfield = (static_cast<OSG::ChunkMaterial *>(mtl))->getMFChunks(); for (unsigned int j = 0 ; j < chunkfield->size() ; ++j) { OSG::StateChunk * chunk = (*chunkfield)[j]; for (unsigned int i = 0 ; i < indent ; ++i) std::cerr << " "; if (! chunk) { std::cerr << "Chunk = <null>" << std::endl; continue; } std::cerr << "Chunk = <" << chunk << ">, type = " << chunk->getType().getName() << ", refcount = " << chunk->getRefCount() << std::endl; if (chunk->getType().isDerivedFrom (OSG::MaterialChunk::getClassType())) { unsigned int color_indent = indent + 1; OSG::Color4f color; for (unsigned int i = 0 ; i < color_indent ; ++i) std::cerr << " "; color = static_cast<OSG::MaterialChunk *>(chunk)->getAmbient(); std::cerr << "Ambient: " << color[0] << ", " << color[1] << ", " << color[2] << ", " << color[3] << std::endl; for (unsigned int i = 0 ; i < color_indent ; ++i) std::cerr << " "; color = static_cast<OSG::MaterialChunk *>(chunk)->getDiffuse(); std::cerr << "Diffuse: " << color[0] << ", " << color[1] << ", " << color[2] << ", " << color[3] << std::endl; for (unsigned int i = 0 ; i < color_indent ; ++i) std::cerr << " "; color = static_cast<OSG::MaterialChunk *>(chunk)->getSpecular(); std::cerr << "Specular: " << color[0] << ", " << color[1] << ", " << color[2] << ", " << color[3] << std::endl; for (unsigned int i = 0 ; i < color_indent ; ++i) std::cerr << " "; color = static_cast<OSG::MaterialChunk *>(chunk)->getEmission(); std::cerr << "Emission: " << color[0] << ", " << color[1] << ", " << color[2] << ", " << color[3] << std::endl; } } } }
//============================================================================ // University of Michigan 3D Lab // u...@umich.edu // http://um3d.dc.umich.edu/ // // Copyright (C) 2001-2010, University of Michigan 3D Lab //============================================================================ #pragma once // The minimum required platform is Windows Vista. #define WINVER 0x0600 #define _WIN32_WINNT 0x0600 // Remove the Microsoft min/max abomination. #define NOMINMAX // OpenSG debugging. #ifdef _DEBUG #define OSG_DEBUG #endif // <OpenSG/OSGConfigured.h> unconditionally does // // #define OSG_DISABLE_MICROSOFT_SECURE_CXXX 1 // // <OpenSG/OSGConfig.h> requires these for consistency: #define _CRT_SECURE_NO_DEPRECATE 1 #define _CRT_SECURE_NO_WARNINGS 1 #define _CRT_NONSTDC_NO_DEPRECATE 1 #define _SECURE_SCL 0 #define _SCL_SECURE_NO_WARNINGS 1 #define _SCL_SECURE_NO_DEPRECATE 1 #define _HAS_ITERATOR_DEBUGGING 0 // FreeGLUT lib pragmas. #define FREEGLUT_LIB_PRAGMAS 0 // Suppress numerous warnings from OpenSG headers. #pragma warning( disable : 4005 ) // macro redefinition #pragma warning( disable : 4099 ) // looking for VC6 #pragma warning( disable : 4231 ) // ignoring "extern" warning for templates #pragma warning( disable : 4244 ) // int64 -> float loss of precision #pragma warning( disable : 4251 ) // needs dll-interface to be used #pragma warning( disable : 4267 ) // size_t -> unsigned int #pragma warning( disable : 4275 ) // non dll-interface class as base #pragma warning( disable : 4290 ) // exception spec ignored #pragma warning( disable : 4312 ) // uint -> void* #pragma warning( disable : 4351 ) // array elements default initialized #pragma warning( disable : 4541 ) // dynamic cast on polymorphic type #pragma warning( disable : 4800 ) // forcing value to bool true or false #pragma warning( disable : 4996 ) // sprintf may be unsafe // Library linkage. #pragma comment(lib,"opengl32.lib") #pragma comment(lib,"glu32.lib") #pragma comment(lib,"comctl32.lib") #pragma comment(lib,"wsock32.lib") #pragma comment(lib,"Ws2_32.lib") #ifdef _DEBUG //debug libraries #pragma comment(lib,"OSGBaseD.lib") #pragma comment(lib,"OSGClusterD.lib") #pragma comment(lib,"OSGDrawableD.lib") #pragma comment(lib,"OSGUtilD.lib") #pragma comment(lib,"OSGWindowD.lib") #pragma comment(lib,"OSGWindowGLUTD.lib") #pragma comment(lib,"OSGFileIOD.lib") #pragma comment(lib,"OSGGroupD.lib") #pragma comment(lib,"OSGStateD.lib") #pragma comment(lib,"OSGSystemD.lib") #pragma comment(lib,"OSGTextD.lib") #pragma comment(lib,"OSGWindowWIN32D.lib") #pragma comment(lib,"OSGEffectGroupsD.lib") #pragma comment(lib,"osgfreeglutD.lib") #else //release libraries #pragma comment(lib,"OSGBase.lib") #pragma comment(lib,"OSGCluster.lib") #pragma comment(lib,"OSGDrawable.lib") #pragma comment(lib,"OSGUtil.lib") #pragma comment(lib,"OSGWindow.lib") #pragma comment(lib,"OSGWindowGLUT.lib") #pragma comment(lib,"OSGFileIO.lib") #pragma comment(lib,"OSGGroup.lib") #pragma comment(lib,"OSGState.lib") #pragma comment(lib,"OSGSystem.lib") #pragma comment(lib,"OSGText.lib") #pragma comment(lib,"OSGWindowWIN32.lib") #pragma comment(lib,"OSGEffectGroups.lib") #pragma comment(lib,"osgfreeglut.lib") #endif
------------------------------------------------------------------------------ Virtualization & Cloud Management Using Capacity Planning Cloud computing makes use of virtualization - but cloud computing also focuses on allowing computing to be delivered as a service. http://www.accelacomm.com/jaw/sfnl/114/51521223/
_______________________________________________ Opensg-users mailing list Opensg-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/opensg-users