朱丽叶—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; }