您的位置:首页 > 其它

ocean所用的蝴蝶纹理

2014-02-25 15:19 363 查看
#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;
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: