Exemple #1
0
        /* virtual */ void
        perspective::do_changed(field::base& f)
        {
          TRACE("hugh::scene::object::camera::perspective::do_changed");

          if ((&f == &viewport) || (&f == &fovy)) {
            viewport_type const& vp(viewport.get());

            frustum_ = compute_frustum(vp, glm::vec2(frustum_.near, frustum_.far));

            if (std::numeric_limits<glm::vec2>::infinity() == frustum_.far) {
              projection_ = glm::infinitePerspective(fovy.get(),
                                                     vp.width / vp.height,
                                                     frustum_.near);
            } else {
              projection_ = glm::perspectiveFov(fovy.get(),
                                                vp.width, vp.height,
                                                frustum_.near, frustum_.far);
            }
          }
        
          else {
            base::do_changed(f);
          }
        }
Exemple #2
0
 /* explicit */
 base::base(matrix_type const& a, viewport_type const& b, glm::vec2 const& c)
   : object::base(),
     projection  (*this, "projection",
                  std::bind(&base::cb_get_projection, this),
                  std::bind(&base::cb_set_projection, this, std::placeholders::_1)),
     frustum     (*this, "frustum",
                  std::bind(&base::cb_get_frustum, this),
                  std::bind(&base::cb_set_frustum, this, std::placeholders::_1)),
     viewport    (*this, "viewport",   b),
     projection_ (a),
     frustum_    (compute_frustum(b, c))
 {
   TRACE("hugh::scene::object::camera::base::base");
 }
