Add clamping to 0..1 bounds for each of the r,g,b,a components in

the CubeMapGenerator::set_pixel() method.
This commit is contained in:
Robert Osfield 2004-06-04 11:35:13 +00:00
parent c69a8a5b80
commit bfd1286b25
5 changed files with 129 additions and 126 deletions

View File

@ -138,6 +138,9 @@ inline T clampAbove(T v,T minimum) { return v<minimum?minimum:v; }
template<typename T> template<typename T>
inline T clampBelow(T v,T maximum) { return v>maximum?maximum:v; } inline T clampBelow(T v,T maximum) { return v>maximum?maximum:v; }
template<typename T>
inline T clampBetween(T v,T minimum, T maximum) { return clampBelow(clampAbove(v,minimum),maximum); }
template<typename T> template<typename T>
inline T sign(T v) { return v<(T)0?(T)-1:(T)1; } inline T sign(T v) { return v<(T)0?(T)-1:(T)1; }

View File

@ -28,93 +28,93 @@
namespace osgUtil namespace osgUtil
{ {
/** This is the base class for cube map generators. /** This is the base class for cube map generators.
It exposes the necessary interface to access the six generated images; It exposes the necessary interface to access the six generated images;
descendants should only override the compute_color() method. descendants should only override the compute_color() method.
*/ */
class OSGUTIL_EXPORT CubeMapGenerator: public osg::Referenced { class OSGUTIL_EXPORT CubeMapGenerator: public osg::Referenced {
public: public:
explicit CubeMapGenerator(int texture_size = 64); explicit CubeMapGenerator(int texture_size = 64);
CubeMapGenerator(const CubeMapGenerator &copy, const osg::CopyOp &copyop = osg::CopyOp::SHALLOW_COPY); CubeMapGenerator(const CubeMapGenerator &copy, const osg::CopyOp &copyop = osg::CopyOp::SHALLOW_COPY);
inline osg::Image *getImage(osg::TextureCubeMap::Face face); inline osg::Image *getImage(osg::TextureCubeMap::Face face);
inline const osg::Image *getImage(osg::TextureCubeMap::Face face) const; inline const osg::Image *getImage(osg::TextureCubeMap::Face face) const;
/** generate the six cube images. /** generate the six cube images.
If use_osg_system is true, then the OSG's coordinate system is used instead If use_osg_system is true, then the OSG's coordinate system is used instead
of the default OpenGL one. of the default OpenGL one.
*/ */
void generateMap(bool use_osg_system = true); void generateMap(bool use_osg_system = true);
protected: protected:
virtual ~CubeMapGenerator() {} virtual ~CubeMapGenerator() {}
CubeMapGenerator &operator=(const CubeMapGenerator &) { return *this; } CubeMapGenerator &operator=(const CubeMapGenerator &) { return *this; }
inline void set_pixel(int index, int c, int r, const osg::Vec4 &color); inline void set_pixel(int index, int c, int r, const osg::Vec4 &color);
inline static osg::Vec4 vector_to_color(const osg::Vec3 &vec); inline static osg::Vec4 vector_to_color(const osg::Vec3 &vec);
/** override this method to define how colors are computed. /** override this method to define how colors are computed.
The parameter R is the reflection vector, pointing from the center of the cube. The parameter R is the reflection vector, pointing from the center of the cube.
The return value should be the RGBA color associated with that reflection ray. The return value should be the RGBA color associated with that reflection ray.
*/ */
virtual osg::Vec4 compute_color(const osg::Vec3 &R) const = 0; virtual osg::Vec4 compute_color(const osg::Vec3 &R) const = 0;
private: private:
int texture_size_; int texture_size_;
typedef std::vector<osg::ref_ptr<osg::Image> > Image_list; typedef std::vector<osg::ref_ptr<osg::Image> > Image_list;
Image_list images_; Image_list images_;
}; };
// INLINE METHODS // INLINE METHODS
inline osg::Image *CubeMapGenerator::getImage(osg::TextureCubeMap::Face face) inline osg::Image *CubeMapGenerator::getImage(osg::TextureCubeMap::Face face)
{ {
switch (face) { switch (face) {
case osg::TextureCubeMap::POSITIVE_X: return images_[0].get(); case osg::TextureCubeMap::POSITIVE_X: return images_[0].get();
case osg::TextureCubeMap::NEGATIVE_X: return images_[1].get(); case osg::TextureCubeMap::NEGATIVE_X: return images_[1].get();
case osg::TextureCubeMap::POSITIVE_Y: return images_[2].get(); case osg::TextureCubeMap::POSITIVE_Y: return images_[2].get();
case osg::TextureCubeMap::NEGATIVE_Y: return images_[3].get(); case osg::TextureCubeMap::NEGATIVE_Y: return images_[3].get();
case osg::TextureCubeMap::POSITIVE_Z: return images_[4].get(); case osg::TextureCubeMap::POSITIVE_Z: return images_[4].get();
case osg::TextureCubeMap::NEGATIVE_Z: return images_[5].get(); case osg::TextureCubeMap::NEGATIVE_Z: return images_[5].get();
default: return 0; default: return 0;
} }
} }
inline const osg::Image *CubeMapGenerator::getImage(osg::TextureCubeMap::Face face) const inline const osg::Image *CubeMapGenerator::getImage(osg::TextureCubeMap::Face face) const
{ {
switch (face) { switch (face) {
case osg::TextureCubeMap::POSITIVE_X: return images_[0].get(); case osg::TextureCubeMap::POSITIVE_X: return images_[0].get();
case osg::TextureCubeMap::NEGATIVE_X: return images_[1].get(); case osg::TextureCubeMap::NEGATIVE_X: return images_[1].get();
case osg::TextureCubeMap::POSITIVE_Y: return images_[2].get(); case osg::TextureCubeMap::POSITIVE_Y: return images_[2].get();
case osg::TextureCubeMap::NEGATIVE_Y: return images_[3].get(); case osg::TextureCubeMap::NEGATIVE_Y: return images_[3].get();
case osg::TextureCubeMap::POSITIVE_Z: return images_[4].get(); case osg::TextureCubeMap::POSITIVE_Z: return images_[4].get();
case osg::TextureCubeMap::NEGATIVE_Z: return images_[5].get(); case osg::TextureCubeMap::NEGATIVE_Z: return images_[5].get();
default: return 0; default: return 0;
} }
} }
inline void CubeMapGenerator::set_pixel(int index, int c, int r, const osg::Vec4 &color) inline void CubeMapGenerator::set_pixel(int index, int c, int r, const osg::Vec4 &color)
{ {
osg::Image *i = images_[index].get(); osg::Image *i = images_[index].get();
if (i) { if (i) {
*(i->data(c, r)+0) = static_cast<unsigned char>(color.x() * 255); *(i->data(c, r)+0) = static_cast<unsigned char>(osg::clampBetween(color.x(),0.0f,1.0f) * 255);
*(i->data(c, r)+1) = static_cast<unsigned char>(color.y() * 255); *(i->data(c, r)+1) = static_cast<unsigned char>(osg::clampBetween(color.y(),0.0f,1.0f) * 255);
*(i->data(c, r)+2) = static_cast<unsigned char>(color.z() * 255); *(i->data(c, r)+2) = static_cast<unsigned char>(osg::clampBetween(color.z(),0.0f,1.0f) * 255);
*(i->data(c, r)+3) = static_cast<unsigned char>(color.w() * 255); *(i->data(c, r)+3) = static_cast<unsigned char>(osg::clampBetween(color.w(),0.0f,1.0f) * 255);
} else { } else {
osg::notify(osg::WARN) << "Warning: CubeMapGenerator::set_pixel(): invalid image index\n"; osg::notify(osg::WARN) << "Warning: CubeMapGenerator::set_pixel(): invalid image index\n";
} }
} }
inline osg::Vec4 CubeMapGenerator::vector_to_color(const osg::Vec3 &vec) inline osg::Vec4 CubeMapGenerator::vector_to_color(const osg::Vec3 &vec)
{ {
return osg::Vec4( return osg::Vec4(
vec.x() / vec.length() / 2 + 0.5f, vec.x() / vec.length() / 2 + 0.5f,
vec.y() / vec.length() / 2 + 0.5f, vec.y() / vec.length() / 2 + 0.5f,
vec.z() / vec.length() / 2 + 0.5f, vec.z() / vec.length() / 2 + 0.5f,
1); 1);
} }
} }

