Thank you Carsten!
The example now also works for me!
BUT... going on with the implementation in my software, I noticed two more
problems:
1) Terrain lighting (and/or normals) is not right, because the terrain
lighting changes as I move the camera (the camera is in the origin and the
world moves by its inverse transform, indeed).
2) The terrain is not correctly rendered in a cluster environment.
In the program I have a WIN32Window (local viewport) and
a MultiDisplayWindow (for cluster visualization).
2a)
In my render loop I usually did things in this order:
MasterApplication::update()
{
changeTheScenegraph();
Thread::getCurrentChangeList()->commitChanges();
MultiDisplayWindow->render();
WIN32Window->render();
Thread::getCurrentChangeList()->clear();
}
If I do this, the result is a wrong rendered terrain: the geometry and the
triangles are not correct. You can see the result by looking at one of the
screenshot I made:
https://www.dropbox.com/s/49sgu7ywf2oqwkt/screenshot000.jpg
https://www.dropbox.com/s/4h681pqcpo9lc29/screenshot002.jpg
https://www.dropbox.com/s/q8kio1cquyzdsea/screenshot007.jpg
2b)
In the case I change the loop to:
MasterApplication::update()
{
changeTheScenegraph();
MultiDisplayWindow->render();
WIN32Window->render();
Thread::getCurrentChangeList()->commitChangesAndClear();
}
, the terrain is correctly rendered (except for lighting) on the WIN32Window,
but on the MultiDisplayWindow the terrain still looks like in the
screenshots.
Any help would really, really be appreciated :)
Thanks again in advance,
Christian Bar
-------------------------------------------------------------------------------------------------------------------------------------------
Hello Christian,
On 07/18/2014 04:02 PM, Christian Bar wrote:
> I tried to specify the eye point in local coordinates, in global, or in
random positions, but the result is never the correct one...
> I made an update to my little test program, now you can also use and move
the eye point.
thanks for the updated program!
> The weirdest thing (to me) is that the terrain starts to show all its
patches when the sum of the absolute x,y,z of the eye point exceed
2000~2100...
I think/hope that was just a (really weird) coincidence ;)
AFAICS the problem was that the camera frustum was not transformed to
local coordinates, so the culling of terrain parts used the wrong
frustum to test against.
There also was something quite fishy in our Plane::transform()
implementation, the whole thing only started to work after I replaced
that with a text book implementation [1].
I'm attaching a patch that makes your example work for me, could you
give it a try with your real application and let me know if that is
fixed as well? Thanks!
Cheers,
Carsten
[1] I'm not quite sure what the previous code was trying to do and if it
perhaps attempted to be more efficient, but mainly it did not seem to
produce correct results... ;)
On Fri, Jul 18, 2014 at 4:02 PM, Christian Bar <ch....@tiscali.it> wrote:
> Thank you Carsten!
>
> I tried to specify the eye point in local coordinates, in global, or in
> random positions, but the result is never the correct one...
>
> I made an update to my little test program, now you can also use and move the
> eye point.
>
> You can see what I mean if you:
>
> - start the test program,
>
> - press '1' to set the camera in the origin and the terrain in (-15,15-30) in
> order to be seen by the camera
>
> - press '3' to start using the eye point for the terrain
>
> - play with 'j,l,i,k,u,o' to move the eye point and see how the terrain
> rendering changes.
>
> The weirdest thing (to me) is that the terrain starts to show all its patches
> when the sum of the absolute x,y,z of the eye point exceed 2000~2100...
>
> Best regards,
>
> Christian Bar
>
>
> Below the code:
>
> "
>
>
> #include <OSGGLUT.h>
> #include <OSGConfig.h>
> #include <OSGSimpleGeometry.h>
> #include <OSGGLUTWindow.h>
> #include <OSGSolidBackground.h>
> #include <OSGDirectionalLight.h>
> #include <OSGPerspectiveCamera.h>
> #include <OSGTransform.h>
> #include <OSGRenderAction.h>
> #include <OSGViewport.h>
> #include <OSGGradientBackground.h>
> #include <OSGTextureBackground.h>
> #include <OSGTextureObjChunk.h>
> #include <OSGImage.h>
> #include <OSGImageForeground.h>
> #include <OSGFileGrabForeground.h>
> #include "OSGQuadTreeTerrain.h"
> #include "OSGImageFileHandler.h"
> #include "OSGChunkMaterial.h"
> #include "OSGMaterialChunk.h"
> #include "OSGTextureObjChunk.h"
> #include "OSGTextureEnvChunk.h"
>
> #define ROT 0.1f;
> #define TRASL 1.f;
>
> bool updateCameraPos=false;
> bool eye=false;
> float tx=-15.f;
> float ty=15.f;
> float tz=-30.f;
> float rx=3.1415f/2.f;
> float ry=0.f;
> float rz=0.f;
> float tex=0.f,tey=0.f,tez=0.f;
> OSG::TransformRecPtr terrainTransCore;
> OSG::NodeRecPtr scene;
> OSG::QuadTreeTerrainUnrecPtr terrain;
> OSG::PerspectiveCameraRecPtr camera;
> OSG::TransformRecPtr camTrans;
> OSG::ViewportRecPtr viewport;
> OSG::WindowRecPtr window;
> OSG::NodeRecPtr camBeacon, lightBeacon, lightNode;
> OSG::RenderActionRefPtr renderAction;
>
> int setupGLUT(int *argc, char *argv[]);
>
> OSG::MaterialTransitPtr makeTexture (const char* texname)
> {
> OSG::ImageUnrecPtr image = OSG::ImageFileHandler::the()->read(texname);
>
> SLOG << "Create ChunkMaterial" << std::endl;
>
> OSG::ChunkMaterialUnrecPtr texMatPtr = OSG::ChunkMaterial
> ::create();
> OSG::TextureObjChunkUnrecPtr texChunkPtr =
> OSG::TextureObjChunk::create();
> OSG::TextureEnvChunkUnrecPtr texEnvChunkPtr =
> OSG::TextureEnvChunk::create();
> OSG::MaterialChunkUnrecPtr phongChunk = OSG::MaterialChunk
> ::create();
>
> phongChunk->setDiffuse (OSG::Color4f(1.0f, 1.0f, 1.0f, 1.0f));
> phongChunk->setAmbient (OSG::Color4f(0.1f, 0.1f, 0.1f, 1.0f));
> phongChunk->setSpecular(OSG::Color4f(0.2f, 0.2f, 0.2f, 1.0f));
> phongChunk->setShininess(6);
>
> texChunkPtr->setImage ( image);
> texChunkPtr->setWrapS ( GL_CLAMP );
> texChunkPtr->setWrapT ( GL_CLAMP );
> texChunkPtr->setWrapR ( GL_CLAMP );
>
> texChunkPtr->setMinFilter ( GL_LINEAR );
> texChunkPtr->setMagFilter ( GL_LINEAR );
>
> texEnvChunkPtr->setEnvMode(GL_MODULATE);
>
> texMatPtr->addChunk(texChunkPtr, 0);
> texMatPtr->addChunk(texEnvChunkPtr, 0);
> texMatPtr->addChunk(phongChunk);
>
> return OSG::MaterialTransitPtr(texMatPtr);
> }
>
> OSG::NodeTransitPtr createScenegraph(void)
> {
> OSG::NodeRecPtr torus = OSG::makeTorus(1,5,8,16);
>
> // create the terrain
> OSG::ImageUnrecPtr height;
> OSG::MaterialUnrecPtr mat;
> mat = makeTexture("Default_TexMap.png");
> height = OSG::ImageFileHandler::the()->read("Default_HeightMap.png");
> terrain = OSG::QuadTreeTerrain::create();
> terrain->setHeightData(height);
> terrain->setMaterial(mat);
> terrain->setVertexSpacing(30.0f/256.0f);
> terrain->setHeightScale (5.0f);
> terrain->setGeoMorphing(true);
> terrain->setDetail (25.0f);
> OSG::NodeRecPtr scenet = OSG::Node::create();
> scenet->setCore(terrain);
>
> terrainTransCore = OSG::Transform::create();
> OSG::NodeRecPtr terrTrans = OSG::makeNodeFor(terrainTransCore);
> torus->addChild(terrTrans);
> OSG::Matrix terrainMat;
> terrainMat.setTransform(OSG::Vec3f( 0, 0, 0),
> OSG::Quaternion(OSG::Vec3f(0,1,0),0));
> terrainTransCore->setMatrix(terrainMat);
> terrTrans->addChild(scenet);
>
> //create transformations & beacons for cameras & light
> camBeacon = OSG::Node::create();
> lightBeacon = OSG::Node::create();
>
> OSG::TransformRecPtr lightTrans;
> camTrans = OSG::Transform::create();
> lightTrans = OSG::Transform::create();
> OSG::Matrix camMat, lightM;
> camMat.setIdentity();
> lightM.setIdentity();
> camTrans->setMatrix(camMat);
> lightTrans->setMatrix(lightM);
>
> camBeacon->setCore(camTrans);
> lightBeacon->setCore(lightTrans );
>
> //create the light source
> OSG::DirectionalLightRecPtr dLight = OSG::DirectionalLight::create();
> dLight->setDirection(OSG::Vec3f(0,1,2));
> dLight->setDiffuse(OSG::Color4f(1,1,1,1));
> dLight->setAmbient(OSG::Color4f(0.2f,0.2f,0.2f,1.f));
> dLight->setSpecular(OSG::Color4f(1,1,1,1));
> dLight->setBeacon(lightBeacon);
>
> lightNode = OSG::Node::create();
> lightNode->setCore(dLight);
> lightNode->addChild(torus);
>
> // now create the root and add all children
> OSG::NodeRecPtr root = OSG::Node::create();
> root->setCore(OSG::Group::create());
> root->addChild(lightNode);
> root->addChild(camBeacon);
> root->addChild(lightBeacon);
>
> return OSG::NodeTransitPtr(root);
> }
>
> int main(int argc, char **argv)
> {
> OSG::preloadSharedObject("OSGFileIO");
> OSG::preloadSharedObject("OSGImageFileIO");
> OSG::osgInit(argc,argv);
>
> int winid = setupGLUT(&argc, argv);
> scene = createScenegraph();
>
> //create camera, background, viewport, render action, window
> camera = OSG::PerspectiveCamera::create();
> camera->setBeacon(camBeacon);
> camera->setFov(OSG::osgDegree2Rad(90.0f));
> camera->setNear(0.1f);
> camera->setFar(100.f);
>
> OSG::GradientBackgroundRecPtr bkg = OSG::GradientBackground::create();
> bkg->addLine(OSG::Color3f(0.5f,0.5f,0.5f),0);
> bkg->addLine(OSG::Color3f(1,1,1),1);
>
> viewport = OSG::Viewport::create();
> viewport->setCamera(camera);
> viewport->setBackground(bkg);
> viewport->setRoot(scene);
> viewport->setSize(0,0,1,1);
>
> renderAction = OSG::RenderAction::create();
> OSG::GLUTWindowRecPtr gwin = OSG::GLUTWindow::create();
> gwin->setGlutId(winid);
> gwin->setSize(300,300);
> window = gwin;
> window->addPort(viewport);
> window->init();
>
> printf_s("Now moving terrain, camera is in 0,0,0\n");
>
> OSG::commitChanges();
>
> glutMainLoop();
> return 0;
> }
>
> void reshape(int w, int h)
> {
> window->resize(w, h);
> glutPostRedisplay();
> }
>
> void display(void)
> {
> OSG::commitChanges();
>
> OSG::Matrix mat;
> OSG::Quaternion q;
> q.setValue(rx,ry,rz);
> mat.setTransform(OSG::Vec3f(tx,ty,tz),q);
>
> if(updateCameraPos)
> camTrans->setMatrix(mat); // 15 30 15
> -1.57
> else
> terrainTransCore->setMatrix(mat); // -15 15 -30 1.57
>
> if(eye)
> terrain->setEyePoint(OSG::Pnt3f(tex,tey,tez));
> //float e = 100.f;
> //terrain->setEyePoint(OSG::Pnt3f(OSG::osgRand()*e-e/2.f,
> OSG::osgRand()*e-e/2.f, OSG::osgRand()*e-e/2.f));
>
> window->render(renderAction);
> }
>
> void mouse(int button, int state, int x, int y)
> {
> glutPostRedisplay();
> }
>
> void motion(int x, int y)
> {
> glutPostRedisplay();
> }
>
> void keyboard(unsigned char k, int x, int y)
> {
> switch(k)
> {
> case 27:
> {
> terrain = NULL;
> terrainTransCore=NULL;
> scene = NULL;
> window = NULL;
> camera = NULL;
> viewport = NULL;
> camBeacon = NULL;
> lightBeacon = NULL;
> lightNode = NULL;
> renderAction= NULL;
> camTrans = NULL;
> OSG::osgExit();
> exit(1);
> }
> break;
> case 'a':
> tx-=TRASL;
> break;
> case 'd':
> tx+=TRASL;
> break;
> case 'w':
> ty+=TRASL;
> break;
> case 's':
> ty-=TRASL;
> break;
> case 'q':
> tz+=TRASL;
> break;
> case 'e':
> tz-=TRASL;
> break;
>
> case 'f':
> rx-=ROT;
> break;
> case 'h':
> rx+=ROT;
> break;
> case 't':
> ry+=ROT;
> break;
> case 'g':
> ry-=ROT;
> break;
> case 'r':
> rz+=ROT;
> break;
> case 'y':
> rz-=ROT;
> break;
>
> case 'j':
> tex-=10.f*TRASL;
> break;
> case 'l':
> tex+=10.f*TRASL;
> break;
> case 'i':
> tey+=10.f*TRASL;
> break;
> case 'k':
> tey-=10.f*TRASL;
> break;
> case 'u':
> tez+=10.f*TRASL;
> break;
> case 'o':
> tez-=10.f*TRASL;
> break;
>
> case '1': // move the terrain and put the camera in 0,0,0
> {
> tx=-15.f;
> ty=15.f;
> tz=-30.f;
> rx=3.1415f/2.f;
> ry=0.f;
> rz=0.f;
> updateCameraPos=false;
> OSG::Matrix mat; mat.setIdentity();
> camTrans->setMatrix(mat);
> terrainTransCore->setMatrix(mat);
> printf_s("Now moving terrain, camera is in 0,0,0\n");
> }
> break;
>
> case '2': // move the camera and put the terrain in 0,0,0
> {
> tx=15.f;
> ty=30.f;
> tz=15.f;
> rx=-3.1415f/2.f;
> ry=0.f;
> rz=0.f;
> updateCameraPos=true;
> OSG::Matrix mat; mat.setIdentity();
> camTrans->setMatrix(mat);
> terrainTransCore->setMatrix(mat);
> printf_s("Now moving camera, terrain is in 0,0,0\n");
> }
> break;
>
> case '3': // use the terrain->setEyePoint() to update the terrain
> {
> eye=!eye;
> if(eye)
> {
> terrain->setEyePointValid(true);
> printf_s("Now moving eye...\n");
> }
> else
> {
> terrain->setEyePointValid(false);
> printf_s("Now NOT moving eye...\n");
> }
> tex=0.f;
> tey=0.f;
> tez=0.f;
> }
> break;
>
> case '0': // reset camera and terrain transformations
> {
> rx=ry=rz=tx=ty=tz=0.f;
> OSG::Matrix mat; mat.setIdentity();
> camTrans->setMatrix(mat);
> terrainTransCore->setMatrix(mat);
> }
> break;
> }
> printf_s("%.1f %.1f %.1f, %.1f %.1f %.1f, %.1f %.1f %.1f\n",
> tx,ty,tz,rx,ry,rz,tex,tey,tez);
> }
>
> int setupGLUT(int *argc, char *argv[])
> {
> glutInit(argc, argv);
> glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
>
> int winid = glutCreateWindow("QuadTreeTerrain without SSM problem");
>
> glutDisplayFunc(display);
> glutMotionFunc(motion);
> glutReshapeFunc(reshape);
> glutKeyboardFunc(keyboard);
> glutIdleFunc(display);
>
> return winid;
> }
>
>
> "
>
>
>
> --------------------------------------------------------------
>
>
> On 2014-07-16 15:06, Christian Bar wrote:
> > Hello! I am experiencing a problem with the QuadTreeTerrain rendering.
> > With the test project everything works, but when I tried to implement it
> > inside my project the terrain shows just some little parts of it (also
> > with wrong triangles, this one seems like an indexing problem).
> > After lot of trials, it seems to me that the quadtree algorithm does not
> > work properly when the terrain is not in the origin of the world
> > coordinates.
>
> hmm, possible, it may never have been located anywhere but at the origin.
>
> [snip]
> > I also tried to use the 'terrain->setEyePoint()' and
> > 'terrain->setEyePointValid()', but it works (again) only if the terrain
> > is in the origin.
>
> In which coordinate system did you specify the eye point? For example
> was the eye point you set in the terrain's local coordinate system or in
> world coordinates?
>
> > What can I do to solve my problem? Thank you!
>
> My guess would be that the camera position (either the one derived from
> the active camera or the one set explicitly) are not transformed to
> local coordinates. I don't have the code in front of me right now (can
> take a look tomorrow), but my hope would be that the eye position is
> calculate only in one (or very few) places and only needs to be
> multiplied with the inverse transform of the current node.
>
> Cheers,
> Carsten
>
>
------------------------------------------------------------------------------
Want fast and easy access to all the code in your enterprise? Index and
search up to 200,000 lines of code with a free copy of Black Duck
Code Sight - the same software that powers the world's largest code
search on Ohloh, the Black Duck Open Hub! Try it now.
http://p.sf.net/sfu/bds
_______________________________________________
Opensg-users mailing list
Opensg-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/opensg-users