Hello ümit,
I want to skybox for surround my terrain! How can I do ? Which way
is the easiest? And is there any example?
I don't believe there is any example of this in OSG right now. This
has come up a few times recently on the list. Here is some code I
developed to create a skybox out of a vertical cross cubemap, like the
ones you can find on http://www.debevec.org/Probes/ . I hope it is
useful.
To use it:
osg::Node* skybox = createSkyBoxCubeMap(filename);
Then put the returned node under your scene root. Optionally, you can
pass a stateset as second argument, which will be used on the cubemap,
and then you can change the cubemap image at run time. This was used
in my Masters project. But the default second argument of zero will
just create a stateset.
The filename must be a vertical cross cubemap. It can be in HDR format
or any other format that OSG supports. HDR images will be clamped (no
tone mapping is done).
One note: I have found that using the cubemaps on debevec.org, I had
to resize them down by 1 pixel (they are 1024x1365, resize it to
1023x1364) so that the dimensions are divisible by the number of
images in each direction (3 horizontally, 4 vertically). You can use
HDRShop (available at http://projects.ict.usc.edu/graphics/HDRShop/)
to resize HDR images. YMMV.
This could be modified to use 6 images, and would actually be much
simpler, as most of the code relates to extracting the 6 faces from
the vertical cross, and then rotating/mirroring them correctly so they
appear on the skybox in the correct orientation.
Hope this helps,
J-S
--
______________________________________________________
Jean-Sebastien Guay [EMAIL PROTECTED]
http://whitestar02.webhop.org/
----------------------------------------------------------------
This message was sent using IMP, the Internet Messaging Program.
//---------------------------------------------------------------------------
// (c) 2006-2008 Jean-S�bastien Guay
//
// This code will create a skybox in OpenSceneGraph. The core of it comes
// from Farshid Lashkari <flashk_at_gmail.com> - see
// http://openscenegraph.org/archiver/osg-users/2005-June/0581.html
//
// I added the functionality to be able to extract the six cube face
// textures from a vertical cross texture such as the ones on
// http://www.debevec.org/Probes/.
//
// This code is distributed in the hope it will be useful, but without
// any warranty whatsoever. You may use it in any project, as well as modify
// it without restriction, as long as this notice is retained in the
// relevant files.
//---------------------------------------------------------------------------
#ifndef __SKYBOX_H__
#define __SKYBOX_H__ 1
#include <string>
#include <osg/Node>
osg::Node* createSkyBoxCubeMap(const std::string& cubemap, osg::StateSet*
stateset = 0);
#endif
//---------------------------------------------------------------------------
// (c) 2006-2008 Jean-S�bastien Guay
// This code is distributed in the hope it will be useful, but without
// any warranty whatsoever. You may use it in any project, as well as modify
// it without restriction, as long as this notice is retained in the
// relevant files.
//---------------------------------------------------------------------------
#include "Skybox.h"
#include <iostream>
#include <cassert>
#include <osg/Geometry>
#include <osg/Depth>
#include <osg/TextureCubeMap>
#include <osg/TexEnv>
#include <osgDB/ReadFile>
#include <osgUtil/CullVisitor>
#include "osgUtil.h"
class SkyboxTransform : public osg::Transform
{
public:
// Get the transformation matrix which moves from local coords to world
coords.
virtual bool computeLocalToWorldMatrix(osg::Matrix& matrix,
osg::NodeVisitor* nv) const
{
osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(nv);
if (cv)
{
osg::Vec3 eyePointLocal = cv->getEyeLocal();
matrix.preMult(osg::Matrix::translate(eyePointLocal));
}
return true;
}
// Get the transformation matrix which moves from world coords to local
coords.
virtual bool computeWorldToLocalMatrix(osg::Matrix& matrix,
osg::NodeVisitor* nv) const
{
osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(nv);
if (cv)
{
osg::Vec3 eyePointLocal = cv->getEyeLocal();
matrix.postMult(osg::Matrix::translate(-eyePointLocal));
}
return true;
}
};
osg::Node* createSkyBoxCubeMap(const std::string& cubemap, osg::StateSet*
stateset)
{
float radius = 100.0f;
if (!stateset)
stateset = new osg::StateSet;
// Set texture mode to REPLACE
osg::TexEnv* te = new osg::TexEnv;
te->setMode(osg::TexEnv::REPLACE);
stateset->setTextureAttributeAndModes(0, te, osg::StateAttribute::ON);
// Turn off lighting and cull face
stateset->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
stateset->setMode(GL_CULL_FACE, osg::StateAttribute::OFF);
// Basic principle of skyboxes: render it last, and with a depth func
// that only sets pixels at the far plane. That way, if the sky is not
// visible at all for example, the sky won't be drawn (and possibly
// fragment shaders will not be called) whereas rendering it first will
// cause all pixels to be written, then overwritten by objects, and
// possibly fragment shaders will have been called for nothing.
// Clear the depth to the far plane.
osg::Depth* depth = new osg::Depth(osg::Depth::LEQUAL, 1.0, 1.0);
stateset->setAttributeAndModes(depth, osg::StateAttribute::ON);
// Make sure it is drawn last
stateset->setRenderBinDetails(1000, "RenderBin");
// Create a drawable for the skybox
osg::Geometry* drawable = new osg::Geometry;
// Create vertices for box
osg::Vec3Array *verts = new osg::Vec3Array;
verts->push_back(osg::Vec3(-radius, -radius, radius));
verts->push_back(osg::Vec3(-radius, radius, radius));
verts->push_back(osg::Vec3( radius, radius, radius));
verts->push_back(osg::Vec3( radius, -radius, radius));
verts->push_back(osg::Vec3(-radius, -radius, -radius));
verts->push_back(osg::Vec3(-radius, radius, -radius));
verts->push_back(osg::Vec3( radius, radius, -radius));
verts->push_back(osg::Vec3( radius, -radius, -radius));
drawable->setVertexArray(verts);
// Create texture coordinates for cubemaps
osg::Vec3Array *coords = new osg::Vec3Array;
coords->push_back(osg::Vec3(-1, 1, -1));
coords->push_back(osg::Vec3(-1, -1, -1));
coords->push_back(osg::Vec3( 1, -1, -1));
coords->push_back(osg::Vec3( 1, 1, -1));
coords->push_back(osg::Vec3(-1, 1, 1));
coords->push_back(osg::Vec3(-1, -1, 1));
coords->push_back(osg::Vec3( 1, -1, 1));
coords->push_back(osg::Vec3( 1, 1, 1));
drawable->setTexCoordArray(0,coords);
// Create an index array for the box
osg::ref_ptr<osg::UIntArray> indices = new osg::UIntArray;
// Front face
indices->push_back(0);
indices->push_back(1);
indices->push_back(2);
indices->push_back(3);
// Back face
indices->push_back(4);
indices->push_back(5);
indices->push_back(6);
indices->push_back(7);
// Right face
indices->push_back(6);
indices->push_back(7);
indices->push_back(3);
indices->push_back(2);
// Left face
indices->push_back(0);
indices->push_back(1);
indices->push_back(5);
indices->push_back(4);
// Top face
indices->push_back(1);
indices->push_back(2);
indices->push_back(6);
indices->push_back(5);
// Bottom face
indices->push_back(0);
indices->push_back(3);
indices->push_back(7);
indices->push_back(4);
drawable->addPrimitiveSet(
new osg::DrawElementsUInt(GL_QUADS,
indices->size(), &(indices->front())));
// Create a geode for the skybox
osg::Geode* geode = new osg::Geode;
geode->setName("Skybox");
// Disable culling
geode->setCullingActive(false);
// Set the stateset
geode->setStateSet(stateset);
// Add the skybox
geode->addDrawable(drawable);
// Load the texture
osg::ref_ptr<osg::TextureCubeMap> texture =
loadVerticalCrossCubeMap(cubemap);
if (texture.valid())
{
texture->setResizeNonPowerOfTwoHint(false);
texture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE);
texture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE);
stateset->setTextureAttributeAndModes(0, texture.get(),
osg::StateAttribute::ON);
}
// Create a transform and set it to absolute so it does not influence
// the viewer's bounds computation (for initial camera settings).
osg::Transform* transform = new SkyboxTransform;
transform->setCullingActive(false);
transform->addChild(geode);
transform->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
transform->setName("SkyboxTransform");
return transform;
}
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org