Strange attractors with OpenCL
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.
 
 
 

174 lines
4.6 KiB

#include "app.hpp"
#include "utils.hpp"
#include <iostream>
using namespace std;
static const std::vector<Vertex> quad = {{
// x y z u v
{{ 1, -1, 0}, {1, 0}},
{{-1, -1, 0}, {0, 0}},
{{ 1, 1, 0}, {1, 1}},
{{-1, 1, 0}, {0, 1}}
}};
enum {
POS_ATTR,
TEX_ATTR
};
App::App(GLContext& gl_context)
: gl_image1(create_gl_texture(W, H))
, gl_image2(create_gl_texture(W, H))
, gl_vbo(create_vbo(quad))
, gl_vao(create_vao(gl_vbo))
, gl_program(create_shader_from_files("Fractal.vsh", "Fractal.fsh"))
, cl_context(create_shared_cl_context(gl_context))
, cl_device(cl_context.getInfo<CL_CONTEXT_DEVICES>().front())
, cl_queue(cl_context, cl_device)
, cl_image1(cl_context, CL_MEM_READ_WRITE, GL_TEXTURE_2D, 0, gl_image1)
, cl_image2(cl_context, CL_MEM_READ_WRITE, GL_TEXTURE_2D, 0, gl_image2)
, cl_program(create_cl_program("Kernel.cl"))
, k_initialize(cl_program, "initialize")
, k_hblur(cl_program, "hblur")
, k_vblur(cl_program, "vblur")
, k_update(cl_program, "update")
{
cl::checky(k_initialize(cl_queue, W, H, W, H, cl_image1));
cl::checky(k_initialize(cl_queue, W, H, W, H, cl_image2));
}
void App::draw(){
GLuint* gl_images[] = {&gl_image1, &gl_image2};
cl::ImageGL* cl_images[] = {&cl_image1, &cl_image2};
auto dt = 1/60.0;
time += dt;
if(wait > 0) wait -= dt;
if(wait <= 0){
bool blur = false;
if((frame / 200) % 2) blur = true;
if(blur){
frame += 4;
cl::checky(k_hblur(cl_queue, W, H, W, H, *cl_images[(frame + 1) % 2], *cl_images[frame % 2]));
cl::checky(k_vblur(cl_queue, W, H, W, H, *cl_images[frame % 2], *cl_images[(frame + 1) % 2]));
} else {
frame++;
cl::checky(k_update(cl_queue, W, H, W, H, *cl_images[(frame + 1) % 2], *cl_images[frame % 2]));
}
}
cl::checky(cl_queue.finish());
moggle::gl::clear_color(0.35f, 0.65f, 0.65f, 1.0f);
moggle::gl::clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
gl_program.use();
moggle::gl::bind_texture(GL_TEXTURE_2D, *gl_images[frame % 2]);
gl_program.uniform<GLint>("tex").set(0);
gl_vao.bind();
moggle::gl::draw_arrays(GL_TRIANGLE_STRIP, 0, 4);
}
void App::resize(size_t w, size_t h){
wait = 2;
W = w;
H = h;
gl_image1 = create_gl_texture(W, H);
gl_image2 = create_gl_texture(W, H);
cl_int err = 0;
cl_image1 = cl::ImageGL(cl_context, CL_MEM_READ_WRITE, GL_TEXTURE_2D, 0, gl_image1, &err);
cl::checky(err);
cl_image2 = cl::ImageGL(cl_context, CL_MEM_READ_WRITE, GL_TEXTURE_2D, 0, gl_image2, &err);
cl::checky(err);
std::cout << cl_image1 << std::endl;
cl::checky(k_initialize(cl_queue, W, H, W, H, cl_image1));
cl::checky(k_initialize(cl_queue, W, H, W, H, cl_image2));
}
moggle::shader_program App::create_shader_from_files(string vertex, string fragment){
moggle::shader_program program;
auto vs = moggle::shader::from_file(moggle::shader_type::vertex, vertex);
auto fs = moggle::shader::from_file(moggle::shader_type::fragment, fragment);
program.attach(vs);
program.attach(fs);
program.bind_attribute(POS_ATTR, "position");
program.bind_attribute(TEX_ATTR, "tex_coord");
program.link();
return program;
}
moggle::vbo<Vertex> App::create_vbo(const std::vector<Vertex>& data){
moggle::vbo<Vertex> vbo;
vbo.bind(GL_ARRAY_BUFFER);
vbo.data(data);
return vbo;
}
moggle::vao App::create_vao(const moggle::vbo<Vertex>& vbo){
moggle::vao vao;
vao.bind();
moggle::gl::enable_vertex_attribute_array(POS_ATTR);
moggle::gl::enable_vertex_attribute_array(TEX_ATTR);
vao.attribute(POS_ATTR, vbo, &Vertex::position);
vao.attribute(TEX_ATTR, vbo, &Vertex::tex_coord);
return vao;
}
GLuint App::create_gl_texture(GLsizei width, GLsizei height){
GLuint tex = 0;
moggle::gl::active_texture(GL_TEXTURE0);
moggle::gl::generate_textures(1, &tex);
moggle::gl::bind_texture(GL_TEXTURE_2D, tex);
moggle::gl::texture_image_2d(GL_TEXTURE_2D, 0, GL_RGBA32F, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
moggle::gl::texture_parameter_i(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
moggle::gl::texture_parameter_i(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
return tex;
}
cl::Context App::create_shared_cl_context(GLContext& gl_context){
CGLShareGroupObj sharegroup = CGLGetShareGroup(gl_context.ctx);
cl_context_properties properties[] = {
CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE, (cl_context_properties)sharegroup,
0
};
cl_int err = 0;
cl::Context cl_context(CL_DEVICE_TYPE_CPU, properties, nullptr, nullptr, &err);
cl::checky(err);
return cl_context;
}
cl::Program App::create_cl_program(string file){
cl_int err = 0;
// build the program
cl::Program cl_program(cl_context, slurp(file), true, &err);
cout << cl_program.getBuildInfo<CL_PROGRAM_BUILD_LOG>(cl_device) << std::endl;
cl::checky(err);
cout << cl_program << endl;
return cl_program;
}