#include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; #define BUFFER_OFFSET(i) ((char *)NULL + (i)) struct Vertex{ moggle::vector3 position; moggle::vector3 color; }; const Vertex quad[] = { // x y z, r g b {{1, -1, 0}, {1, 0, 0}}, {{-1, -1, 0}, {0, 1, 0}}, {{1, 1, 0}, {0, 0, 1}}, {{-1, 1, 0}, {1, 1, 1}} }; static void check_shader(GLuint s){ GLint logLength; glGetShaderiv(s, GL_INFO_LOG_LENGTH, &logLength); if (logLength > 0) { GLchar *log = (GLchar *)malloc(logLength); glGetShaderInfoLog(s, logLength, &logLength, log); std::cout << "Shader compile log:\n%s" << log << std::endl; free(log); } } string slurp(string filename) { ifstream in(filename); stringstream sstr; sstr << in.rdbuf(); return sstr.str(); } struct App { float time = 0; moggle::shader_program program; moggle::vao v; moggle::vbo quad_vbo; enum { POS_ATTR, COL_ATTR }; void initialize(){ auto vs = moggle::shader::from_file(moggle::shader_type::vertex, "Fractal.vsh"); auto fs = moggle::shader::from_file(moggle::shader_type::fragment, "Fractal.fsh"); program.attach(vs); program.attach(fs); program.bind_attribute(POS_ATTR, "position"); program.bind_attribute(COL_ATTR, "color"); program.link(); v.bind(); quad_vbo.bind(GL_ARRAY_BUFFER); quad_vbo.data(quad); moggle::gl::enable_vertex_attribute_array(POS_ATTR); moggle::gl::enable_vertex_attribute_array(COL_ATTR); v.attribute(POS_ATTR, quad_vbo, &Vertex::position); v.attribute(COL_ATTR, quad_vbo, &Vertex::color); } void draw(){ time += 1/60.0f; moggle::gl::clear_color(0.65f, 0.65f, 0.65f, 1.0f); moggle::gl::clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); program.use(); program.uniform("rotation").set(time); v.bind(); moggle::gl::draw_arrays(GL_TRIANGLE_STRIP, 0, 4); } }; struct CLApp { void initialize(){ auto context = cl::Context::getDefault(); cout << context << endl; cl_int err = 0; // build the program auto KernelSource = slurp("Kernel.cl"); cl::Program program(context, {KernelSource.c_str(), KernelSource.size()}, true, &err); check(err); cout << program << endl; // grab the kernel KernelOp kernel(program, "square", &err); check(err); // create a queue cl::CommandQueue queue(context, context.getInfo().front()); // make a lot of data constexpr size_t W = 1280 * 1; constexpr size_t H = 800 * 1; std::vector input_vector(W*H); for(int y = 0; y < H; ++y){ for(int x = 0; x < W; ++x){ input_vector[x + W*y] = 10 * ((x / double(W) - 0.5) + 1.3371337*(y / double(H) - 0.5)); } } // transfer data into buffers cl::Buffer input(context, input_vector.begin(), input_vector.end(), false, true); int r = 20, g = 20, b = 20; // DO IT (in place) for(int i = 0; i < r; ++i){ check(kernel(queue, W, H, input, W, input)); } // read back queue.finish(); auto red = input_vector; // DO IT (in place) for(int i = 0; i < g; ++i){ check(kernel(queue, W, H, input, W, input)); } // read back queue.finish(); auto green = input_vector; // DO IT (in place) for(int i = 0; i < b; ++i){ check(kernel(queue, W, H, input, W, input)); } // read back queue.finish(); auto& blue = input_vector; // test cout << "opencl is done" << endl; png::ostream<> image(W, H, "test.png"); for(int i = 0; i < red.size(); ++i){ image << png::ostream<>::pixel(blue[i], red[i], green[i]); } cout << "png is saved" << endl; } }; int main() { App a; CLApp b; NSAppWrapper app; app.create_window({ [&](ContextParameters){ a.initialize(); // b.initialize(); }, [&](ContextParameters){ a.draw(); }, nullptr }); app.run(); }