+Renderer::~Renderer()
+{
+}
+
+void
+Renderer::draw_surface(const DrawingRequest& request)
+{
+ const Surface* surface = (const Surface*) request.request_data;
+ GL::Texture *gltexture = dynamic_cast<GL::Texture *>(surface->get_texture());
+ GL::SurfaceData *surface_data = reinterpret_cast<GL::SurfaceData *>(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
+Renderer::draw_surface_part(const DrawingRequest& request)
+{
+ const SurfacePartRequest* surfacepartrequest
+ = (SurfacePartRequest*) request.request_data;
+ const Surface *surface = surfacepartrequest->surface;
+ GL::Texture *gltexture = dynamic_cast<GL::Texture *>(surface->get_texture());
+ GL::SurfaceData *surface_data = reinterpret_cast<GL::SurfaceData *>(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
+Renderer::draw_gradient(const DrawingRequest& request)
+{
+ const GradientRequest* gradientrequest
+ = (GradientRequest*) request.request_data;
+ const Color& top = gradientrequest->top;
+ const Color& bottom = gradientrequest->bottom;
+
+ glDisable(GL_TEXTURE_2D);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ glEnableClientState(GL_COLOR_ARRAY);
+
+ float vertices[] = {
+ 0, 0,
+ SCREEN_WIDTH, 0,
+ SCREEN_WIDTH, SCREEN_HEIGHT,
+ 0, SCREEN_HEIGHT
+ };
+ glVertexPointer(2, GL_FLOAT, 0, vertices);
+
+ float colors[] = {
+ top.red, top.green, top.blue, top.alpha,
+ top.red, top.green, top.blue, top.alpha,
+ bottom.red, bottom.green, bottom.blue, bottom.alpha,
+ bottom.red, bottom.green, bottom.blue, bottom.alpha,
+ };
+ glColorPointer(4, GL_FLOAT, 0, colors);
+
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+ glDisableClientState(GL_COLOR_ARRAY);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+
+ glEnable(GL_TEXTURE_2D);
+ glColor4f(1, 1, 1, 1);
+}
+
+void
+Renderer::draw_filled_rect(const DrawingRequest& request)
+{
+ const FillRectRequest* fillrectrequest
+ = (FillRectRequest*) request.request_data;
+
+ if (fillrectrequest->radius != 0.0f)
+ {
+ // draw round rect
+ // Keep radius in the limits, so that we get a circle instead of
+ // just graphic junk
+ float radius = std::min(fillrectrequest->radius,
+ std::min(fillrectrequest->size.x/2,
+ fillrectrequest->size.y/2));
+
+ // inner rectangle
+ Rect irect(request.pos.x + radius,
+ request.pos.y + radius,
+ request.pos.x + fillrectrequest->size.x - radius,
+ request.pos.y + fillrectrequest->size.y - radius);
+
+ glDisable(GL_TEXTURE_2D);
+ glColor4f(fillrectrequest->color.red, fillrectrequest->color.green,
+ fillrectrequest->color.blue, fillrectrequest->color.alpha);
+
+
+ int n = 8;
+ glBegin(GL_QUAD_STRIP);
+ for(int i = 0; i <= n; ++i)
+ {
+ float x = sinf(i * (M_PI/2) / n) * radius;
+ float y = cosf(i * (M_PI/2) / n) * radius;
+
+ glVertex2f(irect.get_left() - x, irect.get_top() - y);
+ glVertex2f(irect.get_right() + x, irect.get_top() - y);
+ }
+ for(int i = 0; i <= n; ++i)
+ {
+ float x = cosf(i * (M_PI/2) / n) * radius;
+ float y = sinf(i * (M_PI/2) / n) * radius;
+
+ glVertex2f(irect.get_left() - x, irect.get_bottom() + y);
+ glVertex2f(irect.get_right() + x, irect.get_bottom() + y);
+ }
+ glEnd();
+ glEnable(GL_TEXTURE_2D);
+ glColor4f(1, 1, 1, 1);
+ }
+ else
+ {
+ float x = request.pos.x;
+ float y = request.pos.y;
+ float w = fillrectrequest->size.x;
+ float h = fillrectrequest->size.y;
+
+ glDisable(GL_TEXTURE_2D);
+ glColor4f(fillrectrequest->color.red, fillrectrequest->color.green,
+ fillrectrequest->color.blue, fillrectrequest->color.alpha);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+
+ float vertices[] = {
+ x, y,
+ x+w, y,
+ x+w, y+h,
+ x, y+h
+ };
+ glVertexPointer(2, GL_FLOAT, 0, vertices);
+
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glEnable(GL_TEXTURE_2D);
+ glColor4f(1, 1, 1, 1);
+ }
+}
+
+void
+Renderer::draw_inverse_ellipse(const DrawingRequest& request)
+{
+ const InverseEllipseRequest* ellipse = (InverseEllipseRequest*)request.request_data;
+
+ glDisable(GL_TEXTURE_2D);
+ glColor4f(ellipse->color.red, ellipse->color.green,
+ ellipse->color.blue, ellipse->color.alpha);
+
+ float x = request.pos.x;
+ float y = request.pos.y;
+ float w = ellipse->size.x/2.0f;
+ float h = ellipse->size.y/2.0f;
+
+ static const int slices = 16;
+ static const int points = (slices+1) * 12;
+
+ float vertices[points * 2];
+ int p = 0;
+
+ // Bottom
+ vertices[p++] = SCREEN_WIDTH; vertices[p++] = SCREEN_HEIGHT;
+ vertices[p++] = 0; vertices[p++] = SCREEN_HEIGHT;
+ vertices[p++] = x; vertices[p++] = y+h;
+
+ // Top
+ vertices[p++] = SCREEN_WIDTH; vertices[p++] = 0;
+ vertices[p++] = 0; vertices[p++] = 0;
+ vertices[p++] = x; vertices[p++] = y-h;
+
+ // Left
+ vertices[p++] = SCREEN_WIDTH; vertices[p++] = 0;
+ vertices[p++] = SCREEN_WIDTH; vertices[p++] = SCREEN_HEIGHT;
+ vertices[p++] = x+w; vertices[p++] = y;
+
+ // Right
+ vertices[p++] = 0; vertices[p++] = 0;
+ vertices[p++] = 0; vertices[p++] = SCREEN_HEIGHT;
+ vertices[p++] = x-w; vertices[p++] = y;
+
+ for(int i = 0; i < slices; ++i)
+ {
+ float ex1 = sinf(M_PI/2 / slices * i) * w;
+ float ey1 = cosf(M_PI/2 / slices * i) * h;
+
+ float ex2 = sinf(M_PI/2 / slices * (i+1)) * w;
+ float ey2 = cosf(M_PI/2 / slices * (i+1)) * h;
+
+ // Bottom/Right
+ vertices[p++] = SCREEN_WIDTH; vertices[p++] = SCREEN_HEIGHT;
+ vertices[p++] = x + ex1; vertices[p++] = y + ey1;
+ vertices[p++] = x + ex2; vertices[p++] = y + ey2;
+
+ // Top/Left
+ vertices[p++] = 0; vertices[p++] = 0;
+ vertices[p++] = x - ex1; vertices[p++] = y - ey1;
+ vertices[p++] = x - ex2; vertices[p++] = y - ey2;
+
+ // Top/Right
+ vertices[p++] = SCREEN_WIDTH; vertices[p++] = 0;
+ vertices[p++] = x + ex1; vertices[p++] = y - ey1;
+ vertices[p++] = x + ex2; vertices[p++] = y - ey2;
+
+ // Bottom/Left
+ vertices[p++] = 0; vertices[p++] = SCREEN_HEIGHT;
+ vertices[p++] = x - ex1; vertices[p++] = y + ey1;
+ vertices[p++] = x - ex2; vertices[p++] = y + ey2;
+ }
+
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ glVertexPointer(2, GL_FLOAT, 0, vertices);
+
+ glDrawArrays(GL_TRIANGLES, 0, points);
+
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);