// // main.cpp // XcodeOpenCL // // Created by Joshua Moerman on 28/03/14. // // #include "cl2.hpp" #include "NSWrapper.hpp" #include "../../CodeTA/ImageStreams/include/png.hpp" #include #include #include #include #include #include #include using namespace std; #define BUFFER_OFFSET(i) ((char *)NULL + (i)) const GLfloat 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; GLuint program; GLint uniform; GLuint vao; GLuint posBufferName; void initialize(){ time = 0; program = glCreateProgram(); auto v_source_str = slurp("Fractal.vsh"); auto v_source = v_source_str.c_str(); GLuint v = glCreateShader(GL_VERTEX_SHADER); glShaderSource(v, 1, &v_source, NULL); glCompileShader(v); check_shader(v); auto f_source_str = slurp("Fractal.fsh"); auto f_source = f_source_str.c_str(); GLuint f = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(f, 1, &f_source, NULL); glCompileShader(f); check_shader(f); glAttachShader(program, v); glAttachShader(program, f); glBindAttribLocation(program, 0, "position"); glBindAttribLocation(program, 1, "color"); glLinkProgram(program); uniform = glGetUniformLocation(program, "rotation"); glDetachShader(program, v); glDeleteShader(v); glDetachShader(program, f); glDeleteShader(f); glGenVertexArrays(1, &vao); glBindVertexArray(vao); glGenBuffers(1, &posBufferName); glBindBuffer(GL_ARRAY_BUFFER, posBufferName); glBufferData(GL_ARRAY_BUFFER, 4*6*4, quad, GL_STATIC_DRAW); glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6*4, BUFFER_OFFSET(0)); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6*4, BUFFER_OFFSET(3*4)); } void draw(){ time += 1/60.0f; glClearColor(0.65f, 0.65f, 0.65f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glUseProgram(program); glUniform1f(uniform, time); glBindVertexArray(vao); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } }; int main(){ const bool mandelbrot = false; if(mandelbrot) { App a; NSAppWrapper app; app.create_window({ [&](ContextParameters){ a.initialize(); }, [&](ContextParameters){ a.draw(); }, nullptr }); app.run(); return 0; } // else, this other weird thing 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 * 4; constexpr size_t H = 800 * 4; 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 = 80, g = 40, 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; }