void
Bomb::draw(SceneContext& sc)
{
  if (state == EXPLODE)
  {
    sc.color().draw(explo, pos);
    sc.light().draw(explolight, pos, 0);

    explolight.set_alpha(0.5);
    explolight.set_scale(0.5);

    sc.highlight().draw(explolight, pos, 0);

    explolight.set_alpha(1.0);
    explolight.set_scale(1.0);
  }
  else
  {
    sc.color().draw(sprite, pos);
    if (sprite.is_finished()) {
      sc.light().draw(light, pos, 0);
      sc.highlight().draw(highlight, pos, 0);
    }
  }
}
void
Player::draw (SceneContext& sc)
{
  //light.set_blend_func(GL_SRC_ALPHA, GL_ONE);
  //light.set_scale(4.0f);

  flashlight.set_blend_func(GL_SRC_ALPHA, GL_ONE);
  flashlight.set_scale(2.0f);

  flashlighthighlight.set_blend_func(GL_SRC_ALPHA, GL_ONE);
  flashlighthighlight.set_scale(2.0f);

  if (1)
    { // draw the 'stand-on' tile
      sc.highlight().fill_rect(Rect(Point(int(pos.x)/32 * 32, (int(pos.y)/32 + 1) * 32),
                                    Size(32, 32)),
                               Color(1.0f, 0.0f, 0.0f, 0.5f), 10000.0f);
    }

  //sc.highlight().draw(flashlighthighlight, pos - Vector(40, 80), 100.0f);
  //sc.light().draw(flashlight, pos - Vector(40, 80), 100.0f);
  sprite.draw(sc.color(), pos, z_pos);

  Entity* obj = find_useable_entity();
  if (obj)
    {
      std::string use_str = "[" + obj->get_use_verb() + "]";
      sc.highlight().draw(use_str, obj->get_pos().x, obj->get_pos().y - 150, 1000);
    }
  
  // Draw weapon at the 'Weapon' attachment point
  Sprite3D::PointID id = sprite.get_attachment_point_id("Weapon");
  sc.push_modelview();
  sc.translate(pos.x, pos.y);
  sc.mult_modelview(sprite.get_attachment_point_matrix(id));
  weapon->draw(sc);
  sc.pop_modelview();
}
void
VRDummy::draw(SceneContext& sc)
{
  sc.highlight().push_modelview();
  sc.highlight().translate(pos.x, pos.y);
  sc.highlight().rotate(rotation, 0.0f, 1.0f, 0.0f);
  sprite.draw(sc.highlight(), Vector(0, 0), 1200.0f);
  sc.highlight().pop_modelview();

  sc.highlight().draw(highlight, pos, 1500.0f);
}
void
Hedgehog::draw(SceneContext& gc)
{
  Sprite* s;

  if (state == DYING)
    s = &die_sprite;
  else
    s = &sprite;

  if (direction_left)
    s->set_vflip(true);
  else
    s->set_vflip(false);

  gc.color().draw(*s, pos, 2);
  //s->draw(int(pos.x), int(pos.y));
  gc.light().draw(light, pos, 0);
  gc.highlight().draw(highlight, pos, 0);
}
void
BasicCompositorImpl::render(SceneContext& sc, SceneGraph* sg, const GraphicContextState& gc_state)
{
  // Resize Lightmap, only needed in the editor, FIXME: move this into a 'set_size()' call
  if (m_lightmap->get_width()  != m_window.width /LIGHTMAP_DIV ||
      m_lightmap->get_height() != m_window.height/LIGHTMAP_DIV)
  {
    m_lightmap = Surface::create(m_window.width / LIGHTMAP_DIV, m_window.height / LIGHTMAP_DIV);
  }

  if (sc.get_render_mask() & SceneContext::LIGHTMAPSCREEN)
  {
    // Render the lightmap to the framebuffers->lightmap
    glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glPushMatrix();
    glScalef(1.0f / LIGHTMAP_DIV, 1.0f / LIGHTMAP_DIV, 1.0f);
    sc.light().render();
    glPopMatrix();

    if (sg)
    {
      glPushMatrix();
      glScalef(1.0f / LIGHTMAP_DIV, 1.0f / LIGHTMAP_DIV, 1.0f);
      glMultMatrixf(gc_state.get_matrix().matrix);
      sg->render(SceneContext::LIGHTMAP);
      glPopMatrix();
    }

    { // Copy lightmap to a texture
      OpenGLState state;
        
      state.bind_texture(m_lightmap->get_texture());
      state.activate();

      glCopyTexSubImage2D(GL_TEXTURE_2D, 
                          0,    // mipmap level
                          0, 0, // xoffset, yoffset
                          0, // x
                          m_window.height - static_cast<GLsizei>(m_lightmap->get_height()), // y (OpenGL is upside down)
                          static_cast<GLsizei>(m_lightmap->get_width()), 
                          static_cast<GLsizei>(m_lightmap->get_height()));
    }
  }

  if (sc.get_render_mask() & SceneContext::COLORMAP)
  {
    // Render the colormap to the framebuffers->screen
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    sc.color().render();

    if (sg)
    {
      glPushMatrix();
      glMultMatrixf(gc_state.get_matrix().matrix);
      sg->render(SceneContext::COLORMAP);
      glPopMatrix();
    }
  }

  if (sc.get_render_mask() & SceneContext::LIGHTMAP)
  { // Renders the lightmap to the screen     
    OpenGLState state;

    state.bind_texture(m_lightmap->get_texture());

    state.enable(GL_BLEND);
    state.set_blend_func(GL_DST_COLOR, GL_ZERO);
    state.activate();

    glBegin(GL_QUADS);

    glTexCoord2f(m_lightmap->get_uv().left, m_lightmap->get_uv().bottom);
    glVertex2i(0, 0);

    glTexCoord2f(m_lightmap->get_uv().right, m_lightmap->get_uv().bottom);
    glVertex2i(m_viewport.width, 0);

    glTexCoord2f(m_lightmap->get_uv().right, m_lightmap->get_uv().top);
    glVertex2i(m_viewport.width, m_viewport.height);

    glTexCoord2f(m_lightmap->get_uv().left, m_lightmap->get_uv().top);
    glVertex2i(0, m_viewport.height);

    glEnd();
  }

  if (sc.get_render_mask() & SceneContext::HIGHLIGHTMAP)
  {
    sc.highlight().render();

    if (sg)
    {
      glPushMatrix();
      glMultMatrixf(gc_state.get_matrix().matrix);
      sg->render(SceneContext::HIGHLIGHTMAP);
      glPopMatrix();
    }
  }

  if (sc.get_render_mask() & SceneContext::CONTROLMAP)
  {
    sc.control().render();

    if (sg)
    {
      glPushMatrix();
      glMultMatrixf(gc_state.get_matrix().matrix);
      sg->render(SceneContext::CONTROLMAP);
      glPopMatrix();
    }
  }
  
  // Clear all DrawingContexts
  sc.color().clear();
  sc.light().clear();
  sc.highlight().clear();
  sc.control().clear(); 
}
void
FramebufferCompositorImpl::render(SceneContext& sc, SceneGraph* sg, const GraphicContextState& gc_state)
{
  if (sc.get_render_mask() & SceneContext::LIGHTMAPSCREEN)
  {
    // Render the lightmap to framebuffers->lightmap
    Display::push_framebuffer(m_lightmap);

    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glPushMatrix();
    glTranslatef(0.0f, static_cast<float>(m_viewport.height - (m_viewport.height / LIGHTMAP_DIV)), 0.0f);
    glScalef(1.0f / LIGHTMAP_DIV, 1.0f / LIGHTMAP_DIV, 1.0f / LIGHTMAP_DIV);

    sc.light().render();

    if (sg)
    {
      glPushMatrix();
      glMultMatrixf(gc_state.get_matrix().matrix);
      sg->render(SceneContext::LIGHTMAP);
      glPopMatrix();
    }

    glPopMatrix();
    
    Display::pop_framebuffer();
  }

  { // Render the main screen
    Display::push_framebuffer(m_screen);

    if (sc.get_render_mask() & SceneContext::COLORMAP)
    {
      // Render the colormap to framebuffers->screen
      glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

      sc.color().render();

      if (sg)
      {
        glPushMatrix();
        glMultMatrixf(gc_state.get_matrix().matrix);
        sg->render(SceneContext::COLORMAP);
        glPopMatrix();
      }
    }

    if (sc.get_render_mask() & SceneContext::LIGHTMAP)
    { // Renders the lightmap to the screen
      render_lightmap(sc, sg);
    }

    if (sc.get_render_mask() & SceneContext::HIGHLIGHTMAP)
    {
      sc.highlight().render();

      if (sg)
      {
        glPushMatrix();
        glMultMatrixf(gc_state.get_matrix().matrix);
        sg->render(SceneContext::HIGHLIGHTMAP);
        glPopMatrix();
      }
    }

    if (sc.get_render_mask() & SceneContext::CONTROLMAP)
    {
      sc.control().render();

      if (sg)
      {
        glPushMatrix();
        glMultMatrixf(gc_state.get_matrix().matrix);
        sg->render(SceneContext::CONTROLMAP);
        glPopMatrix();
      }
    }

    Display::pop_framebuffer();
  }

  if (1) 
  {
    // Render the screen framebuffer to the actual screen 
    OpenGLState state;

    state.bind_texture(m_screen->get_texture(), 0);

    state.activate();

    glBegin(GL_QUADS);
    {
      glTexCoord2i(0, 1);
      glVertex2i(0, 0);

      glTexCoord2i(1, 1);
      glVertex2i(m_viewport.width, 0);

      glTexCoord2i(1, 0);
      glVertex2i(m_viewport.width, m_viewport.height);

      glTexCoord2i(0, 0);
      glVertex2i(0.0f, m_viewport.height);
    }
    glEnd();
  }

  // Clear all DrawingContexts
  sc.color().clear();
  sc.light().clear();
  sc.highlight().clear();
  sc.control().clear();
}