| 1 | /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield |
|---|
| 2 | * |
|---|
| 3 | * This library is open source and may be redistributed and/or modified under |
|---|
| 4 | * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or |
|---|
| 5 | * (at your option) any later version. The full license is in LICENSE file |
|---|
| 6 | * included with this distribution, and on the openscenegraph.org website. |
|---|
| 7 | * |
|---|
| 8 | * This library is distributed in the hope that it will be useful, |
|---|
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 11 | * OpenSceneGraph Public License for more details. |
|---|
| 12 | */ |
|---|
| 13 | #ifndef OSGUTIL_CUBEMAPGENERATOR_ |
|---|
| 14 | #define OSGUTIL_CUBEMAPGENERATOR_ |
|---|
| 15 | |
|---|
| 16 | #include <osgUtil/Export> |
|---|
| 17 | |
|---|
| 18 | #include <osg/Vec3> |
|---|
| 19 | #include <osg/Vec4> |
|---|
| 20 | #include <osg/CopyOp> |
|---|
| 21 | #include <osg/Referenced> |
|---|
| 22 | #include <osg/TextureCubeMap> |
|---|
| 23 | #include <osg/Image> |
|---|
| 24 | #include <osg/Notify> |
|---|
| 25 | |
|---|
| 26 | #include <vector> |
|---|
| 27 | |
|---|
| 28 | namespace osgUtil |
|---|
| 29 | { |
|---|
| 30 | |
|---|
| 31 | /** This is the base class for cube map generators. |
|---|
| 32 | It exposes the necessary interface to access the six generated images; |
|---|
| 33 | descendants should only override the compute_color() method. |
|---|
| 34 | */ |
|---|
| 35 | class OSGUTIL_EXPORT CubeMapGenerator: public osg::Referenced { |
|---|
| 36 | public: |
|---|
| 37 | explicit CubeMapGenerator(int texture_size = 64); |
|---|
| 38 | CubeMapGenerator(const CubeMapGenerator ©, const osg::CopyOp ©op = osg::CopyOp::SHALLOW_COPY); |
|---|
| 39 | |
|---|
| 40 | inline osg::Image *getImage(osg::TextureCubeMap::Face face); |
|---|
| 41 | inline const osg::Image *getImage(osg::TextureCubeMap::Face face) const; |
|---|
| 42 | |
|---|
| 43 | /** Generate the six cube images. |
|---|
| 44 | If use_osg_system is true, then the OSG's coordinate system is used instead |
|---|
| 45 | of the default OpenGL one. |
|---|
| 46 | */ |
|---|
| 47 | void generateMap(bool use_osg_system = true); |
|---|
| 48 | |
|---|
| 49 | protected: |
|---|
| 50 | virtual ~CubeMapGenerator() {} |
|---|
| 51 | CubeMapGenerator &operator=(const CubeMapGenerator &) { return *this; } |
|---|
| 52 | |
|---|
| 53 | inline void set_pixel(int index, int c, int r, const osg::Vec4 &color); |
|---|
| 54 | inline static osg::Vec4 vector_to_color(const osg::Vec3 &vec); |
|---|
| 55 | |
|---|
| 56 | /** Override this method to define how colors are computed. |
|---|
| 57 | The parameter R is the reflection vector, pointing from the center of the cube. |
|---|
| 58 | The return value should be the RGBA color associated with that reflection ray. |
|---|
| 59 | */ |
|---|
| 60 | virtual osg::Vec4 compute_color(const osg::Vec3 &R) const = 0; |
|---|
| 61 | |
|---|
| 62 | private: |
|---|
| 63 | int texture_size_; |
|---|
| 64 | |
|---|
| 65 | typedef std::vector<osg::ref_ptr<osg::Image> > Image_list; |
|---|
| 66 | Image_list images_; |
|---|
| 67 | }; |
|---|
| 68 | |
|---|
| 69 | // INLINE METHODS |
|---|
| 70 | |
|---|
| 71 | inline osg::Image *CubeMapGenerator::getImage(osg::TextureCubeMap::Face face) |
|---|
| 72 | { |
|---|
| 73 | switch (face) { |
|---|
| 74 | case osg::TextureCubeMap::POSITIVE_X: return images_[0].get(); |
|---|
| 75 | case osg::TextureCubeMap::NEGATIVE_X: return images_[1].get(); |
|---|
| 76 | case osg::TextureCubeMap::POSITIVE_Y: return images_[2].get(); |
|---|
| 77 | case osg::TextureCubeMap::NEGATIVE_Y: return images_[3].get(); |
|---|
| 78 | case osg::TextureCubeMap::POSITIVE_Z: return images_[4].get(); |
|---|
| 79 | case osg::TextureCubeMap::NEGATIVE_Z: return images_[5].get(); |
|---|
| 80 | default: return 0; |
|---|
| 81 | } |
|---|
| 82 | } |
|---|
| 83 | |
|---|
| 84 | inline const osg::Image *CubeMapGenerator::getImage(osg::TextureCubeMap::Face face) const |
|---|
| 85 | { |
|---|
| 86 | switch (face) { |
|---|
| 87 | case osg::TextureCubeMap::POSITIVE_X: return images_[0].get(); |
|---|
| 88 | case osg::TextureCubeMap::NEGATIVE_X: return images_[1].get(); |
|---|
| 89 | case osg::TextureCubeMap::POSITIVE_Y: return images_[2].get(); |
|---|
| 90 | case osg::TextureCubeMap::NEGATIVE_Y: return images_[3].get(); |
|---|
| 91 | case osg::TextureCubeMap::POSITIVE_Z: return images_[4].get(); |
|---|
| 92 | case osg::TextureCubeMap::NEGATIVE_Z: return images_[5].get(); |
|---|
| 93 | default: return 0; |
|---|
| 94 | } |
|---|
| 95 | } |
|---|
| 96 | |
|---|
| 97 | inline void CubeMapGenerator::set_pixel(int index, int c, int r, const osg::Vec4 &color) |
|---|
| 98 | { |
|---|
| 99 | osg::Image *i = images_[index].get(); |
|---|
| 100 | if (i) { |
|---|
| 101 | *(i->data(c, r)+0) = static_cast<unsigned char>(osg::clampBetween(color.x(),0.0f,1.0f) * 255); |
|---|
| 102 | *(i->data(c, r)+1) = static_cast<unsigned char>(osg::clampBetween(color.y(),0.0f,1.0f) * 255); |
|---|
| 103 | *(i->data(c, r)+2) = static_cast<unsigned char>(osg::clampBetween(color.z(),0.0f,1.0f) * 255); |
|---|
| 104 | *(i->data(c, r)+3) = static_cast<unsigned char>(osg::clampBetween(color.w(),0.0f,1.0f) * 255); |
|---|
| 105 | } else { |
|---|
| 106 | osg::notify(osg::WARN) << "Warning: CubeMapGenerator::set_pixel(): invalid image index\n"; |
|---|
| 107 | } |
|---|
| 108 | } |
|---|
| 109 | |
|---|
| 110 | inline osg::Vec4 CubeMapGenerator::vector_to_color(const osg::Vec3 &vec) |
|---|
| 111 | { |
|---|
| 112 | return osg::Vec4( |
|---|
| 113 | vec.x() / vec.length() / 2 + 0.5f, |
|---|
| 114 | vec.y() / vec.length() / 2 + 0.5f, |
|---|
| 115 | vec.z() / vec.length() / 2 + 0.5f, |
|---|
| 116 | 1); |
|---|
| 117 | } |
|---|
| 118 | |
|---|
| 119 | } |
|---|
| 120 | |
|---|
| 121 | #endif |
|---|