View File

@ -20,43 +20,43 @@
namespace osgUtil namespace osgUtil
{ {
/** This cube map generator produces a specular highlight map. /** This cube map generator produces a specular highlight map.
The vector-color association is: C = (R dot (-L)) ^ n, where C is the The vector-color association is: C = (R dot (-L)) ^ n, where C is the
resulting color, R is the reflection vector, L is the light direction resulting color, R is the reflection vector, L is the light direction
and n is the specular exponent. and n is the specular exponent.
*/ */
class OSGUTIL_EXPORT HighlightMapGenerator: public CubeMapGenerator { class OSGUTIL_EXPORT HighlightMapGenerator: public CubeMapGenerator {
public: public:
HighlightMapGenerator( HighlightMapGenerator(
const osg::Vec3 &light_direction, const osg::Vec3 &light_direction,
const osg::Vec4 &light_color, const osg::Vec4 &light_color,
float specular_exponent, float specular_exponent,
int texture_size = 64); int texture_size = 64);
HighlightMapGenerator(const HighlightMapGenerator &copy, const osg::CopyOp &copyop = osg::CopyOp::SHALLOW_COPY); HighlightMapGenerator(const HighlightMapGenerator &copy, const osg::CopyOp &copyop = osg::CopyOp::SHALLOW_COPY);
protected: protected:
virtual ~HighlightMapGenerator() {} virtual ~HighlightMapGenerator() {}
HighlightMapGenerator &operator=(const HighlightMapGenerator &) { return *this; } HighlightMapGenerator &operator=(const HighlightMapGenerator &) { return *this; }
inline virtual osg::Vec4 compute_color(const osg::Vec3 &R) const; inline virtual osg::Vec4 compute_color(const osg::Vec3 &R) const;
private: private:
osg::Vec3 ldir_; osg::Vec3 ldir_;
osg::Vec4 lcol_; osg::Vec4 lcol_;
float sexp_; float sexp_;
}; };
// INLINE METHODS // INLINE METHODS
inline osg::Vec4 HighlightMapGenerator::compute_color(const osg::Vec3 &R) const inline osg::Vec4 HighlightMapGenerator::compute_color(const osg::Vec3 &R) const
{ {
float v = -ldir_ * (R / R.length()); float v = -ldir_ * (R / R.length());
if (v < 0) v = 0; if (v < 0) v = 0;
osg::Vec4 color(lcol_ * powf(v, sexp_)); osg::Vec4 color(lcol_ * powf(v, sexp_));
color.w() = 1; color.w() = 1;
return color; return color;
} }
} }

