Joshua Moerman
11 years ago
8 changed files with 294 additions and 203 deletions
@ -0,0 +1,9 @@ |
|||||
|
|
||||
|
file(GLOB sources "*.cpp") |
||||
|
file(GLOB headers "*.hpp") |
||||
|
|
||||
|
set(libs common ${JCLWrapper_LIBRARIES} ${JNSAppWrapper_LIBRARIES} ${ImageStreams_LIBRARIES} moggle_xxx) |
||||
|
|
||||
|
add_library(common ${headers} ${sources}) |
||||
|
target_link_libraries(common ${libs}) |
||||
|
target_include_directories(common PUBLIC ".") |
@ -0,0 +1,174 @@ |
|||||
|
#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; |
||||
|
} |
@ -0,0 +1,51 @@ |
|||||
|
#pragma once |
||||
|
|
||||
|
#include <moggle/core/gl.hpp> |
||||
|
#include <moggle/core/shader.hpp> |
||||
|
#include <moggle/core/vao.hpp> |
||||
|
#include <moggle/core/vbo.hpp> |
||||
|
|
||||
|
#include <cl2.hpp> |
||||
|
#include <NSGLWrapper.hpp> |
||||
|
|
||||
|
struct Vertex{ |
||||
|
moggle::vector3<GLfloat> position; |
||||
|
moggle::vector2<GLfloat> tex_coord; |
||||
|
}; |
||||
|
|
||||
|
struct App { |
||||
|
size_t W = 128; |
||||
|
size_t H = 128; |
||||
|
float time = 0; |
||||
|
float wait = 2; |
||||
|
size_t frame = 0; |
||||
|
|
||||
|
App(GLContext & gl_context); |
||||
|
void draw(); |
||||
|
void resize(size_t w, size_t h); |
||||
|
|
||||
|
private: |
||||
|
GLuint gl_image1; |
||||
|
GLuint gl_image2; |
||||
|
moggle::vbo<Vertex> gl_vbo; |
||||
|
moggle::vao gl_vao; |
||||
|
moggle::shader_program gl_program; |
||||
|
|
||||
|
cl::Context cl_context; |
||||
|
cl::Device cl_device; |
||||
|
cl::CommandQueue cl_queue; |
||||
|
cl::ImageGL cl_image1; |
||||
|
cl::ImageGL cl_image2; |
||||
|
cl::Program cl_program; |
||||
|
KernelOp k_initialize; |
||||
|
KernelOp k_hblur; |
||||
|
KernelOp k_vblur; |
||||
|
KernelOp k_update; |
||||
|
|
||||
|
static moggle::shader_program create_shader_from_files(std::string vertex, std::string fragment); |
||||
|
static moggle::vbo<Vertex> create_vbo(std::vector<Vertex> const & data); |
||||
|
static moggle::vao create_vao(moggle::vbo<Vertex> const & vbo); |
||||
|
static GLuint create_gl_texture(GLsizei width, GLsizei height); |
||||
|
static cl::Context create_shared_cl_context(GLContext & gl_context); |
||||
|
cl::Program create_cl_program(std::string file); |
||||
|
}; |
@ -0,0 +1,10 @@ |
|||||
|
#pragma once |
||||
|
|
||||
|
#include <fstream> |
||||
|
#include <string> |
||||
|
|
||||
|
inline std::string slurp(std::string file_name){ |
||||
|
std::ifstream f(file_name); |
||||
|
if (!f) throw std::runtime_error(std::string("Unable to open file: ") + file_name); |
||||
|
return {std::istreambuf_iterator<char>(f), std::istreambuf_iterator<char>()}; |
||||
|
} |
Reference in new issue