Hello ümit,
When I look your Skybox.cpp source code I couln't see
loadVerticalCrossCubeMap(cubemap); function. Is it only read the the
textures and sending a node. Or Is there any specific process in it?
Oh, sorry, that's in another file and I had forgotten (it's been a
little while since I've touched that project...). Here are the
required files - you could just copy the functions from osgUtil.cpp
into Skybox.cpp (I had them separate because they were used in other
places too in my project).
I hope I didn't forget anything else, but there may be some
missing/superfluous includes since I stripped only the necessary
functions from my code without actually compiling to test. If there's
anything else just ping me again :-)
Sorry again,
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 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 "osgUtil.h"
#include <float.h>
#include <cassert>
#include <osg/Image>
#include <osg/TextureCubeMap>
#include <osgDB/ReadFile>
/** Implementation of copyImage. */
template<typename T>
void copyDataImpl(const osg::Image* source,
const unsigned int x1, const unsigned int y1,
const unsigned int x2, const unsigned int y2,
osg::Image* destination,
const unsigned int xd = 0, const unsigned int yd = 0,
const bool clamp = false)
{
if ((unsigned int)destination->s() >= xd + (x2 - x1) &&
(unsigned int)destination->t() >= yd + (y2 - y1))
{
const unsigned int bpps = source->getPixelSizeInBits() / (8 *
sizeof(T));
const unsigned int bppd = destination->getPixelSizeInBits() / (8 *
sizeof(T));
T* srcdata = (T*)source->data();
T* dstdata = (T*)destination->data();
for (unsigned int y = 0; y < y2 - y1; ++y)
{
for (unsigned int x = 0; x < x2 - x1; ++x)
{
T r = srcdata[(y + y1) * source->s() * bpps + (x + x1) * bpps +
0];
T g = srcdata[(y + y1) * source->s() * bpps + (x + x1) * bpps +
1];
T b = srcdata[(y + y1) * source->s() * bpps + (x + x1) * bpps +
2];
if (clamp)
{
r = osg::clampTo(r, (T)0, (T)1);
g = osg::clampTo(g, (T)0, (T)1);
b = osg::clampTo(b, (T)0, (T)1);
}
dstdata[(yd + y) * destination->s() * bppd + (xd + x) * bppd +
0] = r;
dstdata[(yd + y) * destination->s() * bppd + (xd + x) * bppd +
1] = g;
dstdata[(yd + y) * destination->s() * bppd + (xd + x) * bppd +
2] = b;
}
}
}
else
assert(false && "copyDataImpl: Incorrect image dimensions.");
}
/** Copies a rectangle of corners (x1, y1), (x2, y2) from an image into
another image starting at position (xd, yd). No scaling is done, the
pixels are just copied, so the destination image must be at least
(xd + (x2 - x1)) by (yd + (y2 - y1)) pixels. */
void copyData(const osg::Image* source,
const unsigned int x1, const unsigned int y1,
const unsigned int x2, const unsigned int y2,
osg::Image* destination,
const unsigned int xd, const unsigned int yd,
const bool clamp)
{
if (source->getDataType() == destination->getDataType())
{
if (source->getDataType() == GL_FLOAT)
{
copyDataImpl<float>(source, x1, y1, x2, y2,
destination, xd, yd, clamp);
}
else if (source->getDataType() == GL_UNSIGNED_BYTE)
{
copyDataImpl<unsigned char>(source, x1, y1, x2, y2,
destination, xd, yd, clamp);
}
else
{
assert(false && "copyData not implemented for this data type");
}
}
else
{
assert(false && "source and destination images must be of the same
type.");
return;
}
}
/** Implementation of rotateImage. */
template<typename T>
osg::Image* rotateImageImpl(osg::Image* image)
{
if (image->s() == image->t())
{
const unsigned int s = image->s();
const unsigned int bpp = image->getPixelSizeInBits() / (8 * sizeof(T));
osg::ref_ptr<osg::Image> destination = new osg::Image;
destination->allocateImage(s, s, 1,
image->getPixelFormat(), image->getDataType(),
image->getPacking());
destination->setInternalTextureFormat(image->getInternalTextureFormat());
T* srcdata = (T*)image->data();
T* dstdata = (T*)destination->data();
for (unsigned int y = 0; y < s; ++y)
{
for (unsigned int x = 0; x < s; ++x)
{
dstdata[y * s * bpp + x * bpp + 0] = srcdata[x * s * bpp + y *
bpp + 0];
dstdata[y * s * bpp + x * bpp + 1] = srcdata[x * s * bpp + y *
bpp + 1];
dstdata[y * s * bpp + x * bpp + 2] = srcdata[x * s * bpp + y *
bpp + 2];
}
}
return destination.release();
}
else
{
assert(false && "rotateImageImpl: Image must be square.");
return 0;
}
}
/** Rotates an osg::Image by 90 degrees. Returns a new osg::Image, be sure to
store it in a ref_ptr so it will be freed correctly. */
osg::Image* rotateImage(osg::Image* image)
{
if (image->getDataType() == GL_FLOAT)
{
return rotateImageImpl<float>(image);
}
else if (image->getDataType() == GL_UNSIGNED_BYTE)
{
return rotateImageImpl<unsigned char>(image);
}
else
{
assert(false && "rotateImage not implemented for this data type");
return 0;
}
}
template<typename T>
float getMaxValueImpl(const osg::Image* image)
{
const unsigned int size = image->getImageSizeInBytes() / sizeof(T);
T* data = (T*)image->data();
T maxValue = FLT_MIN;
for (unsigned int i = 0; i < size; i++)
{
if (data[i] > maxValue)
maxValue = data[i];
}
return (T)maxValue;
}
float getMaxValue(osg::Image* image)
{
if (image->getDataType() == GL_FLOAT)
{
return getMaxValueImpl<float>(image);
}
else if (image->getDataType() == GL_UNSIGNED_BYTE)
{
return 1.0f;
}
else
{
assert(false && "getMaxValue not implemented for this data type");
return 0;
}
}
osg::TextureCubeMap* loadVerticalCrossCubeMap(const std::string& filename)
{
const osg::ref_ptr<osg::Image> cross = osgDB::readImageFile(filename);
if (!cross.valid())
{
std::cout << "Image file " << filename << " could not be loaded." <<
std::endl;
return 0;
}
const GLenum pixelFormat = cross->getPixelFormat();
const GLenum dataType = cross->getDataType();
const GLint internalFormat = cross->getInternalTextureFormat();
unsigned int packing = cross->getPacking();
const unsigned int s = (unsigned int)cross->s();
const unsigned int t = (unsigned int)cross->t();
const unsigned int one_third_s = (unsigned int)(float(s) * 1/3);
const unsigned int two_thirds_s = one_third_s * 2;
const unsigned int one_quarter_t = (unsigned int)(float(t) * 1/4);
const unsigned int one_half_t = one_quarter_t * 2;
const unsigned int three_quarters_t = one_quarter_t * 3;
osg::ref_ptr<osg::TextureCubeMap> cubeMap = new osg::TextureCubeMap;
//cubeMap->setTextureSize(one_third_s, one_quarter_t);
osg::ref_ptr<osg::Image> zplus = new osg::Image;
zplus->allocateImage(one_third_s, one_quarter_t, 1,
pixelFormat, dataType, packing);
zplus->setInternalTextureFormat(internalFormat);
copyData(cross.get(), one_third_s, one_quarter_t, two_thirds_s, one_half_t,
zplus.get(), 0, 0, true);
cubeMap->setImage(osg::TextureCubeMap::POSITIVE_Z, zplus.get());
osg::ref_ptr<osg::Image> zminus = new osg::Image;
zminus->allocateImage(one_third_s, one_quarter_t, 1,
pixelFormat, dataType, packing);
zminus->setInternalTextureFormat(internalFormat);
copyData(cross.get(), one_third_s, three_quarters_t, two_thirds_s, t,
zminus.get(), 0, 0, true);
zminus->flipVertical();
zminus->flipHorizontal();
cubeMap->setImage(osg::TextureCubeMap::NEGATIVE_Z, zminus.get());
osg::ref_ptr<osg::Image> yplus = new osg::Image;
yplus->allocateImage(one_third_s, one_quarter_t, 1,
pixelFormat, dataType, packing);
yplus->setInternalTextureFormat(internalFormat);
copyData(cross.get(), one_third_s, 0, two_thirds_s, one_quarter_t,
yplus.get(), 0, 0, true);
cubeMap->setImage(osg::TextureCubeMap::POSITIVE_Y, yplus.get());
osg::ref_ptr<osg::Image> yminus = new osg::Image;
yminus->allocateImage(one_third_s, one_quarter_t, 1,
pixelFormat, dataType, packing);
yminus->setInternalTextureFormat(internalFormat);
copyData(cross.get(), one_third_s, one_half_t, two_thirds_s,
three_quarters_t, yminus.get(), 0, 0, true);
cubeMap->setImage(osg::TextureCubeMap::NEGATIVE_Y, yminus.get());
osg::ref_ptr<osg::Image> xplus = new osg::Image;
xplus->allocateImage(one_third_s, one_quarter_t, 1,
pixelFormat, dataType, packing);
xplus->setInternalTextureFormat(internalFormat);
copyData(cross.get(), two_thirds_s, one_half_t, s, three_quarters_t,
xplus.get(), 0, 0, true);
xplus = rotateImage(xplus.get());
xplus->flipVertical();
cubeMap->setImage(osg::TextureCubeMap::POSITIVE_X, xplus.get());
osg::ref_ptr<osg::Image> xminus = new osg::Image;
xminus->allocateImage(one_third_s, one_quarter_t, 1,
pixelFormat, dataType, packing);
xminus->setInternalTextureFormat(internalFormat);
copyData(cross.get(), 0, one_half_t, one_third_s, three_quarters_t,
xminus.get(), 0, 0, true);
xminus = rotateImage(xminus.get());
xminus->flipHorizontal();
cubeMap->setImage(osg::TextureCubeMap::NEGATIVE_X, xminus.get());
return cubeMap.release();
}
//---------------------------------------------------------------------------
// (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.
//---------------------------------------------------------------------------
#ifndef __OSG_UTIL_H__
#define __OSG_UTIL_H__ 1
#include <string>
#include <osg/Image>
/** Copies a rectangle of corners (x1, y1), (x2, y2) from an image into
another image starting at position (xd, yd). No scaling is done, the
pixels are just copied, so the destination image must be at least
(xd + (x2 - x1)) by (yd + (y2 - y1)) pixels. */
void copyData(const osg::Image* source,
const unsigned int x1, const unsigned int y1,
const unsigned int x2, const unsigned int y2,
osg::Image* destination,
const unsigned int xd = 0, const unsigned int yd = 0,
const bool clamp = false);
/** Rotates an osg::Image by 90 degrees. Returns a new osg::Image, be sure to
store it in a ref_ptr so it will be freed correctly. */
osg::Image* rotateImage(osg::Image* image);
/** Returns the maximum value in the image for tone mapping purposes. Only
really makes sense for HDR images, and as such if the image's pixel
format is not float it will always return 1.0. */
float getMaxValue(osg::Image* image);
osg::TextureCubeMap* loadVerticalCrossCubeMap(const std::string& filename);
#endif
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org