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

Revision 13574, 8.0 kB (checked in by robert, 11 days ago)

Moved widgets from VolumeEditorWidget? to TransferFunctionWidget?, and widget utilities into WidgetUtils?.

  • 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.