#include "glutil.hpp"
#include "gl_renderer.hpp"
#include "gl_texture.hpp"
+#include "gl_surface_data.hpp"
#include "drawing_context.hpp"
#include "drawing_request.hpp"
#include "surface.hpp"
#include "obstack/obstackpp.hpp"
#define LIGHTMAP_DIV 5
-namespace
+namespace
{
- inline void intern_draw(float left, float top, float right, float bottom,
- float uv_left, float uv_top,
- float uv_right, float uv_bottom,
- float angle, float alpha,
- const Color& color,
- const Blend& blend,
- DrawingEffect effect)
- {
- if(effect & HORIZONTAL_FLIP)
- std::swap(uv_left, uv_right);
- if(effect & VERTICAL_FLIP) {
- std::swap(uv_top, uv_bottom);
+inline void intern_draw(float left, float top, float right, float bottom,
+ float uv_left, float uv_top,
+ float uv_right, float uv_bottom,
+ float angle, float alpha,
+ const Color& color,
+ const Blend& blend,
+ DrawingEffect effect)
+{
+ if(effect & HORIZONTAL_FLIP)
+ std::swap(uv_left, uv_right);
+
+ if(effect & VERTICAL_FLIP)
+ std::swap(uv_top, uv_bottom);
+
+ if (angle == 0.0f)
+ { // unrotated blit
+ glBlendFunc(blend.sfactor, blend.dfactor);
+ glColor4f(color.red, color.green, color.blue, color.alpha * alpha);
+ glBegin(GL_QUADS);
+ glTexCoord2f(uv_left, uv_top);
+ glVertex2f(left, top);
+
+ glTexCoord2f(uv_right, uv_top);
+ glVertex2f(right, top);
+
+ glTexCoord2f(uv_right, uv_bottom);
+ glVertex2f(right, bottom);
+
+ glTexCoord2f(uv_left, uv_bottom);
+ glVertex2f(left, bottom);
+ glEnd();
+ }
+ else
+ { // rotated blit
+ float center_x = (left + right) / 2;
+ float center_y = (top + bottom) / 2;
+
+ float sa = sinf(angle/180.0f*M_PI);
+ float ca = cosf(angle/180.0f*M_PI);
+
+ left -= center_x;
+ right -= center_x;
+
+ top -= center_y;
+ bottom -= center_y;
+
+ glBlendFunc(blend.sfactor, blend.dfactor);
+ glColor4f(color.red, color.green, color.blue, color.alpha * alpha);
+ glBegin(GL_QUADS);
+ glTexCoord2f(uv_left, uv_top);
+ glVertex2f(left*ca - top*sa + center_x,
+ left*sa + top*ca + center_y);
+
+ glTexCoord2f(uv_right, uv_top);
+ glVertex2f(right*ca - top*sa + center_x,
+ right*sa + top*ca + center_y);
+
+ glTexCoord2f(uv_right, uv_bottom);
+ glVertex2f(right*ca - bottom*sa + center_x,
+ right*sa + bottom*ca + center_y);
+
+ glTexCoord2f(uv_left, uv_bottom);
+ glVertex2f(left*ca - bottom*sa + center_x,
+ left*sa + bottom*ca + center_y);
+ glEnd();
}
- float center_x = (left + right) / 2;
- float center_y = (top + bottom) / 2;
-
- float sa = sinf(angle/180.0f*M_PI);
- float ca = cosf(angle/180.0f*M_PI);
-
- left -= center_x;
- right -= center_x;
-
- top -= center_y;
- bottom -= center_y;
-
- glBlendFunc(blend.sfactor, blend.dfactor);
- glColor4f(color.red, color.green, color.blue, color.alpha * alpha);
- glBegin(GL_QUADS);
- glTexCoord2f(uv_left, uv_top);
- glVertex2f(left*ca - top*sa + center_x,
- left*sa + top*ca + center_y);
-
- glTexCoord2f(uv_right, uv_top);
- glVertex2f(right*ca - top*sa + center_x,
- right*sa + top*ca + center_y);
-
- glTexCoord2f(uv_right, uv_bottom);
- glVertex2f(right*ca - bottom*sa + center_x,
- right*sa + bottom*ca + center_y);
-
- glTexCoord2f(uv_left, uv_bottom);
- glVertex2f(left*ca - bottom*sa + center_x,
- left*sa + bottom*ca + center_y);
- glEnd();
-
- // FIXME: find a better way to restore the blend mode
- glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- }
+ // FIXME: find a better way to restore the blend mode
+ glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+}
}
namespace GL
{
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->get_uv_left(),
- surface->get_uv_top(),
- surface->get_uv_right(),
- surface->get_uv_bottom(),
+ 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,
= (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->get_uv_right() - surface->get_uv_left();
- float uv_height = surface->get_uv_bottom() - surface->get_uv_top();
+ 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->get_uv_left() + (uv_width * surfacepartrequest->source.x) / surface->get_width();
- float uv_top = surface->get_uv_top() + (uv_height * surfacepartrequest->source.y) / surface->get_height();
- float uv_right = surface->get_uv_left() + (uv_width * (surfacepartrequest->source.x + surfacepartrequest->size.x)) / surface->get_width();
- float uv_bottom = surface->get_uv_top() + (uv_height * (surfacepartrequest->source.y + surfacepartrequest->size.y)) / surface->get_height();
+ 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,
}
void
- Renderer::draw_text(const DrawingRequest& request)
- {
- const TextRequest* textrequest = (TextRequest*) request.request_data;
-
- textrequest->font->draw(this, textrequest->text, request.pos,
- textrequest->alignment, request.drawing_effect, request.alpha);
- }
-
- void
Renderer::draw_filled_rect(const DrawingRequest& request)
{
const FillRectRequest* fillrectrequest
= (FillRectRequest*) request.request_data;
- 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);
-
- glBegin(GL_QUADS);
- glVertex2f(x, y);
- glVertex2f(x+w, y);
- glVertex2f(x+w, y+h);
- glVertex2f(x, y+h);
- glEnd();
- glEnable(GL_TEXTURE_2D);
- glColor4f(1, 1, 1, 1);
+ 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);
+
+ glBegin(GL_QUADS);
+ glVertex2f(x, y);
+ glVertex2f(x+w, y);
+ glVertex2f(x+w, y+h);
+ glVertex2f(x, y+h);
+ glEnd();
+ glEnable(GL_TEXTURE_2D);
+ glColor4f(1, 1, 1, 1);
+ }
}
void
// copy array line-by-line
for (int i = 0; i < SCREEN_HEIGHT; i++) {
char* src = pixels + (3 * SCREEN_WIDTH * (SCREEN_HEIGHT - i - 1));
+ if(SDL_MUSTLOCK(shot_surf))
+ {
+ SDL_LockSurface(shot_surf);
+ }
char* dst = ((char*)shot_surf->pixels) + i * shot_surf->pitch;
memcpy(dst, src, 3 * SCREEN_WIDTH);
+ if(SDL_MUSTLOCK(shot_surf))
+ {
+ SDL_UnlockSurface(shot_surf);
+ }
}
// free array