#include <ork/render/FrameBuffer.h> #include <ork/scenegraph/SceneManager.h> #include <ork/ui/GlutWindow.h> #include <pmath.h> #include <stbi/stb_image.h> #include <iostream> #include <fstream> const int FFT_SIZE = 256; const int PASSES = 8; const int N = 256; 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)); } float *computeButterflyLookupTexture() { float *data = new float[FFT_SIZE * PASSES * 4]; 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 = 4 * (i1 + i * FFT_SIZE); data[offset1 + 0] = (j1 + 0.5) / FFT_SIZE; data[offset1 + 1] = (j2 + 0.5) / FFT_SIZE; data[offset1 + 2] = wr; data[offset1 + 3] = wi; int offset2 = 4 * (i2 + i * FFT_SIZE); data[offset2 + 0] = (j1 + 0.5) / FFT_SIZE; data[offset2 + 1] = (j2 + 0.5) / FFT_SIZE; data[offset2 + 2] = -wr; data[offset2 + 3] = -wi; } } } return data; } const unsigned char * loadfile(const std::string &file, int &size) { std::ifstream fs(file.c_str(), std::ios::binary); fs.seekg(0, std::ios::end); size = fs.tellg(); char * data = new char[size + 1]; fs.seekg(0); fs.read(data, size); fs.close(); data[size] = 0; return (unsigned char *)data; } struct P3_UV { float _x, _y, _z; float _u, _v; P3_UV() { } P3_UV(float x, float y, float z, float u, float v) :_x(x),_y(y),_z(z),_u(u),_v(v) { } }; class TestWindow : public ork::GlutWindow { public: TestWindow() :ork::GlutWindow(ork::Window::Parameters().name("ProlandTerrain").size(1024, 800)) ,_dist(2.0) { _mesh = new ork::Mesh<P3_UV, unsigned int>(ork::TRIANGLES, ork::GPU_STATIC); _mesh->addAttributeType(0, 3, ork::A32F, false); _mesh->addAttributeType(1, 2, ork::A32F, true); _mesh->addVertex(P3_UV(-1, -1, 0, 0, 1)); _mesh->addVertex(P3_UV(1, -1, 0, 1, 1)); _mesh->addVertex(P3_UV(1, 1, 0, 1, 0)); _mesh->addVertex(P3_UV(-1, 1, 0, 0, 0)); _mesh->addIndice(0); _mesh->addIndice(1); _mesh->addIndice(2); _mesh->addIndice(0); _mesh->addIndice(2); _mesh->addIndice(3); int w; int h; int channels; int size; /*const unsigned char * data = loadfile("D:/1.jpg", size); const unsigned char * logo = stbi_load_from_memory(data, size, &w, &h, &channels, 0);*/ float *data = computeButterflyLookupTexture(); ork::ptr<ork::Texture2D> butterfly = new ork::Texture2D(FFT_SIZE, PASSES, ork::RGBA16F, ork::RGBA, ork::ORK_FLOAT, ork::Texture::Parameters().min(ork::NEAREST).mag(ork::NEAREST).wrapS(ork::CLAMP_TO_EDGE).wrapT(ork::CLAMP_TO_EDGE), ork::Buffer::Parameters(), ork::CPUBuffer(data)); ork::ptr<ork::Module> meshModule = new ork::Module(330, "\ uniform mat4 localToScreen; \n layout(location = 0) in vec3 vertex; \n layout(location = 1) in vec2 uv; \n out vec2 fuv; \n void main() { \n fuv = uv; \n gl_Position = localToScreen * vec4(vertex, 1.0); \n } \n ", " uniform sampler2D sampler; \n layout(location = 0) out vec4 data; \n in vec2 fuv; \n void main() { \n data = vec4(texture(sampler, fuv).rgb, 1); \n } \n "); _meshProgram = new ork::Program(meshModule); _localToScreen = _meshProgram->getUniformMatrix4f("localToScreen"); _meshProgram->getUniformSampler("sampler")->set(butterfly); _frameBuffer = ork::FrameBuffer::getDefault(); _frameBuffer->setClearColor(ork::vec4f(0.0, 0.0, 1.0, 1.0)); _frameBuffer->setDepthTest(true, ork::LESS); } virtual void redisplay(double t, double dt) { _frameBuffer->clear(true, false, true); static float i = 0.0; ork::mat4f cameraToWorld = ork::mat4f::rotatey(i); //i += 0.01; cameraToWorld = cameraToWorld * ork::mat4f::translate(ork::vec3f(0.0, 0.0, _dist)); ork::mat4f worldToCamera = cameraToWorld.inverse(); ork::vec4<int> vp = _frameBuffer->getViewport(); float width = float(vp.z); float height = float(vp.w); ork::mat4f cameraToScreen = ork::mat4f::perspectiveProjection(degrees(45.0), width/height, 0.1, 100000.0); _localToScreen->setMatrix(cameraToScreen * worldToCamera); _frameBuffer->draw(_meshProgram, *_mesh); ork::GlutWindow::redisplay(t, dt); } virtual void reshape(int x, int y) { _frameBuffer->setViewport(ork::vec4i(0, 0, x, y)); ork::GlutWindow::reshape(x, y); idle(false); } public: static ork::static_ptr<ork::Window> _app; ork::ptr<ork::FrameBuffer> _frameBuffer; ork::ptr<ork::Mesh<P3_UV, unsigned int> > _mesh; ork::ptr<ork::Program> _meshProgram; ork::ptr<ork::UniformMatrix4f> _localToScreen; float _dist; }; ork::static_ptr<ork::Window> TestWindow::_app; int main() { atexit(ork::Object::exit); TestWindow::_app = new TestWindow; TestWindow::_app->start(); return EXIT_SUCCESS; }
原文:http://www.cnblogs.com/nmgxbc/p/3566827.html