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.
244 lines
6.3 KiB
244 lines
6.3 KiB
#include "app.hpp"
|
|
|
|
#include "utils.hpp"
|
|
|
|
#include <iostream>
|
|
|
|
using namespace std;
|
|
|
|
// implementation follow later
|
|
static moggle::shader_program create_shader_from_files(std::string vertex, std::string fragment);
|
|
template <typename T>
|
|
static moggle::vbo<T> create_vbo(std::vector<T> const & data);
|
|
static moggle::vao create_vao(moggle::vbo<GLPoint> const & vbo);
|
|
static moggle::vao create_vao(moggle::vbo<Vertex> const & vbo);
|
|
static GLuint create_gl_texture(GLsizei width, GLsizei height);
|
|
static std::vector<GLPoint> generate_random_points(size_t N);
|
|
cl::Context create_shared_cl_context(GLContext & gl_context);
|
|
|
|
std::vector<Vertex> quad = {
|
|
{{-1, -1}, {0, 0}},
|
|
{{ 1, -1}, {1, 0}},
|
|
{{-1, 1}, {0, 1}},
|
|
{{ 1, 1}, {1, 1}},
|
|
};
|
|
|
|
static const GLsizei FBO_SIZE = 1024;
|
|
|
|
Parameters::Parameters(cl::Context& cl_context, std::initializer_list<float> x)
|
|
: cl_context(cl_context)
|
|
, parameters(x)
|
|
, cl_parameter_buffer(cl_context, CL_MEM_USE_HOST_PTR, parameters.size() * sizeof(float), ¶meters[0])
|
|
{}
|
|
|
|
void Parameters::resize(size_t n){
|
|
parameters.resize(n);
|
|
cl_parameter_buffer = cl::Buffer(cl_context, CL_MEM_USE_HOST_PTR, parameters.size() * sizeof(float), ¶meters[0]);
|
|
}
|
|
|
|
size_t Parameters::size() const {
|
|
return parameters.size();
|
|
}
|
|
|
|
float & Parameters::operator[](size_t n){
|
|
return parameters[n];
|
|
}
|
|
|
|
float Parameters::operator[](size_t n) const {
|
|
return parameters[n];
|
|
}
|
|
|
|
cl::Buffer const & Parameters::get_cl() const {
|
|
return cl_parameter_buffer;
|
|
}
|
|
|
|
App::App(GLContext& gl_context)
|
|
: gl_vbo(create_vbo(generate_random_points(N)))
|
|
, gl_vao(create_vao(gl_vbo))
|
|
, gl_quad_vbo(create_vbo(quad))
|
|
, gl_quad_vao(create_vao(gl_quad_vbo))
|
|
, gl_points_program(create_shader_from_files("Points.vsh", "Points.fsh"))
|
|
, gl_texture_program(create_shader_from_files("Texture.vsh", "Texture.fsh"))
|
|
, gl_fbo(moggle::create_default_fbo(FBO_SIZE, FBO_SIZE))
|
|
, cl_context(create_shared_cl_context(gl_context))
|
|
, cl_device(cl_context.getInfo<CL_CONTEXT_DEVICES>().front())
|
|
, cl_queue(cl_context, cl_device)
|
|
, cl_buffer(cl_context, 0, gl_vbo.get_id())
|
|
, cl_program(create_cl_program("Kernel.cl"))
|
|
, k_update(cl_program, "update")
|
|
, parameters(cl_context, {10.962073, 31.211250, 1.537946, 0.013040})
|
|
{
|
|
moggle::gl::clear_color(0.0f, 0.0f, 0.0f, 1.0f);
|
|
|
|
moggle::gl::enable(GL_BLEND);
|
|
moggle::gl::blend_function(GL_ONE, GL_ONE);
|
|
moggle::gl::blend_equation(GL_FUNC_ADD);
|
|
|
|
moggle::gl::active_texture(GL_TEXTURE0);
|
|
moggle::gl::texture_parameter_i(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
moggle::gl::texture_parameter_i(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
}
|
|
|
|
void App::draw(std::function<void(void)> bind, std::function<void(void)> flush){
|
|
auto dt = 1/60.0;
|
|
time += dt;
|
|
|
|
static quaternion speed(1, 0, 0, 0);
|
|
static int frame = 0;
|
|
|
|
if(frame > 200){
|
|
static bool dir = true;
|
|
frame = 0;
|
|
if(dir) {
|
|
speed = quaternion{40.0, 0, 0.1, 0};
|
|
dir = false;
|
|
} else {
|
|
speed = quaternion{40.0, 0.1, 0, 0};
|
|
dir = true;
|
|
}
|
|
speed = normalize(speed);
|
|
}
|
|
frame++;
|
|
rotation = speed * rotation;
|
|
auto const mat = quaternion_to_R3_rotation(normalize(rotation));
|
|
|
|
// OpenCL update
|
|
cl::checky(k_update(cl_queue, N, parameters.get_cl(), cl_buffer));
|
|
cl::checky(cl_queue.finish());
|
|
|
|
// OpenGL to fbo
|
|
gl_fbo.bind();
|
|
moggle::gl::viewport(0, 0, FBO_SIZE, FBO_SIZE);
|
|
if(clear){
|
|
gl_fbo.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
}
|
|
|
|
gl_points_program.use();
|
|
gl_points_program.uniform<moggle::matrix4<float>>("modelmatrix").set(mat);
|
|
gl_vao.bind();
|
|
moggle::gl::draw_arrays(GL_POINTS, 0, N);
|
|
|
|
// Draw fbo
|
|
bind();
|
|
moggle::gl::clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
|
|
gl_texture_program.use();
|
|
|
|
gl_fbo.get_texture().bind(GL_TEXTURE_2D);
|
|
gl_texture_program.uniform<GLint>("tex").set(0);
|
|
gl_texture_program.uniform<GLfloat>("maxf").set(maxf);
|
|
gl_texture_program.uniform<GLfloat>("gamma").set(gamma);
|
|
|
|
gl_quad_vao.bind();
|
|
moggle::gl::draw_arrays(GL_TRIANGLE_STRIP, 0, 4);
|
|
|
|
flush();
|
|
}
|
|
|
|
void App::resize(size_t w, size_t h){
|
|
W = w;
|
|
H = h;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
enum {
|
|
POS_ATTR,
|
|
TEX_ATTR
|
|
};
|
|
|
|
moggle::shader_program 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;
|
|
}
|
|
|
|
template <typename T>
|
|
moggle::vbo<T> create_vbo(const std::vector<T>& data){
|
|
moggle::vbo<T> vbo;
|
|
vbo.bind(GL_ARRAY_BUFFER);
|
|
vbo.data(data);
|
|
return vbo;
|
|
}
|
|
|
|
moggle::vao create_vao(const moggle::vbo<GLPoint>& vbo){
|
|
moggle::vao vao;
|
|
vao.bind();
|
|
|
|
moggle::gl::enable_vertex_attribute_array(POS_ATTR);
|
|
|
|
vao.attribute(POS_ATTR, vbo);
|
|
|
|
return vao;
|
|
}
|
|
|
|
moggle::vao 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::pos);
|
|
vao.attribute(TEX_ATTR, vbo, &Vertex::tex);
|
|
|
|
return vao;
|
|
}
|
|
|
|
GLuint create_gl_texture(GLsizei width, GLsizei height){
|
|
GLuint tex = 0;
|
|
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);
|
|
return tex;
|
|
}
|
|
|
|
static std::vector<GLPoint> generate_random_points(size_t N){
|
|
std::vector<GLPoint> ret(N);
|
|
|
|
const auto d = 2.0;
|
|
for(auto& x : ret){
|
|
x[0] = d * rand() / float(RAND_MAX) - 0.5*d;
|
|
x[1] = d * rand() / float(RAND_MAX) - 0.5*d;
|
|
x[2] = d * rand() / float(RAND_MAX) - 0.5*d;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
cl::Context 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;
|
|
}
|
|
|