root/OpenSceneGraph/trunk/examples/osgtexturerectangle/osgtexturerectangle.cpp @ 13276

Revision 6941, 8.0 kB (checked in by robert, 7 years ago)

From Martin Lavery and Robert Osfield, Updated examples to use a variation of the MIT License

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/* OpenSceneGraph example, osgtexturerectangle.
2*
3*  Permission is hereby granted, free of charge, to any person obtaining a copy
4*  of this software and associated documentation files (the "Software"), to deal
5*  in the Software without restriction, including without limitation the rights
6*  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7*  copies of the Software, and to permit persons to whom the Software is
8*  furnished to do so, subject to the following conditions:
9*
10*  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
11*  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
12*  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
13*  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
14*  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
15*  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
16*  THE SOFTWARE.
17*/
18
19/*
20 * demonstrates usage of osg::TextureRectangle.
21 *
22 * Actually there isn't much difference to the rest of the osg::Texture*
23 * bunch only this:
24 * - texture coordinates for texture rectangles must be in image
25 *   coordinates instead of normalized coordinates (0-1). So for a 500x250
26 *   image the coordinates for the entire image would be
27 *   0,250 0,0 500,0 500,250 instead of 0,1 0,0 1,0 1,1
28 * - only the following wrap modes are supported (but not enforced)
29 *   CLAMP, CLAMP_TO_EDGE, CLAMP_TO_BORDER
30 * - a border is not supported
31 * - mipmap is not supported
32 */
33
34#include <osg/Notify>
35#include <osg/TextureRectangle>
36#include <osg/Geometry>
37#include <osg/Geode>
38#include <osg/TexMat>
39
40#include <osg/Group>
41#include <osg/Projection>
42#include <osg/MatrixTransform>
43#include <osgText/Text>
44
45#include <osgDB/Registry>
46#include <osgDB/ReadFile>
47
48#include <osgViewer/Viewer>
49
50
51/**********************************************************************
52 *
53 * Texture pan animation callback
54 *
55 **********************************************************************/
56
57class TexturePanCallback : public osg::NodeCallback
58{
59public:
60    TexturePanCallback(osg::TexMat* texmat,
61                       double delay = 0.05) :
62        _texmat(texmat),
63        _phaseS(35.0f),
64        _phaseT(18.0f),
65        _phaseScale(5.0f),
66        _delay(delay),
67        _prevTime(0.0)
68    {
69    }
70
71    virtual void operator()(osg::Node*, osg::NodeVisitor* nv)
72    {
73        if (!_texmat)
74            return;
75
76        if (nv->getFrameStamp()) {
77            double currTime = nv->getFrameStamp()->getSimulationTime();
78            if (currTime - _prevTime > _delay) {
79
80                float rad = osg::DegreesToRadians(currTime);
81
82                // zoom scale (0.2 - 1.0)
83                float scale = sin(rad * _phaseScale) * 0.4f + 0.6f;
84                float scaleR = 1.0f - scale;
85
86                // calculate new texture coordinates
87                float s, t;
88                s = ((sin(rad * _phaseS) + 1) * 0.5f) * (scaleR);
89                t = ((sin(rad * _phaseT) + 1) * 0.5f) * (scaleR);
90
91
92                _texmat->setMatrix(osg::Matrix::translate(s,t,1.0)*osg::Matrix::scale(scale,scale,1.0));
93
94                // record time
95                _prevTime = currTime;
96            }
97        }
98    }
99
100private:
101    osg::TexMat* _texmat;
102
103    float _phaseS, _phaseT, _phaseScale;
104
105    double _delay;
106    double _prevTime;
107};
108
109
110osg::Node* createRectangle(osg::BoundingBox& bb,
111                           const std::string& filename)
112{
113    osg::Vec3 top_left(bb.xMin(),bb.yMax(),bb.zMax());
114    osg::Vec3 bottom_left(bb.xMin(),bb.yMax(),bb.zMin());
115    osg::Vec3 bottom_right(bb.xMax(),bb.yMax(),bb.zMin());
116    osg::Vec3 top_right(bb.xMax(),bb.yMax(),bb.zMax());
117   
118    // create geometry
119    osg::Geometry* geom = new osg::Geometry;
120
121    osg::Vec3Array* vertices = new osg::Vec3Array(4);
122    (*vertices)[0] = top_left;
123    (*vertices)[1] = bottom_left;
124    (*vertices)[2] = bottom_right;
125    (*vertices)[3] = top_right;
126    geom->setVertexArray(vertices);
127   
128    osg::Vec2Array* texcoords = new osg::Vec2Array(4);
129    (*texcoords)[0].set(0.0f, 0.0f);
130    (*texcoords)[1].set(1.0f, 0.0f);
131    (*texcoords)[2].set(1.0f, 1.0f);
132    (*texcoords)[3].set(0.0f, 1.0f);
133    geom->setTexCoordArray(0,texcoords);
134
135    osg::Vec3Array* normals = new osg::Vec3Array(1);
136    (*normals)[0].set(0.0f,-1.0f,0.0f);
137    geom->setNormalArray(normals);
138    geom->setNormalBinding(osg::Geometry::BIND_OVERALL);
139
140    osg::Vec4Array* colors = new osg::Vec4Array(1);
141    (*colors)[0].set(1.0f,1.0f,1.0f,1.0f);
142    geom->setColorArray(colors);
143    geom->setColorBinding(osg::Geometry::BIND_OVERALL);
144
145    geom->addPrimitiveSet(new osg::DrawArrays(GL_QUADS, 0, 4));
146
147    // disable display list so our modified tex coordinates show up
148    geom->setUseDisplayList(false);
149
150    // load image
151    osg::Image* img = osgDB::readImageFile(filename);
152
153    // setup texture
154    osg::TextureRectangle* texture = new osg::TextureRectangle(img);
155
156    osg::TexMat* texmat = new osg::TexMat;
157    texmat->setScaleByTextureRectangleSize(true);
158
159    // setup state
160    osg::StateSet* state = geom->getOrCreateStateSet();
161    state->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON);
162    state->setTextureAttributeAndModes(0, texmat, osg::StateAttribute::ON);
163
164    // turn off lighting
165    state->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
166
167    // install 'update' callback
168    osg::Geode* geode = new osg::Geode;
169    geode->addDrawable(geom);
170    geode->setUpdateCallback(new TexturePanCallback(texmat));
171   
172    return geode;
173}
174
175
176osg::Geode* createText(const std::string& str,
177                       const osg::Vec3& pos)
178{
179    static std::string font("fonts/arial.ttf");
180
181    osg::Geode* geode = new osg::Geode;
182
183    osgText::Text* text = new osgText::Text;
184    geode->addDrawable(text);
185
186    text->setFont(font);
187    text->setPosition(pos);
188    text->setText(str);
189
190    return geode;
191}
192
193
194osg::Node* createHUD()
195{
196    osg::Group* group = new osg::Group;
197
198    // turn off lighting and depth test
199    osg::StateSet* state = group->getOrCreateStateSet();
200    state->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
201    state->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
202
203    // add text
204    osg::Vec3 pos(120.0f, 800.0f, 0.0f);
205    const osg::Vec3 delta(0.0f, -80.0f, 0.0f);
206
207    const char* text[] = {
208        "TextureRectangle Mini-HOWTO",
209        "- essentially behaves like Texture2D, *except* that:",
210        "- tex coords must be non-normalized (0..pixel) instead of (0..1),\nalternatively you can use osg::TexMat to scale normal non dimensional texcoords.",
211        "- wrap modes must be CLAMP, CLAMP_TO_EDGE, or CLAMP_TO_BORDER\n  repeating wrap modes are not supported",
212        "- filter modes must be NEAREST or LINEAR since\n  mipmaps are not supported",
213        "- texture borders are not supported",
214        "- defaults should be fine",
215        NULL
216    };
217    const char** t = text;
218    while (*t) {
219        group->addChild(createText(*t++, pos));
220        pos += delta;
221    }
222
223    // create HUD
224    osg::MatrixTransform* modelview_abs = new osg::MatrixTransform;
225    modelview_abs->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
226    modelview_abs->setMatrix(osg::Matrix::identity());
227    modelview_abs->addChild(group);
228
229    osg::Projection* projection = new osg::Projection;
230    projection->setMatrix(osg::Matrix::ortho2D(0,1280,0,1024));
231    projection->addChild(modelview_abs);
232
233    return projection;
234}
235
236
237osg::Node* createModel(const std::string& filename)
238{
239    osg::Group* root = new osg::Group;
240
241    if (filename != "X") {
242        osg::BoundingBox bb(0.0f,0.0f,0.0f,1.0f,1.0f,1.0f);
243        root->addChild(createRectangle(bb, filename)); // XXX
244    }
245
246    root->addChild(createHUD());
247
248    return root;
249}
250
251
252int main(int argc, char** argv)
253{
254    // use an ArgumentParser object to manage the program arguments.
255    osg::ArgumentParser arguments(&argc,argv);
256
257    // construct the viewer.
258    osgViewer::Viewer viewer;
259
260    // create a model from the images.
261    osg::Node* rootNode = createModel((arguments.argc() > 1 ? arguments[1] : "Images/lz.rgb"));
262
263    // add model to viewer.
264    viewer.setSceneData(rootNode);
265   
266    return viewer.run();
267}
Note: See TracBrowser for help on using the browser.