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