38 #include "SDL_image.h" 58 static std::string backend_name =
"SDL";
63 if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) {
64 throw SDLException(SDL_GetError());
67 if (SDL_VideoInit(driver.c_str()) < 0) {
68 throw SDLException(SDL_GetError());
74 SDL_SetRenderDrawColor(
m_renderer, 0, 0, 0, 255);
82 SDL_Surface *img = IMG_Load(icon.c_str());
88 SDL_SetWindowTitle(
m_window, title.c_str());
106 m_window = SDL_CreateWindow(
"", SDL_WINDOWPOS_UNDEFINED_DISPLAY(displayIndex), SDL_WINDOWPOS_UNDEFINED_DISPLAY(displayIndex), width, height, flags | SDL_WINDOW_SHOWN);
108 m_window = SDL_CreateWindow(
"", SDL_WINDOWPOS_CENTERED_DISPLAY(displayIndex), SDL_WINDOWPOS_CENTERED_DISPLAY(displayIndex), width, height, flags | SDL_WINDOW_SHOWN);
112 throw SDLException(SDL_GetError());
115 SDL_DisplayMode displayMode;
117 displayMode.w = width;
118 displayMode.h = height;
120 if (SDL_SetWindowDisplayMode(
m_window, &displayMode) != 0) {
121 throw SDLException(SDL_GetError());
125 flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE;
127 flags |= SDL_RENDERER_PRESENTVSYNC;
131 throw SDLException(SDL_GetError());
135 SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY,
"best");
137 SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY,
"linear");
139 SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY,
"nearest");
142 SDL_SetRenderDrawBlendMode(
m_renderer, SDL_BLENDMODE_BLEND);
148 throw SDLException(SDL_GetError());
152 <<
"Videomode " << width <<
"x" << height
153 <<
" at " << int32_t(bitsPerPixel) <<
" bpp with " << displayMode.refresh_rate <<
" Hz");
158 if (bitsPerPixel != 16) {
200 return new SDLImage(data, width, height);
204 return new SDLImage(name, data, width, height);
208 SDLException(
"Lighting not available under SDL");
237 SDL_SetRenderDrawColor(
m_renderer, r, g, b, a);
238 if (SDL_RenderDrawPoint(
m_renderer, x, y) == 0) {
245 SDL_SetRenderDrawColor(
m_renderer, r, g, b, a);
250 float xDiff = p2.
x - p1.
x;
251 float yDiff = p2.
y - p1.
y;
252 float halfW =
static_cast<float>(width) / 2.0;
256 }
else if (angle > 360.0) {
265 std::vector<Point> points;
266 Point p(p1.
x + cornerX, p1.
y + cornerY);
267 yMax = std::max(yMax, p.
y);
268 yMin = std::min(yMin, p.
y);
270 p.
x = p2.
x + cornerX;
271 p.
y = p2.
y + cornerY;
272 yMax = std::max(yMax, p.
y);
273 yMin = std::min(yMin, p.
y);
275 p.
x = p2.
x - cornerX;
276 p.
y = p2.
y - cornerY;
277 yMax = std::max(yMax, p.
y);
278 yMin = std::min(yMin, p.
y);
280 p.
x = p1.
x - cornerX;
281 p.
y = p1.
y - cornerY;
282 yMax = std::max(yMax, p.
y);
283 yMin = std::min(yMin, p.
y);
288 int32_t n = points.size();
289 for (; y <= yMax; ++y) {
290 std::vector<int32_t> xs;
292 for (int32_t i = 0; i < n; j = i++) {
293 if ((points[i].y < y && y <= points[j].y) || (points[j].y < y && y <= points[i].y)) {
294 int32_t x =
static_cast<int32_t
>(points[i].x +
static_cast<float>(y - points[i].y) / static_cast<float>(points[j].y - points[i].y) *
static_cast<float>(points[j].x - points[i].x));
296 for (int32_t k = xs.size() - 1; k && xs[k-1] > xs[k]; --k) {
297 std::swap(xs[k-1], xs[k]);
302 for (int32_t i = 0; i < xs.size(); i += 2) {
304 int32_t x2 = xs[i+1];
315 if (points.size() < 2) {
319 std::vector<Point>::const_iterator it = points.begin();
323 for (; it != points.end(); ++it) {
330 for (; it != points.end(); ++it) {
338 if (points.size() < 2) {
341 int32_t elements = points.size();
342 if (elements < 3 || steps < 2) {
346 bool thick = width > 1;
347 float step = 1.0 /
static_cast<float>(steps-1);
351 for (int32_t i = 0; i <= (elements*steps); ++i) {
360 for (int32_t i = 0; i <= (elements*steps); ++i) {
370 SDL_SetRenderDrawColor(
m_renderer, r, g, b, a);
382 SDL_SetRenderDrawColor(
m_renderer, r, g, b, a);
392 SDL_SetRenderDrawColor(
m_renderer, r, g, b, a);
397 fillRectangle(p1, static_cast<uint16_t>(p3.
x-p1.
x), static_cast<uint16_t>(p3.
y-p1.
y), r, g, b, a);
406 SDL_SetRenderDrawColor(
m_renderer, r, g, b, a);
417 int32_t radiusError = 1-x;
429 if (radiusError < 0) {
430 radiusError += 2 * y + 1;
433 radiusError += 2 * (y - x + 1);
439 float rad =
static_cast<float>(radius);
440 for (
float dy = 1; dy <= r; dy += 1.0) {
442 int32_t x = p.
x - dx;
443 for (; x <= p.
x + dx; x++) {
452 int32_t s = (sangle + 360) % 360;
453 int32_t e = (eangle + 360) % 360;
461 float angle =
static_cast<float>(s) * step;
463 for (;s <= e; ++s, angle += step) {
465 drawLine(oldPoint, newPoint, r, g, b, a);
472 int32_t s = (sangle + 360) % 360;
473 int32_t e = (eangle + 360) % 360;
481 std::vector<Point> points;
485 float angle =
static_cast<float>(s) * step;
486 for (;s <= e; ++s, angle += step) {
488 yMax = std::max(yMax, newPoint.
y);
489 yMin = std::min(yMin, newPoint.
y);
490 points.push_back(newPoint);
493 angle =
static_cast<float>(e) * step;
495 points.push_back(newPoint);
496 yMax = std::max(yMax, newPoint.
y);
497 yMin = std::min(yMin, newPoint.
y);
501 int32_t n = points.size();
502 for (; y <= yMax; ++y) {
503 std::vector<int32_t> xs;
505 for (int32_t i = 0; i < n; j = i++) {
506 if ((points[i].y < y && y <= points[j].y) || (points[j].y < y && y <= points[i].y)) {
507 int32_t x =
static_cast<int32_t
>(points[i].x +
static_cast<float>(y - points[i].y) / static_cast<float>(points[j].y - points[i].y) *
static_cast<float>(points[j].x - points[i].x));
509 for (int32_t k = xs.size() - 1; k && xs[k-1] > xs[k]; --k) {
510 std::swap(xs[k-1], xs[k]);
515 for (int32_t i = 0; i < xs.size(); i += 2) {
517 int32_t x2 = xs[i+1];
541 SDL_Surface* surface = SDL_CreateRGBSurface(0, swidth, sheight, 24,
548 SDL_BlitSurface(
m_screen, NULL, surface, NULL);
551 SDL_FreeSurface(surface);
559 const bool same_size = (width == swidth && height == sheight);
561 if (width < 1 || height < 1) {
570 SDL_Surface* src = SDL_CreateRGBSurface(0, swidth, sheight, 32,
577 SDL_BlitSurface(
m_screen, NULL, src, NULL);
579 SDL_Surface* dst = SDL_CreateRGBSurface(0, width, height, 32,
583 uint32_t* src_help_pointer = src_pointer;
586 int32_t x, y, *sx_ca, *sy_ca;
587 int32_t sx =
static_cast<int32_t
>(0xffff * src->w / dst->w);
588 int32_t sy =
static_cast<int32_t
>(0xffff * src->h / dst->h);
593 int32_t* sx_a =
new int32_t[dst->w + 1];
595 for (x = 0; x <= dst->w; x++) {
602 int32_t* sy_a =
new int32_t[dst->h + 1];
604 for (y = 0; y <= dst->h; y++) {
614 if (SDL_MUSTLOCK(src)) {
615 SDL_LockSurface(src);
618 if (SDL_MUSTLOCK(dst)) {
619 SDL_LockSurface(dst);
622 for (y = 0; y < dst->h; y++) {
623 src_pointer = src_help_pointer;
625 for (x = 0; x < dst->w; x++) {
626 *dst_pointer = *src_pointer;
628 src_pointer += (*sx_ca >> 16);
632 src_help_pointer = (
uint32_t*)((
uint8_t*)src_help_pointer + (*sy_ca >> 16) * src->pitch);
635 if (SDL_MUSTLOCK(dst)) {
636 SDL_UnlockSurface(dst);
638 if (SDL_MUSTLOCK(src)) {
639 SDL_UnlockSurface(src);
645 SDL_FreeSurface(src);
646 SDL_FreeSurface(dst);
663 SDL_SetRenderDrawColor(
m_renderer, 0, 0, 0, 255);
uint8_t getDisplay() const
Returns the display index.
uint16_t getHeight() const
Returns the height of the screen mode.
static T ATan2(T _x, T _y)
virtual void renderGuiGeometry(const std::vector< GuiVertex > &vertices, const std::vector< int > &indices, const DoublePoint &translation, ImagePtr texture)
Renders geometry required by gui.
Abstract interface for all the renderbackends.
uint32_t getSDLFlags() const
Returns the SDL flags used when testing this mode.
int8_t getRenderDriverIndex() const
Returns the index of the render driver.
uint32_t getHeight() const
virtual void createMainScreen(const ScreenMode &mode, const std::string &title, const std::string &icon)
Creates the mainscreen (the display window).
virtual const std::string & getName() const
The name of the renderbackend.
virtual void drawFillCircleSegment(const Point &p, uint32_t radius, int32_t sangle, int32_t eangle, uint8_t r, uint8_t g, uint8_t b, uint8_t a=255)
Draws a filled circle segment.
virtual void renderVertexArrays()
Render the Vertex Arrays, only for primitives (points, lines,...)
T h
Height of the rectangle.
Helper class to create log strings out from separate parts Usage: LMsg("some text") << variable << "...
uint32_t next(octet_iterator &it, octet_iterator end)
SDL_PixelFormat m_rgba_format
virtual void drawTriangle(const Point &p1, const Point &p2, const Point &p3, uint8_t r, uint8_t g, uint8_t b, uint8_t a=255)
Draws triangle between given points with given RGBA.
virtual void resetStencilBuffer(uint8_t buffer)
Reset stencil buffer with given value.
virtual void drawFillCircle(const Point &p, uint32_t radius, uint8_t r, uint8_t g, uint8_t b, uint8_t a=255)
Draws a filled circle.
The SDL implementation of the Image base class.
static void saveAsPng(const std::string &filename, const SDL_Surface &surface)
Saves the SDL_Surface to png format.
void setTexture(SDL_Texture *texture)
virtual void captureScreen(const std::string &filename)
Creates a Screenshot and saves it to a file.
uint32_t getFormat() const
Returns the pixel format enum.
virtual void setClipArea(const Rect &cliparea, bool clear)
Sets given clip area into image.
static Logger _log(LM_AUDIO)
virtual void drawQuad(const Point &p1, const Point &p2, const Point &p3, const Point &p4, uint8_t r, uint8_t g, uint8_t b, uint8_t a=255)
Draws quad between given points with given RGBA.
virtual ~RenderBackendSDL()
SDL_Texture * getTexture()
virtual Image * createImage(IResourceLoader *loader=0)
virtual void disableScissorTest()
Disables scissor test on the render backend.
virtual void startFrame()
Called when a new frame starts.
virtual void setScreenMode(const ScreenMode &mode)
Sets the mainscreen display mode.
virtual bool putPixel(int32_t x, int32_t y, uint8_t r, uint8_t g, uint8_t b, uint8_t a=255)
Writes pixel to given position.
PointType2D< int32_t > Point
virtual void drawCircleSegment(const Point &p, uint32_t radius, int32_t sangle, int32_t eangle, uint8_t r, uint8_t g, uint8_t b, uint8_t a=255)
Draws a circle segment.
SDL_Surface * getSurface()
virtual void drawLightPrimitive(const Point &p, uint8_t intensity, float radius, int32_t subdivisions, float xstretch, float ystretch, uint8_t red, uint8_t green, uint8_t blue)
Draws a light primitive that based on a triangle fan.
virtual void startFrame()
Called when a new frame starts.
virtual void drawRectangle(const Point &p, uint16_t w, uint16_t h, uint8_t r, uint8_t g, uint8_t b, uint8_t a=255)
Draws an axis parallel rectangle.
RenderBackendSDL(const SDL_Color &colorkey)
uint16_t getBPP() const
Returns the number of bits per pixel this mode uses.
virtual void drawBezier(const std::vector< Point > &points, int32_t steps, uint8_t width, uint8_t r, uint8_t g, uint8_t b, uint8_t a=255)
Draws bezier curve between given points with given RGBA and width.
virtual uint32_t getLightingModel() const
Gets the current light model.
virtual void detachRenderTarget()
Detaches current render surface.
virtual void resetLighting()
Reset lighting with default values.
virtual void changeRenderInfos(RenderDataType type, uint16_t elements, int32_t src, int32_t dst, bool light, bool stentest, uint8_t stenref, GLConstants stenop, GLConstants stenfunc, OverlayType otype=OVERLAY_TYPE_NONE)
Dirty helper function to change the render infos.
SDL_Color m_backgroundcolor
virtual void fillRectangle(const Point &p, uint16_t w, uint16_t h, uint8_t r, uint8_t g, uint8_t b, uint8_t a=255)
Draws a filled axis parallel rectangle.
#define FL_LOG(logger, msg)
virtual void endFrame()
Called when a frame is finished and ready to be displayed.
virtual void clearBackBuffer()
Forces a clear of the backbuffer.
virtual void endFrame()
Called when a frame is finished and ready to be displayed.
TextureFiltering m_textureFilter
virtual void changeBlending(int32_t scr, int32_t dst)
Change the Blendingmodel.
virtual void setLighting(float red, float green, float blue)
Set colors for lighting.
virtual void drawLine(const Point &p1, const Point &p2, uint8_t r, uint8_t g, uint8_t b, uint8_t a=255)
Draws line between given points with given RGBA.
SDL_Renderer * m_renderer
Point getBezierPoint(const std::vector< Point > &points, int32_t elements, float t)
Helper that returns an interpolated Point.
virtual void drawPolyLine(const std::vector< Point > &points, uint8_t width, uint8_t r, uint8_t g, uint8_t b, uint8_t a=255)
Draws lines between given points with given RGBA and width.
uint32_t getWidth() const
T * get() const
allows direct access to underlying pointer
virtual void attachRenderTarget(ImagePtr &img, bool discard)
Attaches given image as a new render surface.
virtual void drawCircle(const Point &p, uint32_t radius, uint8_t r, uint8_t g, uint8_t b, uint8_t a=255)
Draws a circle.
void deinit()
Performs cleanup actions.
uint16_t getWidth() const
Returns the width of the screen mode.
uint16_t getRefreshRate() const
Returns the refresh rate in Hz of this mode.
virtual void drawThickLine(const Point &p1, const Point &p2, uint8_t width, uint8_t r, uint8_t g, uint8_t b, uint8_t a=255)
Draws line between given points with given RGBA and width.
virtual void addImageToArray(uint32_t id, const Rect &rec, float const *st, uint8_t alpha, uint8_t const *rgba)
Add the Image data to the array.
T w
Width of the rectangle.
virtual void enableScissorTest()
Enables scissor test on the render backend.
virtual void setLightingModel(uint32_t lighting)
Initializes the light.
virtual void drawVertex(const Point &p, const uint8_t size, uint8_t r, uint8_t g, uint8_t b, uint8_t a=255)
Draws a quad that represents a vertex with given RGBA.
virtual void init(const std::string &driver)
Initializes the backend.
bool isFullScreen() const
True if this is a fullscreen mode.