Beispiel #1
0
void WorldRenderer::RenderWorld(const corgi::CameraInterface& camera,
                                fplbase::Renderer& renderer, World* world) {
  mat4 camera_transform = camera.GetTransformMatrix();
  renderer.set_color(mathfu::kOnes4f);
  renderer.DepthTest(true);
  renderer.set_model_view_projection(camera_transform);

  assert(textured_shadowed_shader_);
  textured_shadowed_shader_->SetUniform("view_projection", camera_transform);
  textured_shadowed_shader_->SetUniform("light_view_projection",
                                        light_camera_.GetTransformMatrix());
  textured_shadowed_shader_->SetUniform(
      "shadow_intensity",
      world->config->rendering_config()->shadow_intensity());

  float shadow_intensity =
      world->config->rendering_config()->shadow_intensity();
  float ambient_intensity = 1.0f - shadow_intensity;
  vec4 ambient =
      vec4(ambient_intensity, ambient_intensity, ambient_intensity, 1.0f);

  float diffuse_intensity = shadow_intensity;
  vec4 diffuse =
      vec4(diffuse_intensity, diffuse_intensity, diffuse_intensity, 1.0f);

  textured_lit_cutout_shader_->SetUniform("ambient_material", ambient);
  textured_lit_cutout_shader_->SetUniform("diffuse_material", diffuse);

  textured_lit_shader_->SetUniform("ambient_material", ambient);
  textured_lit_shader_->SetUniform("diffuse_material", diffuse);

  textured_lit_bank_shader_->SetUniform("ambient_material", ambient);
  textured_lit_bank_shader_->SetUniform("diffuse_material", diffuse);

  textured_skinned_lit_shader_->SetUniform("ambient_material", ambient);
  textured_skinned_lit_shader_->SetUniform("diffuse_material", diffuse);

  float texture_repeats = world->config->river_config()->texture_repeats();
  float river_offset = world->river_component.river_offset();

  river_shader_->SetUniform("river_offset",   river_offset);
  river_shader_->SetUniform("texture_repeats", texture_repeats);

  SetFogUniforms(textured_shadowed_shader_, world);
  SetFogUniforms(textured_lit_shader_, world);
  SetFogUniforms(textured_lit_bank_shader_, world);
  SetFogUniforms(textured_skinned_lit_shader_, world);

  shadow_map_.BindAsTexture(kShadowMapTextureID);

  if (!world->skip_rendermesh_rendering) {
    for (int pass = 0; pass < corgi::RenderPass_Count; pass++) {
      world->render_mesh_component.RenderPass(pass, camera, renderer);
    }
  }

  if (world->draw_debug_physics) {
    world->physics_component.DebugDrawWorld(&renderer, camera_transform);
  }
}
Beispiel #2
0
void WorldRenderer::CreateShadowMap(const corgi::CameraInterface& camera,
                                    fplbase::Renderer& renderer, World* world) {
  float shadow_map_resolution = static_cast<float>(
        world->config->rendering_config()->shadow_map_resolution());
  float shadow_map_zoom = world->config->rendering_config()->shadow_map_zoom();
  float shadow_map_offset =
      world->config->rendering_config()->shadow_map_offset();
  vec3 light_position =
      LoadVec3(world->config->rendering_config()->light_position());
  SetLightPosition(light_position);
  light_camera_.set_viewport_angle(kShadowMapViewportAngle / shadow_map_zoom);
  light_camera_.set_viewport_resolution(
      vec2(shadow_map_resolution, shadow_map_resolution));
  vec3 light_camera_focus =
      camera.position() + camera.facing() * shadow_map_offset;
  light_camera_focus.z() = 0;
  vec3 light_facing = light_camera_focus - light_camera_.position();
  light_camera_.set_facing(light_facing.Normalized());

  // Shadow map needs to be cleared to near-white, since that's
  // the maximum (furthest) depth.
  shadow_map_.SetAsRenderTarget();
  renderer.ClearFrameBuffer(kShadowMapClearColor);
  renderer.SetCulling(fplbase::Renderer::kCullBack);

  depth_shader_->Set(renderer);
  // Generate the shadow map:
  // TODO - modify this so that shadowcast is its own render pass
  for (int pass = 0; pass < corgi::RenderPass_Count; pass++) {
    world->render_mesh_component.RenderPass(pass, light_camera_,
                                            renderer, depth_shader_);
  }
}
void TouchscreenButton::DebugRender(const vec3& position,
                                    const vec3& texture_size,
                                    fplbase::Renderer& renderer) const {
#if defined(DEBUG_RENDER_BOUNDS)
    if (debug_shader_ && draw_bounds_) {
        const vec2 window_size = vec2(renderer.window_size());
        static const float kButtonZDepth = 0.0f;
        static const fplbase::Attribute kFormat[] = {fplbase::kPosition3f,
                                                     fplbase::kEND
                                                    };
        static const unsigned short kIndices[] = {0, 1, 1, 3, 2, 3, 2, 0};
        const vec3 bottom_left = position - (texture_size / 2.0f);
        const vec3 top_right = position + (texture_size / 2.0f);

        // vertex format is [x, y, z]
        float vertices[] = {
            bottom_left.x(), bottom_left.y(), bottom_left.z(), top_right.x(),
            bottom_left.y(), bottom_left.z(), bottom_left.x(), top_right.y(),
            top_right.z(),   top_right.x(),   top_right.y(),   top_right.z(),
        };
        renderer.set_color(vec4(1.0f, 0.0f, 1.0f, 1.0f));
        debug_shader_->Set(renderer);
        fplbase::Mesh::RenderArray(fplbase::Mesh::kLines, 8,
                                   kFormat, sizeof(float) * 3,
                                   reinterpret_cast<const char*>(vertices),
                                   kIndices);

        renderer.set_color(vec4(1.0f, 1.0f, 0.0f, 1.0f));
        debug_shader_->Set(renderer);
        static unsigned short indicesButtonDef[] = {1, 0, 1, 2, 2, 3, 3, 0};
        float verticesButtonDef[] = {
            button_def()->top_left()->x() * window_size.x(),
            button_def()->top_left()->y() * window_size.y(),
            kButtonZDepth,
            button_def()->top_left()->x() * window_size.x(),
            button_def()->bottom_right()->y() * window_size.y(),
            kButtonZDepth,
            button_def()->bottom_right()->x() * window_size.x(),
            button_def()->bottom_right()->y() * window_size.y(),
            kButtonZDepth,
            button_def()->bottom_right()->x() * window_size.x(),
            button_def()->top_left()->y() * window_size.y(),
            kButtonZDepth,
        };
        fplbase::Mesh::RenderArray(fplbase::Mesh::kLines, 8, kFormat,
                                   sizeof(float) * 3,
                                   reinterpret_cast<const char*>(verticesButtonDef),
                                   indicesButtonDef);
    }
#else
    (void)position;
    (void)texture_size;
    (void)renderer;
#endif  // DEBUG_RENDER_BOUNDS
}
Beispiel #4
0
void WorldRenderer::CreateShadowMap(const corgi::CameraInterface &camera,
                                    fplbase::Renderer &renderer, World *world) {
  PushDebugMarker("CreateShadowMap");

  PushDebugMarker("Setup");
  float shadow_map_resolution = static_cast<float>(
      world->config->rendering_config()->shadow_map_resolution());
  float shadow_map_zoom = world->config->rendering_config()->shadow_map_zoom();
  float shadow_map_offset =
      world->config->rendering_config()->shadow_map_offset();
  LightComponent *light_component =
      world->entity_manager.GetComponent<LightComponent>();

  const EntityRef &main_light_entity = light_component->begin()->entity;
  const TransformData *light_transform =
      world->entity_manager.GetComponentData<TransformData>(main_light_entity);
  vec3 light_position = light_transform->position;
  SetLightPosition(light_position);

  float viewport_angle =
      world->config->rendering_config()->shadow_map_viewport_angle() *
      kDegreesToRadians;
  light_camera_.set_viewport_angle(viewport_angle / shadow_map_zoom);
  light_camera_.set_viewport_resolution(
      vec2(shadow_map_resolution, shadow_map_resolution));
  vec3 light_camera_focus =
      camera.position() + camera.facing() * shadow_map_offset;
  light_camera_focus.z = 0;
  vec3 light_facing = light_camera_focus - light_camera_.position();
  light_camera_.set_facing(light_facing.Normalized());

  // Shadow map needs to be cleared to near-white, since that's
  // the maximum (furthest) depth.
  shadow_map_.SetAsRenderTarget();
  renderer.ClearFrameBuffer(kShadowMapClearColor);
  renderer.SetCulling(fplbase::kCullingModeBack);

  depth_shader_->Set(renderer);
  depth_skinned_shader_->Set(renderer);
  // Generate the shadow map:
  // TODO - modify this so that shadowcast is its own render pass
  PopDebugMarker(); // Setup

  for (int pass = 0; pass < corgi::RenderPass_Count; pass++) {
    PushDebugMarker("RenderPass");
    world->render_mesh_component.RenderPass(pass, light_camera_, renderer,
                                            ShaderIndex_Depth);
    PopDebugMarker();
  }

  fplbase::RenderTarget::ScreenRenderTarget(renderer).SetAsRenderTarget();
  PopDebugMarker(); // CreateShadowMap
}
void TouchscreenButton::Render(fplbase::Renderer& renderer) {
    static const float kButtonZDepth = 0.0f;

    if (!is_visible_) {
        return;
    }
    renderer.set_color(vec4(color_));

    auto mat = (button_.is_down() && down_material_ != nullptr)
               ? down_material_
               : up_current_ < up_materials_.size()
               ? up_materials_[up_current_]
               : nullptr;
    if (!mat) return;  // This is an invisible button.

    const vec2 window_size = vec2(renderer.window_size());
    const float texture_scale =
        window_size.y() * one_over_cannonical_window_height_;

    vec2 base_size = LoadVec2(
                         is_highlighted_ ? button_def_->draw_scale_highlighted()
                         : (button_.is_down() ? button_def_->draw_scale_pressed()
                            : button_def_->draw_scale_normal()));

    auto pulse = sinf(static_cast<float>(elapsed_time_) / 100.0f);
    if (is_highlighted_) {
        base_size += mathfu::kOnes2f * pulse * 0.05f;
    }

    vec3 texture_size =
        texture_scale * vec3(mat->textures()[0]->size().x() * base_size.x(),
                             -mat->textures()[0]->size().y() * base_size.y(), 0);

    vec3 position = vec3(button_def()->texture_position()->x() * window_size.x(),
                         button_def()->texture_position()->y() * window_size.y(),
                         kButtonZDepth);

    renderer.set_color(mathfu::kOnes4f);
    if (is_active_ || inactive_shader_ == nullptr) {
        shader_->Set(renderer);
    } else {
        inactive_shader_->Set(renderer);
    }
    mat->Set(renderer);
    fplbase::Mesh::RenderAAQuadAlongX(position - (texture_size / 2.0f),
                                      position + (texture_size / 2.0f), vec2(0, 1),
                                      vec2(1, 0));
#if defined(DEBUG_RENDER_BOUNDS)
    DebugRender(position, texture_size, renderer);
#endif  // DEBUG_RENDER_BOUNDS
}
Beispiel #6
0
static void RenderSettingsGear(fplbase::Renderer& renderer, World* world) {
  vec2i res = renderer.window_size();
  renderer.set_model_view_projection(mathfu::mat4::Ortho(
      0.0f, static_cast<float>(res.x), static_cast<float>(res.y), 0.0f,
      -1.0f, 1.0f));
  renderer.set_color(mathfu::kOnes4f);
  auto shader = world->asset_manager->LoadShader("shaders/textured");
  world->cardboard_settings_gear->Set(renderer);
  shader->Set(renderer);

  fplbase::Mesh::RenderAAQuadAlongX(
      vec3((res.x - kGearSize) / 2.0f, res.y - kGearSize, 0.0f),
      vec3((res.x + kGearSize) / 2.0f, res.y, 0.0f));
}
Beispiel #7
0
void RenderMeshComponent::RenderAllEntities(fplbase::Renderer& renderer,
                                            const CameraInterface& camera) {
  // Make sure we only draw the front-facing polygons:
  renderer.SetCulling(fplbase::Renderer::kCullBack);

  // Render the actual game:
  for (int pass = 0; pass < RenderPass_Count; pass++) {
    RenderPass(pass, camera, renderer);
  }
}
void StaticImage::Render(fplbase::Renderer& renderer) {
    if (!Valid()) return;
    if (!is_visible_) return;
    renderer.set_color(vec4(color_));

    auto material = materials_[current_material_index_];
    const vec2 window_size = vec2(renderer.window_size());
    const float texture_scale =
        window_size.y() * one_over_cannonical_window_height_;
    const vec2 texture_size =
        texture_scale * vec2(material->textures()[0]->size()) * vec2(scale_);
    const vec2 position_percent = vec2(texture_position_);
    const vec2 position = window_size * position_percent;

    const vec3 position3d(position.x(), position.y(), image_def_->z_depth());
    const vec3 texture_size3d(texture_size.x(), -texture_size.y(), 0.0f);

    shader_->Set(renderer);
    material->Set(renderer);

    fplbase::Mesh::RenderAAQuadAlongX(position3d - texture_size3d * 0.5f,
                                      position3d + texture_size3d * 0.5f, vec2(0, 1),
                                      vec2(1, 0));
}
Beispiel #9
0
// Draw the shadow map in the world, so we can see it.
void WorldRenderer::DebugShowShadowMap(const corgi::CameraInterface& camera,
                                       fplbase::Renderer& renderer) {
  fplbase::RenderTarget::ScreenRenderTarget(renderer).SetAsRenderTarget();

  static const mat4 kDebugTextureWorldTransform =
      mat4::FromScaleVector(mathfu::vec3(10.0f, 10.0f, 10.0f));

  const mat4 mvp = camera.GetTransformMatrix() * kDebugTextureWorldTransform;
  const mat4 world_matrix_inverse = kDebugTextureWorldTransform.Inverse();

  renderer.set_camera_pos(world_matrix_inverse * camera.position());
  renderer.set_light_pos(world_matrix_inverse * light_camera_.position());
  renderer.set_model_view_projection(mvp);
  renderer.set_color(vec4(1.0f, 1.0f, 1.0f, 1.0f));

  shadow_map_.BindAsTexture(0);

  textured_shader_->Set(renderer);

  // Render a large quad in the world, with the shadowmap texture on it:
  fplbase::Mesh::RenderAAQuadAlongX(vec3(0.0f, 0.0f, 0.0f),
                                    vec3(10.0f, 0.0f, 10.0f),
                                    vec2(1.0f, 0.0f), vec2(0.0f, 1.0f));
}
Beispiel #10
0
void RenderWorld(fplbase::Renderer& renderer, World* world, Camera& camera,
                 Camera* cardboard_camera, fplbase::InputSystem* input_system) {
  vec2 window_size = vec2(renderer.window_size());
  world->river_component.UpdateRiverMeshes();
  if (world->rendering_mode() == kRenderingStereoscopic) {
    window_size.x = window_size.x / 2;
    cardboard_camera->set_viewport_resolution(window_size);
  }
  camera.set_viewport_resolution(window_size);
  if (world->rendering_mode() == kRenderingStereoscopic) {
    // This takes care of setting/clearing the framebuffer for us.
    RenderStereoscopic(renderer, world, camera, cardboard_camera, input_system);
  } else {
    // Always clear the framebuffer, even though we overwrite it with the
    // skybox, since it's a speedup on tile-based architectures, see .e.g.:
    // http://www.seas.upenn.edu/~pcozzi/OpenGLInsights/OpenGLInsights-TileBasedArchitectures.pdf
    renderer.ClearFrameBuffer(mathfu::kZeros4f);

    if (world->RenderingOptionEnabled(kShadowEffect)) {
      world->world_renderer->RenderShadowMap(camera, renderer, world);
    }
    world->world_renderer->RenderWorld(camera, renderer, world);
  }
}
Beispiel #11
0
void WorldRenderer::RenderWorld(const corgi::CameraInterface &camera,
                                fplbase::Renderer &renderer, World *world) {
  PushDebugMarker("Render World");

  PushDebugMarker("Scene Setup");
  if (world->RenderingOptionsDirty()) {
    RefreshGlobalShaderDefines(world);
  }

  mat4 camera_transform = camera.GetTransformMatrix();
  renderer.set_color(mathfu::kOnes4f);
  renderer.SetDepthFunction(fplbase::kDepthFunctionLess);
  renderer.set_model_view_projection(camera_transform);

  float texture_repeats =
      world->CurrentLevel()->river_config()->texture_repeats();
  float river_offset = world->river_component.river_offset();

  if (world->RenderingOptionEnabled(kShadowEffect)) {
    world->asset_manager->ForEachShaderWithDefine(
        kDefinesText[kShadowEffect], [&](fplbase::Shader *shader) {
          shader->SetUniform("view_projection", camera_transform);
          shader->SetUniform("light_view_projection",
                             light_camera_.GetTransformMatrix());
        });
  }

  world->asset_manager->ForEachShaderWithDefine(
      "WATER", [&](fplbase::Shader *shader) {
        shader->SetUniform("river_offset", river_offset);
        shader->SetUniform("texture_repeats", texture_repeats);
      });

  world->asset_manager->ForEachShaderWithDefine(
      kDefinesText[kPhongShading],
      [&](fplbase::Shader *shader) { SetLightingUniforms(shader, world); });

  world->asset_manager->ForEachShaderWithDefine(
      "FOG_EFFECT",
      [&](fplbase::Shader *shader) { SetFogUniforms(shader, world); });

  shadow_map_.BindAsTexture(kShadowMapTextureID);
  PopDebugMarker(); // Scene Setup

  if (!world->skip_rendermesh_rendering) {
    for (int pass = 0; pass < corgi::RenderPass_Count; pass++) {
      PushDebugMarker("RenderPass");
      world->render_mesh_component.RenderPass(pass, camera, renderer);
      PopDebugMarker();
    }
  }

  if (world->draw_debug_physics) {
    PushDebugMarker("Debug Draw World");
    world->physics_component.DebugDrawWorld(&renderer, camera_transform);
    PopDebugMarker();
  }

  PushDebugMarker("Text");
  world->render_3d_text_component.RenderAllEntities(camera);
  PopDebugMarker();

  PopDebugMarker(); // Render World
}
Beispiel #12
0
static float AspectRatio(const fplbase::Renderer& renderer) {
  return static_cast<float>(renderer.window_size().x) /
         renderer.window_size().y;
}
Beispiel #13
0
// Render a single render-pass, by ID.
void RenderMeshComponent::RenderPass(int pass_id, const CameraInterface& camera,
                                     fplbase::Renderer& renderer,
                                     const fplbase::Shader* shader_override) {
  mat4 camera_vp = camera.GetTransformMatrix();

  for (size_t i = 0; i < pass_render_list_[pass_id].size(); i++) {
    EntityRef& entity = pass_render_list_[pass_id][i].entity;

    RenderMeshData* rendermesh_data = Data<RenderMeshData>(entity);

    TransformData* transform_data = Data<TransformData>(entity);

    AnimationData* anim_data = Data<AnimationData>(entity);

    // TODO: anim_data will set uniforms for an array of matricies. Each
    //       matrix represents one bone position.
    const bool has_anim = anim_data != nullptr && anim_data->motivator.Valid();
    const int num_mesh_bones = rendermesh_data->mesh->num_bones();
    const int num_anim_bones =
        has_anim ? anim_data->motivator.DefiningAnim()->NumBones() : 0;
    const bool has_one_bone_anim =
        has_anim && (num_mesh_bones <= 1 || num_anim_bones == 1);
    const mat4 world_transform =
        has_one_bone_anim
            ? transform_data->world_transform *
                  mat4::FromAffineTransform(
                      anim_data->motivator.GlobalTransforms()[0])
            : transform_data->world_transform;

    const mat4 mvp = camera_vp * world_transform;
    const mat4 world_matrix_inverse = world_transform.Inverse();
    renderer.set_light_pos(world_matrix_inverse * light_position_);
    renderer.set_color(rendermesh_data->tint);
    renderer.set_model(world_transform);

    // If the mesh has a skeleton, we need to update the bone positions.
    // The positions are normally supplied by the animation, but if they are
    // not, use the default pose in the RenderMesh.
    if (num_mesh_bones > 1) {
      const bool use_default_pose =
          num_anim_bones != num_mesh_bones || rendermesh_data->default_pose;
      const mathfu::AffineTransform* bone_transforms =
          use_default_pose ? rendermesh_data->mesh->bone_global_transforms()
                           : anim_data->motivator.GlobalTransforms();
      rendermesh_data->mesh->GatherShaderTransforms(
          bone_transforms, rendermesh_data->shader_transforms);
      renderer.SetBoneTransforms(rendermesh_data->shader_transforms,
                                 rendermesh_data->num_shader_transforms);
    }

    if (!camera.IsStereo()) {
      renderer.set_camera_pos(world_matrix_inverse * camera.position());
      renderer.set_model_view_projection(mvp);

      if (!shader_override && rendermesh_data->shader) {
        rendermesh_data->shader->Set(renderer);
      } else {
        shader_override->Set(renderer);
      }

      rendermesh_data->mesh->Render(renderer);
    } else {
      const fplbase::Shader* shader = nullptr;
      if (!shader_override && rendermesh_data->shader) {
        shader = rendermesh_data->shader;
      } else {
        shader = shader_override;
      }
      mathfu::vec4i viewport[2] = {camera.viewport(0), camera.viewport(1)};
      mat4 camera_vp_stereo = camera.GetTransformMatrix(1);
      mat4 mvp_matrices[2] = {mvp, camera_vp_stereo * world_transform};
      vec3 camera_positions[2] = {world_matrix_inverse * camera.position(0),
                                  world_matrix_inverse * camera.position(1)};
      rendermesh_data->mesh->RenderStereo(renderer, shader, viewport,
                                          mvp_matrices, camera_positions);
    }
  }
}