Exemple #3
0
void render_voxel_world(float campos[3])
{
   int num_build_remaining;
   int distance;
   float x = campos[0], y = campos[1];
   int qchunk_x, qchunk_y;
   int cam_x, cam_y;
   int i,j, rad;

#ifdef SINGLE_THREADED_MESHBUILD
   num_build_remaining = 1;
#else
   num_build_remaining = 0;
#endif

   cam_x = (int) floor(x);
   cam_y = (int) floor(y);

   qchunk_x = C_MESH_CHUNK_X_FOR_WORLD_X(cam_x);
   qchunk_y = C_MESH_CHUNK_Y_FOR_WORLD_Y(cam_y);

   request_mesh_generation(qchunk_x, qchunk_y, cam_x, cam_y);

   glEnable(GL_ALPHA_TEST);
   glAlphaFunc(GL_GREATER, 0.5);

   stbglUseProgram(main_prog);
   setup_uniforms(campos); // set uniforms to default values inefficiently
   glActiveTextureARB(GL_TEXTURE2_ARB);
   stbglEnableVertexAttribArray(0);

   rad = view_distance >> MESH_CHUNK_SIZE_X_LOG2;
   view_dist_for_display = view_distance;

   {
      float lighting[2][3] = { { 0,0,0 }, { 0.75,0.75,0.65f } };
      float bright = 32;
      lighting[0][0] = light_pos[0];
      lighting[0][1] = light_pos[1];
      lighting[0][2] = light_pos[2];
      lighting[1][0] *= bright;
      lighting[1][1] *= bright;
      lighting[1][2] *= bright;
      stbglUniform3fv(stbgl_find_uniform(main_prog, "light_source"), 2, lighting[0]);
   }

   quads_rendered = 0;
   quads_considered = 0;
   chunk_storage_rendered = 0;
   chunk_storage_considered = 0;
   chunk_locations = 0;
   chunks_considered = 0;
   chunks_in_frustum = 0;

   compute_frustum();

   for (distance = 0; distance <= rad; ++distance) {
      for (j=-distance; j <= distance; ++j) {
         for (i=-distance; i <= distance; ++i) {
            int cx = qchunk_x + i;
            int cy = qchunk_y + j;
            int slot_x = cx & (C_MESH_CHUNK_CACHE_X-1);
            int slot_y = cy & (C_MESH_CHUNK_CACHE_Y-1);
            mesh_chunk *mc = c_mesh_cache[slot_y][slot_x];

            if (stb_max(abs(i),abs(j)) != distance)
               continue;

            if (i*i + j*j > rad*rad)
               continue;

            if (mc == NULL || mc->chunk_x != cx || mc->chunk_y != cy || mc->vbuf == 0) {
               float estimated_bounds[2][3];
               if (num_build_remaining == 0)
                  continue;
               estimated_bounds[0][0] = (float) ( cx    << MESH_CHUNK_SIZE_X_LOG2);
               estimated_bounds[0][1] = (float) ( cy    << MESH_CHUNK_SIZE_Y_LOG2);
               estimated_bounds[0][2] = (float) (0);
               estimated_bounds[1][0] = (float) ((cx+1) << MESH_CHUNK_SIZE_X_LOG2);
               estimated_bounds[1][1] = (float) ((cy+1) << MESH_CHUNK_SIZE_Y_LOG2);
               estimated_bounds[1][2] = (float) (255);
               if (!is_box_in_frustum(estimated_bounds[0], estimated_bounds[1]))
                  continue;
               mc = build_mesh_chunk_for_coord(cx * C_MESH_CHUNK_CACHE_X, cy * C_MESH_CHUNK_CACHE_Y);
               --num_build_remaining;
            }

            ++chunk_locations;

            ++chunks_considered;
            quads_considered += mc->num_quads;
            chunk_storage_considered += mc->num_quads * 20;

            if (mc->num_quads) {
               if (is_box_in_frustum(mc->bounds[0], mc->bounds[1])) {
                  // @TODO if in range, frustum cull
                  stbglUniform3fv(stbgl_find_uniform(main_prog, "transform"), 3, mc->transform[0]);
                  glBindBufferARB(GL_ARRAY_BUFFER_ARB, mc->vbuf);
                  glVertexAttribIPointer(0, 1, GL_UNSIGNED_INT, 4, (void*) 0);
                  glBindTexture(GL_TEXTURE_BUFFER_ARB, mc->fbuf_tex);

                  glDrawArrays(GL_QUADS, 0, mc->num_quads*4);

                  quads_rendered += mc->num_quads;
                  ++chunks_in_frustum;
                  chunk_storage_rendered += mc->num_quads * 20;
               }
            }
         }
      }
   }

   if (num_build_remaining) {
      for (j=-rad; j <= rad; ++j) {
         for (i=-rad; i <= rad; ++i) {
            int cx = qchunk_x + i;
            int cy = qchunk_y + j;
            int slot_x = cx & (C_MESH_CHUNK_CACHE_X-1);
            int slot_y = cy & (C_MESH_CHUNK_CACHE_Y-1);
            mesh_chunk *mc = c_mesh_cache[slot_y][slot_x];
            if (mc->chunk_x != cx || mc->chunk_y != cy || mc->vbuf == 0) {
               mc = build_mesh_chunk_for_coord(cx * C_MESH_CHUNK_CACHE_X, cy * C_MESH_CHUNK_CACHE_Y);
               --num_build_remaining;
               if (num_build_remaining == 0)
                  goto done;
            }
         }
      }
      done:
      ;
   }

   {
      built_mesh bm;
      while (get_next_built_mesh(&bm)) {
         if (!bm.mc->has_triangles) {
            // server:
            physics_process_mesh_chunk(bm.mc);
            // don't free the physics data below, because the above call copies them
            bm.mc->allocs = NULL;
            free_mesh_chunk(bm.mc);
         } else {
            //s_process_mesh_chunk(bm.mc);
            // client:
            upload_mesh(bm.mc, bm.vertex_build_buffer, bm.face_buffer);
            set_mesh_chunk_for_coord(bm.mc->chunk_x * MESH_CHUNK_SIZE_X, bm.mc->chunk_y * MESH_CHUNK_SIZE_Y, bm.mc);
            free(bm.face_buffer);
            free(bm.vertex_build_buffer);
            bm.mc = NULL;
         }
      }
   }

   chunk_storage_total = 0;
   for (j=0; j < C_MESH_CHUNK_CACHE_Y; ++j)
      for (i=0; i < C_MESH_CHUNK_CACHE_X; ++i)
         if (c_mesh_cache[j][i] != NULL && c_mesh_cache[j][i]->vbuf)
            chunk_storage_total += c_mesh_cache[j][i]->num_quads * 20;

   stbglDisableVertexAttribArray(0);
   glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
   glActiveTextureARB(GL_TEXTURE0_ARB);

   stbglUseProgram(0);
}