osg蝴蝶纹理

#include <osgViewer/Viewer>
#include <osgDB/WriteFile>
#include <osg/StateSet>
#include <osg/Texture>
#include <osg/Texture2D>
#include <osg/Image>
#include <cmath>
#include <osgDB/ReadFile>
#pragma comment(lib, "osgd.lib")
#pragma comment(lib, "osgViewerd.lib")
#pragma comment(lib, "osgDBd.lib")
#pragma comment(lib, "osgGAd.lib")
const int FFT_SIZE = 256;
const int PASSES = 8;
const int N = 256;
const float M_PI = osg::PI;

int bitReverse(int i, int N)
{
    int j = i;
    int M = N;
    int Sum = 0;
    int W = 1;
    M = M / 2;
    while (M != 0) {
        j = (i & M) > M - 1;
        Sum += j * W;
        W *= 2;
        M = M / 2;
    }
    return Sum;
}
void computeWeight(int N, int k, float &Wr, float &Wi)
{
    Wr = cosl(2.0 * M_PI * k / float(N));
    Wi = sinl(2.0 * M_PI * k / float(N));
}


osg::ref_ptr<osg::Image> CreateImage()
{
    osg::ref_ptr<osg::Image> image = new osg::Image;
    image->allocateImage(FFT_SIZE, PASSES, 1, GL_RGBA, GL_FLOAT);
    image->setInternalTextureFormat(GL_RGBA16);
    osg::Vec4 * data = (osg::Vec4 *)image->data();
    for (int i = 0; i < PASSES; i++) {
        int nBlocks  = (int) powf(2.0, float(PASSES - 1 - i));
        int nHInputs = (int) powf(2.0, float(i));
        for (int j = 0; j < nBlocks; j++) {
            for (int k = 0; k < nHInputs; k++) {
                int i1, i2, j1, j2;
                if (i == 0) {
                    i1 = j * nHInputs * 2 + k;
                    i2 = j * nHInputs * 2 + nHInputs + k;
                    j1 = bitReverse(i1, FFT_SIZE);
                    j2 = bitReverse(i2, FFT_SIZE);
                } else {
                    i1 = j * nHInputs * 2 + k;
                    i2 = j * nHInputs * 2 + nHInputs + k;
                    j1 = i1;
                    j2 = i2;
                }
                float wr, wi;
                computeWeight(FFT_SIZE, k * nBlocks, wr, wi);
                int offset1 = (i1 + i * FFT_SIZE);
                data[offset1]._v[0] = (j1 + 0.5) / FFT_SIZE; 
                data[offset1]._v[1] = (j2 + 0.5) / FFT_SIZE;
                data[offset1]._v[2] = wr;
                data[offset1]._v[3] = wi;
                int offset2 =  (i2 + i * FFT_SIZE);
                data[offset2]._v[0] = (j1 + 0.5) / FFT_SIZE;
                data[offset2]._v[1] = (j2 + 0.5) / FFT_SIZE;
                data[offset2]._v[2] = -wr;
                data[offset2]._v[3] = -wi;
            }
        }
    }
    return image.get();
}
osg::ref_ptr<osg::Geode> CreateQuad()
{
    osg::ref_ptr<osg::Geode> quad = new osg::Geode;
    osg::ref_ptr<osg::Geometry> geometry = new osg::Geometry;
    osg::ref_ptr<osg::Vec3Array> vArray = new osg::Vec3Array;
    osg::ref_ptr<osg::Vec2Array> tArray = new osg::Vec2Array;
    vArray->push_back(osg::Vec3(-1.0, -1.0, 0.0));
    vArray->push_back(osg::Vec3(1.0, -1.0, 0.0));
    vArray->push_back(osg::Vec3(1.0, 1.0, 0.0));
    vArray->push_back(osg::Vec3(-1.0, 1.0, 0.0));

    tArray->push_back(osg::Vec2(0.0, 0.0));
    tArray->push_back(osg::Vec2(1.0, 0.0));
    tArray->push_back(osg::Vec2(1.0, 1.0));
    tArray->push_back(osg::Vec2(0.0, 1.0));

    geometry->setVertexArray(vArray.get());
    geometry->setTexCoordArray(0, tArray.get());

    geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, vArray->size()));
    quad->addDrawable(geometry.get());
    return quad.get();
}

osg::ref_ptr<osg::StateSet> SetUpImageStateSet(osg::ref_ptr<osg::Image> image)
{
    osg::ref_ptr<osg::StateSet> stateSet = new osg::StateSet;
    osg::ref_ptr<osg::Texture2D> texture2D = new osg::Texture2D;
    texture2D->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::NEAREST);
    texture2D->setFilter(osg::Texture2D::MAG_FILTER, osg::Texture2D::NEAREST);
    texture2D->setWrap(osg::Texture2D::WRAP_S, osg::Texture2D::CLAMP_TO_EDGE);
    texture2D->setWrap(osg::Texture2D::WRAP_T, osg::Texture2D::CLAMP_TO_EDGE);
    texture2D->setImage(image.get());
    stateSet->setTextureAttributeAndModes(0, texture2D.get(), osg::StateAttribute::ON);
    return stateSet.get();
}

int main()
{
    osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;
    viewer->setUpViewInWindow(35, 35, 1024, 800);

    osg::ref_ptr<osg::Geode> quad = CreateQuad();
    quad->setStateSet(SetUpImageStateSet(CreateImage().get()));
    viewer->setSceneData(quad.get());
    viewer->getCamera()->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
    viewer->run();
    return EXIT_SUCCESS;
}

 

posted @ 2014-02-26 14:22  20118281131  阅读(439)  评论(0编辑  收藏  举报