On Friday, March 02, 2012 12:41
johannes-bru...@arcor.de [mailto:johannes-bru...@arcor.de] wrote:
> Subject: Re: [Opensg-users] ChunkMaterial rendering woes
> what I do different from your code is that I always return OpenSG objects,
> which I have created in functions by the respective TransitPtr.
Thank you Johannes.
I've never been perfectly certain of the subtle differences between the various
pointer types. I've been frustrated in the past by compiler errors when trying
to implicitly convert between TransitPtr and other kinds of pointer, though I
never tried using an explicit constructor such as ChunkMaterialTransitPtr
(ChunkMaterialUnrecPtr).
In any case, I have now changed all of my UnrecPtr return values to TransitPtr,
but it didn't make any difference in either the text dump of the scene graph or
in the rendering. Even the reference counts appear to be the same.
For what it's worth, I'm attaching my very slightly revised source code. (You
can just overwrite the previous file with this one.)
Regards,
--
Ted
#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);
NodeTransitPtr loadScene (const char * osbfilename);
void makeTestScene (const char * osbfilename);
NodeTransitPtr makeTestGeometry (Pnt3f ctr, Color4f clr, PolygonChunk *
shared_polygon_chunk, bool use_material_group);
PolygonChunkTransitPtr 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;
}
//============================================================================
NodeTransitPtr 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);
NodeTransitPtr 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);
}
//============================================================================
NodeTransitPtr 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);
NodeTransitPtr 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;
}
//============================================================================
PolygonChunkTransitPtr makePolygonChunk ()
{
PolygonChunkTransitPtr 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;
}
}
}
}
------------------------------------------------------------------------------
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