View File

@ -43,13 +43,13 @@ CubeMapGenerator::CubeMapGenerator(const CubeMapGenerator &copy, const osg::Copy
void CubeMapGenerator::generateMap(bool use_osg_system) void CubeMapGenerator::generateMap(bool use_osg_system)
{ {
osg::Matrix M; osg::Matrix M;
if (use_osg_system) { if (use_osg_system) {
M = osg::Matrix::rotate(osg::PI_2, osg::Vec3(1, 0, 0)); M = osg::Matrix::rotate(osg::PI_2, osg::Vec3(1, 0, 0));
} else { } else {
M = osg::Matrix::identity(); M = osg::Matrix::identity();
} }
const float dst = 2.0f/(texture_size_-1); const float dst = 2.0f/(texture_size_-1);
@ -57,7 +57,7 @@ void CubeMapGenerator::generateMap(bool use_osg_system)
for (int i=0; i<texture_size_; ++i) { for (int i=0; i<texture_size_; ++i) {
float s = -1; float s = -1;
for (int j=0; j<texture_size_; ++j) { for (int j=0; j<texture_size_; ++j) {
set_pixel(0, j, i, compute_color(osg::Vec3(1, -t, -s) * M)); set_pixel(0, j, i, compute_color(osg::Vec3(1, -t, -s) * M));
set_pixel(1, j, i, compute_color(osg::Vec3(-1, -t, s) * M)); set_pixel(1, j, i, compute_color(osg::Vec3(-1, -t, s) * M));
set_pixel(2, j, i, compute_color(osg::Vec3(s, 1, t) * M)); set_pixel(2, j, i, compute_color(osg::Vec3(s, 1, t) * M));
set_pixel(3, j, i, compute_color(osg::Vec3(s, -1, -t) * M)); set_pixel(3, j, i, compute_color(osg::Vec3(s, -1, -t) * M));

View File

@ -15,21 +15,21 @@
using namespace osgUtil; using namespace osgUtil;
HighlightMapGenerator::HighlightMapGenerator(const osg::Vec3 &light_direction, HighlightMapGenerator::HighlightMapGenerator(const osg::Vec3 &light_direction,
const osg::Vec4 &light_color, const osg::Vec4 &light_color,
float specular_exponent, float specular_exponent,
int texture_size) int texture_size)
: CubeMapGenerator(texture_size), : CubeMapGenerator(texture_size),
ldir_(light_direction), ldir_(light_direction),
lcol_(light_color), lcol_(light_color),
sexp_(specular_exponent) sexp_(specular_exponent)
{ {
ldir_.normalize(); ldir_.normalize();
} }
HighlightMapGenerator::HighlightMapGenerator(const HighlightMapGenerator &copy, const osg::CopyOp &copyop) HighlightMapGenerator::HighlightMapGenerator(const HighlightMapGenerator &copy, const osg::CopyOp &copyop)
: CubeMapGenerator(copy, copyop), : CubeMapGenerator(copy, copyop),
ldir_(copy.ldir_), ldir_(copy.ldir_),
lcol_(copy.lcol_), lcol_(copy.lcol_),
sexp_(copy.sexp_) sexp_(copy.sexp_)
{ {
} }