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.
199 lines
4.0 KiB
199 lines
4.0 KiB
#include <cl2.hpp>
|
|
|
|
#include <NSWrapper.hpp>
|
|
#include <png.hpp>
|
|
|
|
#include <moggle/core/gl.hpp>
|
|
#include <moggle/core/shader.hpp>
|
|
#include <moggle/core/vao.hpp>
|
|
#include <moggle/core/vbo.hpp>
|
|
|
|
#include <OpenGL/gl3.h>
|
|
|
|
#include <vector>
|
|
#include <iostream>
|
|
#include <fstream>
|
|
#include <sstream>
|
|
#include <cassert>
|
|
#include <cmath>
|
|
|
|
using namespace std;
|
|
|
|
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
|
|
|
|
struct Vertex{
|
|
moggle::vector3<GLfloat> position;
|
|
moggle::vector3<GLfloat> 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<Vertex> 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<GLfloat>("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<CL_CONTEXT_DEVICES>().front());
|
|
|
|
// make a lot of data
|
|
constexpr size_t W = 1280 * 1;
|
|
constexpr size_t H = 800 * 1;
|
|
std::vector<cl_float> 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();
|
|
}
|
|
|
|
|
|
|