朱丽叶—Cuda+OSG

#include <cuda_runtime.h>
#include <osg/Image>
const int DIM = 1024;

typedef struct cuComplex
{
    float r;
    float i;
    __device__ cuComplex(float a, float b)
        :r(a)
        ,i(b)
    {
    }

    __device__ float magnitude2(void)
    {
        return r * r + i * i;
    }

    __device__ cuComplex operator * (const cuComplex & a)
    {
        return cuComplex(r * a.r - i * a.i, i * a.r + r * a.i);
    }

    __device__ cuComplex operator + (const cuComplex & a)
    {
        return cuComplex(r + a.r, i + a.i);
    }
};

__device__ int julia(int x, int y)
{
    const float scale = 1.5;
    float jx = scale * (float)(DIM/2 - x)/(DIM/2);
    float jy = scale * (float)(DIM/2 -y)/(DIM/2);
    cuComplex c(-0.8, 0.156);
    cuComplex a(jx, jy);
    
    for (int i = 0; i < 200; ++i)
    {
        a = a * a + c;
        if (a.magnitude2() > 1024)
            return 0;
    }
    return 1;
}

__global__ void kernel(unsigned char * ptr)
{
    int x = blockIdx.x;
    int y = blockIdx.y;
    int offset = x + y * gridDim.x;
    int juliaValue = julia(x, y);
    ptr[offset * 4 + 0] = 255 * juliaValue;
    ptr[offset * 4 + 1] = 0;
    ptr[offset * 4 + 2] = 0;
    ptr[offset * 4 + 3] = 255;
    
}




extern "C" void SetUp(osg::Image * image)
{
    unsigned char * dev_bitmap;    
    cudaMalloc((void **)&dev_bitmap, DIM * DIM * 4);
    dim3 grid(DIM, DIM);
    kernel<<<grid, 1>>>(dev_bitmap);
    cudaMemcpy(image->data(), dev_bitmap, DIM * DIM * 4, cudaMemcpyDeviceToHost);
    cudaFree(dev_bitmap);
}
#include <osgViewer/Viewer>
#include <osg/Texture2D>
#include <osg/Image>
#include <osgDB/WriteFile>
#include <osgViewer/ViewerEventHandlers>
#pragma comment(lib, "osgViewerd.lib")
#pragma comment(lib, "osgDBd.lib")
#pragma comment(lib, "osgd.lib")
#pragma comment(lib, "osgGAd.lib")
const int DIM = 1024; 

osg::ref_ptr<osg::Geode> CreateQuad()
{
    osg::ref_ptr<osg::Geode> geode = 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;
    osg::ref_ptr<osg::Vec3Array> nArray = new osg::Vec3Array;
    vArray->push_back(osg::Vec3(-1.0, 0.0, -1.0));
    vArray->push_back(osg::Vec3(1.0, 0.0, -1.0));
    vArray->push_back(osg::Vec3(1.0, 0.0, 1.0));
    vArray->push_back(osg::Vec3(-1.0, 0.0, 1.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));

    nArray->push_back(osg::Vec3(0.0, 1.0, 0.0));
    geometry->setVertexArray(vArray.get());
    geometry->setTexCoordArray(0, tArray.get());
    geometry->setNormalArray(nArray.get());
    geometry->setNormalBinding(osg::Geometry::BIND_OVERALL);
    geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, vArray->size()));
    geode->addDrawable(geometry.get());
    return geode.get();
}

osg::ref_ptr<osg::StateSet> CreateStateSet(osg::Image * image)
{
    osg::ref_ptr<osg::StateSet> stateSet = new osg::StateSet;

    osg::ref_ptr<osg::Texture2D> texture = new osg::Texture2D();
    texture->setImage(image);
    stateSet->setTextureAttributeAndModes(0, texture.get(), osg::StateAttribute::ON);
    return stateSet.get();
}
extern "C" void SetUp(osg::Image * image);
int main()
{
    osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;

    osg::ref_ptr<osg::Image> image = new osg::Image;
    image->allocateImage(DIM, DIM, 1, GL_RGBA, GL_UNSIGNED_BYTE);
    SetUp(image.get());

    osg::ref_ptr<osg::StateSet> stateSet = CreateStateSet(image.get());
    osg::ref_ptr<osg::Geode> quad = CreateQuad();
    quad->setStateSet(stateSet.get());
    viewer->setSceneData(quad.get());
    viewer->getCamera()->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
    viewer->addEventHandler(new osgViewer::StatsHandler);
    viewer->setUpViewInWindow(35, 35, 1024, 800);
    viewer->run();
    return 0;
}

 

posted @ 2014-01-22 21:07  20118281131  阅读(704)  评论(1编辑  收藏  举报