void marching_cubes_point(int x, int y, int z, float value) { if ((x >= width) || (y >= height) || (z >= depth) || (x < 0) || (y < 0) || (z < 0)) { error("Point (%i, %i, %i) outside of volume", x, y, z); } kernel_set_argument(write_point, 1, sizeof(int), &x); kernel_set_argument(write_point, 2, sizeof(int), &y); kernel_set_argument(write_point, 3, sizeof(int), &z); kernel_set_argument(write_point, 7, sizeof(float), &value); kernel_run(write_point, 1); }
void marching_cubes_init() { const int full_size = width * height * depth; /* Point rendering data */ vec4* point_data = malloc(sizeof(vec4) * full_size); if(point_data == NULL) { error("Not enough memory!"); } int x, y, z; for(x = 0; x < width; x++) for(y = 0; y < height; y++) for(z = 0; z < depth; z++) { int id = x + y * width + z * width * height; vec4 position = vec4_new(x, y, z, 1); point_data[id] = position; } glGenBuffers(1, &point_positions); glBindBuffer(GL_ARRAY_BUFFER, point_positions); glBufferData(GL_ARRAY_BUFFER, sizeof(vec4) * full_size, point_data, GL_STATIC_DRAW); free(point_data); vec4* point_color_data = malloc(sizeof(vec4) * full_size); memset(point_color_data, 0, sizeof(vec4) * full_size); glGenBuffers(1, &point_colors); glBindBuffer(GL_ARRAY_BUFFER, point_colors); glBufferData(GL_ARRAY_BUFFER, sizeof(vec4) * full_size, point_color_data, GL_DYNAMIC_COPY); free(point_color_data); point_color_buffer = kernel_memory_from_glbuffer(point_colors); /* OpenCL volume */ volume = kernel_memory_allocate(sizeof(float) * full_size); /* Vertex stuff */ vec4* vertex_pos_data = malloc(sizeof(vec4) * MAX_VERTS); memset(vertex_pos_data, 0, sizeof(vec4) * MAX_VERTS); glGenBuffers(1, &vertex_positions); glBindBuffer(GL_ARRAY_BUFFER, vertex_positions); glBufferData(GL_ARRAY_BUFFER, sizeof(vec4) * MAX_VERTS, vertex_pos_data, GL_DYNAMIC_COPY); free(vertex_pos_data); vertex_positions_buffer = kernel_memory_from_glbuffer(vertex_positions); vec4* vertex_norm_data = malloc(sizeof(vec4) * MAX_VERTS); memset(vertex_norm_data, 0, sizeof(vec4) * MAX_VERTS); glGenBuffers(1, &vertex_normals); glBindBuffer(GL_ARRAY_BUFFER, vertex_normals); glBufferData(GL_ARRAY_BUFFER, sizeof(vec4) * MAX_VERTS, vertex_norm_data, GL_DYNAMIC_COPY); free(vertex_norm_data); vertex_normals_buffer = kernel_memory_from_glbuffer(vertex_normals); vertex_index = kernel_memory_allocate(sizeof(int)); /* Kernels */ kernel_program* marching_cubes = asset_get(P("./kernels/marching_cubes.cl")); write_point = kernel_program_get_kernel(marching_cubes, "write_point"); kernel_set_argument(write_point, 0, sizeof(kernel_memory), &volume); kernel_set_argument(write_point, 4, sizeof(int), (void*)&width); kernel_set_argument(write_point, 5, sizeof(int), (void*)&height); kernel_set_argument(write_point, 6, sizeof(int), (void*)&depth); write_metaball = kernel_program_get_kernel(marching_cubes, "write_metaball"); kernel_set_argument(write_metaball, 0, sizeof(kernel_memory), &volume); write_metaballs = kernel_program_get_kernel(marching_cubes, "write_metaballs"); kernel_set_argument(write_metaballs, 0, sizeof(kernel_memory), &volume); write_clear = kernel_program_get_kernel(marching_cubes, "write_clear"); kernel_set_argument(write_clear, 0, sizeof(kernel_memory), &volume); write_point_color_back = kernel_program_get_kernel(marching_cubes, "write_point_color_back"); kernel_set_argument(write_point_color_back, 0, sizeof(kernel_memory), &volume); kernel_set_argument(write_point_color_back, 1, sizeof(kernel_memory), &point_color_buffer); construct_surface = kernel_program_get_kernel(marching_cubes, "construct_surface"); kernel_set_argument(construct_surface, 0, sizeof(kernel_memory), &volume); generate_normals = kernel_program_get_kernel(marching_cubes, "generate_flat_normals"); generate_normals_smooth = kernel_program_get_kernel(marching_cubes, "generate_smooth_normals"); }
void marching_cubes_update() { int size[3] = {width, height, depth}; /* Update volumes */ kernel_memory_gl_aquire(metaball_positions); kernel_memory_gl_aquire(vertex_positions_buffer); kernel_memory_gl_aquire(vertex_normals_buffer); kernel_set_argument(write_metaballs, 1, sizeof(cl_int3), &size); kernel_set_argument(write_metaballs, 2, sizeof(kernel_memory), &metaball_positions); kernel_set_argument(write_metaballs, 3, sizeof(cl_int), &num_metaballs); kernel_run(write_metaballs, width * height * depth); /* End */ int zero = 0; kernel_memory_write(vertex_index, sizeof(int), &zero); const int num_workers = (width-1) * (height-1) * (depth-1); kernel_set_argument(construct_surface, 0, sizeof(kernel_memory), &volume); kernel_set_argument(construct_surface, 1, sizeof(cl_int3), &size); kernel_set_argument(construct_surface, 2, sizeof(kernel_memory), &vertex_positions_buffer); kernel_set_argument(construct_surface, 3, sizeof(kernel_memory), &vertex_index); kernel_run(construct_surface, num_workers); kernel_memory_read(vertex_index, sizeof(cl_int), &num_verts); /* Generate Normals */ if (num_verts > 0) { kernel_set_argument(generate_normals_smooth, 0, sizeof(kernel_memory), &vertex_positions_buffer); kernel_set_argument(generate_normals_smooth, 1, sizeof(kernel_memory), &vertex_normals_buffer); kernel_set_argument(generate_normals_smooth, 2, sizeof(kernel_memory), &metaball_positions); kernel_set_argument(generate_normals_smooth, 3, sizeof(cl_int), &num_metaballs); kernel_run(generate_normals_smooth, num_verts); } /* kernel_set_argument(generate_normals, 0, sizeof(kernel_memory), &vertex_positions_buffer); kernel_set_argument(generate_normals, 1, sizeof(kernel_memory), &vertex_normals_buffer); kernel_run(generate_normals, num_verts/3); */ kernel_memory_gl_release(vertex_positions_buffer); kernel_memory_gl_release(vertex_normals_buffer); kernel_memory_gl_release(metaball_positions); kernel_run_finish(); }
void particles_init() { particle_positions = malloc(sizeof(vector4) * particle_count); particle_velocities = malloc(sizeof(vector4) * particle_count); particle_lifetimes = malloc(sizeof(float) * particle_count); particle_randoms = malloc(sizeof(vector4) * particle_count); srand(time(NULL)); for(int i = 0; i < particle_count; i++) { particle_lifetimes[i] = 999; particle_positions[i] = v4(0,0,0,0); particle_velocities[i] = v4(0,0,0,0); float rx = ((float)rand() / RAND_MAX) * 2 - 1; float ry = ((float)rand() / RAND_MAX) * 2 + 0.5; float rz = ((float)rand() / RAND_MAX) * 2 - 1; float rm = (float)rand() / RAND_MAX; vector3 rand = v3_mul(v3_normalize(v3(rx, ry, rz)), rm * 2); particle_randoms[i] = v4(rand.x, rand.y, rand.z, 0); } glGenBuffers(1, &positions_buffer); glBindBuffer(GL_ARRAY_BUFFER, positions_buffer); glBufferData(GL_ARRAY_BUFFER, sizeof(vector4) * particle_count, particle_positions, GL_DYNAMIC_COPY); glGenBuffers(1, &velocities_buffer); glBindBuffer(GL_ARRAY_BUFFER, velocities_buffer); glBufferData(GL_ARRAY_BUFFER, sizeof(vector4) * particle_count, particle_velocities, GL_DYNAMIC_COPY); glGenBuffers(1, &lifetimes_buffer); glBindBuffer(GL_ARRAY_BUFFER, lifetimes_buffer); glBufferData(GL_ARRAY_BUFFER, sizeof(float) * particle_count, particle_lifetimes, GL_DYNAMIC_COPY); glGenBuffers(1, &randoms_buffer); glBindBuffer(GL_ARRAY_BUFFER, randoms_buffer); glBufferData(GL_ARRAY_BUFFER, sizeof(vector4) * particle_count, particle_randoms, GL_DYNAMIC_COPY); #ifdef OPEN_GL_CPU #ifndef CPU_ONLY k_particle_positions = kernel_memory_allocate(sizeof(vector4) * particle_count); k_particle_velocities = kernel_memory_allocate(sizeof(vector4) * particle_count); k_particle_lifetimes = kernel_memory_allocate(sizeof(float) * particle_count); k_particle_randoms = kernel_memory_allocate(sizeof(vector4) * particle_count); kernel_memory_write(k_particle_positions, sizeof(vector4) * particle_count, particle_positions); kernel_memory_write(k_particle_velocities, sizeof(vector4) * particle_count, particle_velocities); kernel_memory_write(k_particle_lifetimes, sizeof(float) * particle_count, particle_lifetimes); kernel_memory_write(k_particle_randoms, sizeof(vector4) * particle_count, particle_randoms); #endif #else k_particle_positions = kernel_memory_from_glbuffer(positions_buffer); k_particle_velocities = kernel_memory_from_glbuffer(velocities_buffer); k_particle_lifetimes = kernel_memory_from_glbuffer(lifetimes_buffer); k_particle_randoms = kernel_memory_from_glbuffer(randoms_buffer); #endif kernel_program* program = asset_get("./kernels/particles.cl"); float max_life = 60.0; float min_velocity = 0.5; #ifndef CPU_ONLY k_update = kernel_program_get_kernel(program, "particle_update"); kernel_set_argument(k_update, 0, sizeof(kernel_memory), &k_particle_positions); kernel_set_argument(k_update, 1, sizeof(kernel_memory), &k_particle_velocities); kernel_set_argument(k_update, 2, sizeof(kernel_memory), &k_particle_lifetimes); kernel_set_argument(k_update, 3, sizeof(kernel_memory), &k_particle_randoms); kernel_set_argument(k_update, 4, sizeof(cl_float), &max_life); kernel_set_argument(k_update, 5, sizeof(cl_float), &min_velocity); kernel_set_argument(k_update, 9, sizeof(cl_int), &particle_count); #endif }
void particles_update(float timestep) { int random = rand(); #ifndef CPU_ONLY #ifndef OPEN_GL_CPU kernel_memory_gl_aquire(k_particle_positions); kernel_memory_gl_aquire(k_particle_velocities); kernel_memory_gl_aquire(k_particle_lifetimes); kernel_memory_gl_aquire(k_particle_randoms); #endif kernel_set_argument(k_update, 6, sizeof(cl_float), ×tep); kernel_set_argument(k_update, 7, sizeof(cl_int), &reset); kernel_set_argument(k_update, 8, sizeof(cl_int), &random); kernel_run(k_update, particle_count); reset = 0; #ifndef OPEN_GL_CPU kernel_memory_gl_release(k_particle_positions); kernel_memory_gl_release(k_particle_velocities); kernel_memory_gl_release(k_particle_lifetimes); kernel_memory_gl_release(k_particle_randoms); #endif kernel_run_finish(); #else for(int i = 0; i < particle_count; i++) { particle_lifetimes[i] = particle_lifetimes[i] + timestep; if ((particle_lifetimes[i] > 60.0) || ( v4_length(particle_velocities[i]) < 0.5 )) { particle_lifetimes[i] = 0.0; particle_positions[i] = v4(32,15,32,1); int random_index = (random + i) % particle_count; float rx = particle_randoms[random_index].x; float ry = particle_randoms[random_index].y; float rz = particle_randoms[random_index].z; particle_velocities[i] = v4_mul(v4(rx, ry, rz, 0), 5); } else { /* Update positions and velocity */ particle_positions[i].x = particle_positions[i].x + (particle_velocities[i].x * timestep); particle_positions[i].y = particle_positions[i].y + (particle_velocities[i].y * timestep); particle_positions[i].z = particle_positions[i].z + (particle_velocities[i].z * timestep); particle_velocities[i].y = particle_velocities[i].y - (9.81 * timestep); /* Bounce on floors */ if (particle_positions[i].y < 15.0) { particle_velocities[i].x = particle_velocities[i].x * 0.75; particle_velocities[i].y = particle_velocities[i].y * 0.75; particle_velocities[i].z = particle_velocities[i].z * 0.75; particle_velocities[i].y = -particle_velocities[i].y; } } } #endif }