void
GLPainter::draw_surface_part(const DrawingRequest& request)
{
  const SurfacePartRequest* surfacepartrequest
    = (SurfacePartRequest*) request.request_data;
  const Surface* surface = surfacepartrequest->surface;
  std::shared_ptr<GLTexture> gltexture = std::dynamic_pointer_cast<GLTexture>(surface->get_texture());
  GLSurfaceData *surface_data = reinterpret_cast<GLSurfaceData *>(surface->get_surface_data());

  float uv_width = surface_data->get_uv_right() - surface_data->get_uv_left();
  float uv_height = surface_data->get_uv_bottom() - surface_data->get_uv_top();

  float uv_left = surface_data->get_uv_left() + (uv_width * surfacepartrequest->srcrect.p1.x) / surface->get_width();
  float uv_top = surface_data->get_uv_top() + (uv_height * surfacepartrequest->srcrect.p1.y) / surface->get_height();
  float uv_right = surface_data->get_uv_left() + (uv_width * surfacepartrequest->srcrect.p2.x) / surface->get_width();
  float uv_bottom = surface_data->get_uv_top() + (uv_height * surfacepartrequest->srcrect.p2.y) / surface->get_height();

  GLuint th = gltexture->get_handle();
  if (th != s_last_texture) {
    s_last_texture = th;
    glBindTexture(GL_TEXTURE_2D, th);
  }
  intern_draw(request.pos.x, request.pos.y,
              request.pos.x + surfacepartrequest->dstsize.width,
              request.pos.y + surfacepartrequest->dstsize.height,
              uv_left,
              uv_top,
              uv_right,
              uv_bottom,
              0.0,
              request.alpha,
              request.color,
              Blend(),
              request.drawing_effect);
}
void
GLLightmap::draw_surface_part(const DrawingRequest& request)
{
  const SurfacePartRequest* surfacepartrequest
    = (SurfacePartRequest*) request.request_data;
  const Surface* surface = surfacepartrequest->surface;
  boost::shared_ptr<GLTexture> gltexture = boost::dynamic_pointer_cast<GLTexture>(surface->get_texture());
  GLSurfaceData *surface_data = reinterpret_cast<GLSurfaceData *>(surface->get_surface_data());

  float uv_width = surface_data->get_uv_right() - surface_data->get_uv_left();
  float uv_height = surface_data->get_uv_bottom() - surface_data->get_uv_top();

  float uv_left = surface_data->get_uv_left() + (uv_width * surfacepartrequest->source.x) / surface->get_width();
  float uv_top = surface_data->get_uv_top() + (uv_height * surfacepartrequest->source.y) / surface->get_height();
  float uv_right = surface_data->get_uv_left() + (uv_width * (surfacepartrequest->source.x + surfacepartrequest->size.x)) / surface->get_width();
  float uv_bottom = surface_data->get_uv_top() + (uv_height * (surfacepartrequest->source.y + surfacepartrequest->size.y)) / surface->get_height();

  glBindTexture(GL_TEXTURE_2D, gltexture->get_handle());
  intern_draw(request.pos.x, request.pos.y,
              request.pos.x + surfacepartrequest->size.x,
              request.pos.y + surfacepartrequest->size.y,
              uv_left,
              uv_top,
              uv_right,
              uv_bottom,
              0.0,
              request.alpha,
              Color(1.0, 1.0, 1.0),
              Blend(),
              request.drawing_effect);
}
void
Surface::draw(float x, float y, float alpha, DrawingEffect effect) const
{
  glColor4f(1.0f, 1.0f, 1.0f, alpha);
  glBindTexture(GL_TEXTURE_2D, texture->get_handle());

  intern_draw(x, y,
              x + width, y + height,
              uv_left, uv_top, uv_right, uv_bottom, effect);
}
void
Surface::draw_part(float src_x, float src_y, float dst_x, float dst_y,
                   float width, float height, float alpha,
                   DrawingEffect effect) const
{
  float uv_width = uv_right - uv_left;
  float uv_height = uv_bottom - uv_top;

  float uv_left = this->uv_left + (uv_width * src_x) / this->width;
  float uv_top = this->uv_top + (uv_height * src_y) / this->height;
  float uv_right = this->uv_left + (uv_width * (src_x + width)) / this->width;
  float uv_bottom = this->uv_top + (uv_height * (src_y + height)) / this->height;

  glColor4f(1.0f, 1.0f, 1.0f, alpha);
  glBindTexture(GL_TEXTURE_2D, texture->get_handle());

  intern_draw(dst_x, dst_y,
              dst_x + width, dst_y + height,
              uv_left, uv_top, uv_right, uv_bottom, effect);
}
void
GLLightmap::draw_surface(const DrawingRequest& request)
{
  const Surface* surface = (const Surface*) request.request_data;
  boost::shared_ptr<GLTexture> gltexture = boost::dynamic_pointer_cast<GLTexture>(surface->get_texture());
  GLSurfaceData *surface_data = reinterpret_cast<GLSurfaceData *>(surface->get_surface_data());

  glBindTexture(GL_TEXTURE_2D, gltexture->get_handle());
  intern_draw(request.pos.x, request.pos.y,
              request.pos.x + surface->get_width(),
              request.pos.y + surface->get_height(),
              surface_data->get_uv_left(),
              surface_data->get_uv_top(),
              surface_data->get_uv_right(),
              surface_data->get_uv_bottom(),
              request.angle,
              request.alpha,
              request.color,
              request.blend,
              request.drawing_effect);
}
void
GLPainter::draw_surface(const DrawingRequest& request)
{
  const Surface* surface = static_cast<const SurfaceRequest*>(request.request_data)->surface;
  if(surface == NULL)
  {
    return;
  }
  GLTexture* gltexture = static_cast<GLTexture*>(surface->get_texture().get());
  if(gltexture == NULL)
  {
    return;
  }
  GLSurfaceData *surface_data = static_cast<GLSurfaceData*>(surface->get_surface_data());
  if(surface_data == NULL)
  {
    return;
  }

  GLuint th = gltexture->get_handle();
  if (th != s_last_texture) {
    s_last_texture = th;
    glBindTexture(GL_TEXTURE_2D, th);
  }
  intern_draw(request.pos.x, request.pos.y,
              request.pos.x + surface->get_width() * 1.001f, // Avoid seams between background textures
              request.pos.y + surface->get_height() * 1.001f,
              surface_data->get_uv_left(),
              surface_data->get_uv_top(),
              surface_data->get_uv_right(),
              surface_data->get_uv_bottom(),
              request.angle,
              request.alpha,
              request.color,
              request.blend,
              request.drawing_effect);
}