示例#1
0
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);
}
示例#2
0
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");
  
}
示例#3
0
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();
  
}
示例#4
0
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
  
}
示例#5
0
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), &timestep);
      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
  
}