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

Revision 1957, 8.9 kB (checked in by robert, 11 years ago)

Added osgtexturerectangle example from Ulrich Hertlein.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1// -*-c++-*-
2
3/*
4 * demonstrates usage of osg::TextureRectangle.
5 *
6 * Actually there isn't much difference to the rest of the osg::Texture*
7 * bunch only this:
8 * - texture coordinates for texture rectangles must be in image
9 *   coordinates instead of normalized coordinates (0-1). So for a 500x250
10 *   image the coordinates for the entire image would be
11 *   0,250 0,0 500,0 500,250 instead of 0,1 0,0 1,0 1,1
12 * - only the following wrap modes are supported (but not enforced)
13 *   CLAMP, CLAMP_TO_EDGE, CLAMP_TO_BORDER
14 * - a border is not supported
15 * - mipmap is not supported
16 */
17
18#include <osg/Notify>
19#include <osg/TextureRectangle>
20#include <osg/Geometry>
21#include <osg/Geode>
22
23#include <osg/Projection>
24#include <osg/MatrixTransform>
25
26#include <osgText/Text>
27
28#include <osgDB/Registry>
29#include <osgDB/ReadFile>
30
31#include <osgProducer/Viewer>
32
33
34/**********************************************************************
35 *
36 * Texture pan animation callback
37 *
38 **********************************************************************/
39
40class TexturePanCallback : public osg::NodeCallback
41{
42public:
43    TexturePanCallback(osg::Geometry* geom, osg::Image* img,
44                       double delay = 0.05) :
45        _geom(geom),
46        _img(img),
47        _phaseS(35.0f),
48        _phaseT(18.0f),
49        _phaseScale(5.0f),
50        _delay(delay),
51        _prevTime(0.0)
52    {
53    }
54
55    virtual void operator()(osg::Node*, osg::NodeVisitor* nv)
56    {
57        if (!_geom || !_img)
58            return;
59
60        if (nv->getFrameStamp()) {
61            double currTime = nv->getFrameStamp()->getReferenceTime();
62            if (currTime - _prevTime > _delay) {
63
64                float rad = osg::DegreesToRadians(currTime);
65
66                // zoom scale (0.2 - 1.0)
67                float scale = sin(rad * _phaseScale) * 0.4f + 0.6f;
68                float scaleR = 1.0f - scale;
69
70                // calculate new texture coordinates
71                float s, t;
72                s = ((sin(rad * _phaseS) + 1) * 0.5f) * (_img->s() * scaleR);
73                t = ((sin(rad * _phaseT) + 1) * 0.5f) * (_img->t() * scaleR);
74
75                // set new texture coordinate array
76                osg::Vec2Array* texcoords = (osg::Vec2Array*) _geom->getTexCoordArray(0);
77                float w = _img->s() * scale, h = _img->t() * scale;
78                (*texcoords)[0].set(s, t+h);
79                (*texcoords)[1].set(s, t);
80                (*texcoords)[2].set(s+w, t);
81                (*texcoords)[3].set(s+w, t+h);
82
83                // record time
84                _prevTime = currTime;
85            }
86        }
87    }
88
89private:
90    osg::Geometry* _geom;
91    osg::Image* _img;
92
93    float _phaseS, _phaseT, _phaseScale;
94
95    double _delay;
96    double _prevTime;
97};
98
99
100osg::Node* createRectangle(osg::BoundingBox& bb,
101                           const std::string& filename)
102{
103    osg::Vec3 top_left(bb.xMin(),bb.yMax(),bb.zMax());
104    osg::Vec3 bottom_left(bb.xMin(),bb.yMax(),bb.zMin());
105    osg::Vec3 bottom_right(bb.xMax(),bb.yMax(),bb.zMin());
106    osg::Vec3 top_right(bb.xMax(),bb.yMax(),bb.zMax());
107   
108    // create geometry
109    osg::Geometry* geom = new osg::Geometry;
110
111    osg::Vec3Array* vertices = new osg::Vec3Array(4);
112    (*vertices)[0] = top_left;
113    (*vertices)[1] = bottom_left;
114    (*vertices)[2] = bottom_right;
115    (*vertices)[3] = top_right;
116    geom->setVertexArray(vertices);
117   
118    osg::Vec2Array* texcoords = new osg::Vec2Array(4);
119    (*texcoords)[0].set(0.0f, 0.0f);
120    (*texcoords)[1].set(1.0f, 0.0f);
121    (*texcoords)[2].set(1.0f, 1.0f);
122    (*texcoords)[3].set(0.0f, 1.0f);
123    geom->setTexCoordArray(0,texcoords);
124
125    osg::Vec3Array* normals = new osg::Vec3Array(1);
126    (*normals)[0].set(-1.0f,0.0f,0.0f);
127    geom->setNormalArray(normals);
128    geom->setNormalBinding(osg::Geometry::BIND_OVERALL);
129
130    osg::Vec4Array* colors = new osg::Vec4Array(1);
131    (*colors)[0].set(1.0f,1.0f,1.0f,1.0f);
132    geom->setColorArray(colors);
133    geom->setColorBinding(osg::Geometry::BIND_OVERALL);
134
135    geom->addPrimitiveSet(new osg::DrawArrays(GL_QUADS, 0, 4));
136
137    // disable display list so our modified tex coordinates show up
138    geom->setUseDisplayList(false);
139
140    osg::Geode* geode = new osg::Geode;
141    geode->addDrawable(geom);
142
143    // setup texture
144    osg::TextureRectangle* texture = new osg::TextureRectangle;
145    texture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP);
146    texture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP);
147
148    // load image
149    osg::Image* img = osgDB::readImageFile(filename);
150    texture->setImage(img);
151   
152    osg::StateSet* state = geom->getOrCreateStateSet();
153    state->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON);
154
155    // turn off lighting
156    state->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
157
158    // install 'update' callback
159    geode->setUpdateCallback(new TexturePanCallback(geom, img));
160   
161    return geode;
162}
163
164
165osg::Geode* createText(const std::string& str,
166                       const osg::Vec3& pos)
167{
168    static std::string font("fonts/arial.ttf");
169
170    osg::Geode* geode = new osg::Geode;
171
172    osgText::Text* text = new osgText::Text;
173    geode->addDrawable(text);
174
175    text->setFont(font);
176    text->setPosition(pos);
177    text->setText(str);
178
179    return geode;
180}
181
182
183osg::Node* createHUD()
184{
185    osg::Group* group = new osg::Group;
186
187    // turn off lighting and depth test
188    osg::StateSet* state = group->getOrCreateStateSet();
189    state->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
190    state->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
191
192    // add text
193    osg::Vec3 pos(150.0f, 800.0f, 0.0f);
194    const osg::Vec3 delta(0.0f, -80.0f, 0.0f);
195
196    const char* text[] = {
197        "TextureRectangle Mini-HOWTO",
198        "- essentially behaves like Texture2D, *except* that:",
199        "- tex coords must be non-normalized (0..width) instead of (0..1)",
200        "- wrap mode must be CLAMP, CLAMP_TO_EDGE, or CLAMP_TO_BORDER",
201        "- repeating wrap modes are *not* supported",
202        "- texture border is *not* supported",
203        "- texture mipmaps are *not* supported",
204        NULL
205    };
206    const char** t = text;
207    while (*t) {
208        group->addChild(createText(*t++, pos));
209        pos += delta;
210    }
211
212    // create HUD
213    osg::MatrixTransform* modelview_abs = new osg::MatrixTransform;
214    modelview_abs->setReferenceFrame(osg::Transform::RELATIVE_TO_ABSOLUTE);
215    modelview_abs->setMatrix(osg::Matrix::identity());
216    modelview_abs->addChild(group);
217
218    osg::Projection* projection = new osg::Projection;
219    projection->setMatrix(osg::Matrix::ortho2D(0,1280,0,1024));
220    projection->addChild(modelview_abs);
221
222    return projection;
223}
224
225
226osg::Node* createModel(const std::string& filename)
227{
228    osg::Group* root = new osg::Group;
229   
230    osg::BoundingBox bb(0.0f,0.0f,0.0f,1.0f,1.0f,1.0f);
231    root->addChild(createRectangle(bb, filename)); // XXX
232
233    root->addChild(createHUD());
234
235    return root;
236}
237
238
239int main(int argc, char** argv)
240{
241    // use an ArgumentParser object to manage the program arguments.
242    osg::ArgumentParser arguments(&argc,argv);
243
244    // set up the usage document, in case we need to print out how to use this program.
245    arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is a demo which demonstrates use of osg::TextureRectangle.");
246    arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] <image> ...");
247    arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");
248   
249    // construct the viewer.
250    osgProducer::Viewer viewer(arguments);
251
252    // set up the value with sensible default event handlers.
253    viewer.setUpViewer(osgProducer::Viewer::STANDARD_SETTINGS);
254
255    // get details on keyboard and mouse bindings used by the viewer.
256    viewer.getUsage(*arguments.getApplicationUsage());
257
258    // if user request help write it out to cout.
259    if (arguments.read("-h") || arguments.read("--help"))
260    {
261        arguments.getApplicationUsage()->write(std::cout);
262        return 1;
263    }
264
265    // any option left unread are converted into errors to write out later.
266    arguments.reportRemainingOptionsAsUnrecognized();
267
268    // report any errors if they have occured when parsing the program aguments.
269    if (arguments.errors())
270    {
271        arguments.writeErrorMessages(std::cout);
272        return 1;
273    }
274
275    // create a model from the images.
276    osg::Node* rootNode = createModel((arguments.argc() > 1 ? arguments[1] : "lz.rgb"));
277
278    // add model to viewer.
279    viewer.setSceneData(rootNode);
280
281    // create the windows and run the threads.
282    viewer.realize();
283
284    while (!viewer.done())
285    {
286        // wait for all cull and draw threads to complete.
287        viewer.sync();
288
289        // update the scene by traversing it with the the update visitor which will
290        // call all node update callbacks and animations.
291        viewer.update();
292
293        // fire off the cull and draw traversals of the scene.
294        viewer.frame();
295    }
296
297    // wait for all cull and draw threads to complete before exit.
298    viewer.sync();
299   
300    return 0;
301}
Note: See TracBrowser for help on using the browser.