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

Revision 13574, 8.0 kB (checked in by robert, 56 minutes ago)

From Jason Beverage, "It looks like the Callback header got accidentally removed from the CMakeLists.txt in the submission yesterday for the geometry instancing example."

  • 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, osg::Array::BIND_OVERALL);
138
139    osg::Vec4Array* colors = new osg::Vec4Array(1);
140    (*colors)[0].set(1.0f,1.0f,1.0f,1.0f);
141    geom->setColorArray(colors, osg::Array::BIND_OVERALL);
142
143    geom->addPrimitiveSet(new osg::DrawArrays(GL_QUADS, 0, 4));
144
145    // disable display list so our modified tex coordinates show up
146    geom->setUseDisplayList(false);
147
148    // load image
149    osg::Image* img = osgDB::readImageFile(filename);
150
151    // setup texture
152    osg::TextureRectangle* texture = new osg::TextureRectangle(img);
153
154    osg::TexMat* texmat = new osg::TexMat;
155    texmat->setScaleByTextureRectangleSize(true);
156
157    // setup state
158    osg::StateSet* state = geom->getOrCreateStateSet();
159    state->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON);
160    state->setTextureAttributeAndModes(0, texmat, osg::StateAttribute::ON);
161
162    // turn off lighting
163    state->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
164
165    // install 'update' callback
166    osg::Geode* geode = new osg::Geode;
167    geode->addDrawable(geom);
168    geode->setUpdateCallback(new TexturePanCallback(texmat));
169
170    return geode;
171}
172
173
174osg::Geode* createText(const std::string& str,
175                       const osg::Vec3& pos)
176{
177    static std::string font("fonts/arial.ttf");
178
179    osg::Geode* geode = new osg::Geode;
180
181    osgText::Text* text = new osgText::Text;
182    geode->addDrawable(text);
183
184    text->setFont(font);
185    text->setPosition(pos);
186    text->setText(str);
187
188    return geode;
189}
190
191
192osg::Node* createHUD()
193{
194    osg::Group* group = new osg::Group;
195
196    // turn off lighting and depth test
197    osg::StateSet* state = group->getOrCreateStateSet();
198    state->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
199    state->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
200
201    // add text
202    osg::Vec3 pos(120.0f, 800.0f, 0.0f);
203    const osg::Vec3 delta(0.0f, -80.0f, 0.0f);
204
205    const char* text[] = {
206        "TextureRectangle Mini-HOWTO",
207        "- essentially behaves like Texture2D, *except* that:",
208        "- tex coords must be non-normalized (0..pixel) instead of (0..1),\nalternatively you can use osg::TexMat to scale normal non dimensional texcoords.",
209        "- wrap modes must be CLAMP, CLAMP_TO_EDGE, or CLAMP_TO_BORDER\n  repeating wrap modes are not supported",
210        "- filter modes must be NEAREST or LINEAR since\n  mipmaps are not supported",
211        "- texture borders are not supported",
212        "- defaults should be fine",
213        NULL
214    };
215    const char** t = text;
216    while (*t) {
217        group->addChild(createText(*t++, pos));
218        pos += delta;
219    }
220
221    // create HUD
222    osg::MatrixTransform* modelview_abs = new osg::MatrixTransform;
223    modelview_abs->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
224    modelview_abs->setMatrix(osg::Matrix::identity());
225    modelview_abs->addChild(group);
226
227    osg::Projection* projection = new osg::Projection;
228    projection->setMatrix(osg::Matrix::ortho2D(0,1280,0,1024));
229    projection->addChild(modelview_abs);
230
231    return projection;
232}
233
234
235osg::Node* createModel(const std::string& filename)
236{
237    osg::Group* root = new osg::Group;
238
239    if (filename != "X") {
240        osg::BoundingBox bb(0.0f,0.0f,0.0f,1.0f,1.0f,1.0f);
241        root->addChild(createRectangle(bb, filename)); // XXX
242    }
243
244    root->addChild(createHUD());
245
246    return root;
247}
248
249
250int main(int argc, char** argv)
251{
252    // use an ArgumentParser object to manage the program arguments.
253    osg::ArgumentParser arguments(&argc,argv);
254
255    // construct the viewer.
256    osgViewer::Viewer viewer;
257
258    // create a model from the images.
259    osg::Node* rootNode = createModel((arguments.argc() > 1 ? arguments[1] : "Images/lz.rgb"));
260
261    // add model to viewer.
262    viewer.setSceneData(rootNode);
263
264    return viewer.run();
265}
Note: See TracBrowser for help on using the browser.