diff --git a/Backend/SGSDL2/src/SGSDL2Graphics.cpp b/Backend/SGSDL2/src/SGSDL2Graphics.cpp index ff7b62d0..8bf2e144 100644 --- a/Backend/SGSDL2/src/SGSDL2Graphics.cpp +++ b/Backend/SGSDL2/src/SGSDL2Graphics.cpp @@ -98,44 +98,6 @@ void _sgsdl2_set_renderer_target(unsigned int window_idx, sg_bitmap_be *target) } } -void _sgsdl2_make_drawable(sg_bitmap_be *bitmap) -{ - // recreate all textures with target access - - int access, w, h; - - for (unsigned int i = 0; i < _sgsdl2_num_open_windows; i++) - { - SDL_Renderer *renderer = _sgsdl2_open_windows[i]->renderer; - - SDL_Texture *orig_tex = bitmap->texture[i]; - - SDL_QueryTexture(orig_tex, NULL, &access, &w, &h); - - if ( access == SDL_TEXTUREACCESS_TARGET ) continue; // already target - - // Create new texture - SDL_Texture *tex = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, w, h); - bitmap->texture[i] = tex; - - // Draw onto new texture - SDL_SetRenderTarget(renderer, tex); - SDL_RenderCopy(renderer, orig_tex, NULL, NULL); - - // Destroy old - SDL_DestroyTexture(orig_tex); - - _sgsdl2_restore_default_render_target(_sgsdl2_open_windows[i], bitmap); - } - - // Remove surface - SDL_FreeSurface(bitmap->surface); - bitmap->surface = NULL; - - // Set drawable - bitmap->drawable = true; -} - //-------------------------------------------------------------------------------------- // @@ -327,16 +289,6 @@ void _sgsdl2_add_window(sg_window_be * window) } } -bool _sgsdl2_has_open_bitmap_without_surface() -{ - for (uint i = 0; i < _sgsdl2_num_open_bitmaps; i++) - { - if ( ! _sgsdl2_open_bitmaps[i]->surface ) return true; - } - - return false; -} - void _sgsdl2_get_pixels_from_renderer(SDL_Renderer *renderer, int x, int y, int w, int h, int *pixels) { SDL_Rect rect = {x, y, w, h}; @@ -353,82 +305,69 @@ void _sgsdl2_get_pixels_from_renderer(SDL_Renderer *renderer, int x, int y, int free(raw_pixels); } -void _sgsdl2_bitmap_be_texture_to_pixels(sg_bitmap_be *bitmap_be, int *pixels, int sz, int w, int h) +void _sgsdl2_bitmap_be_texture_to_surface(sg_bitmap_be *bitmap) { - if (bitmap_be->drawable && _sgsdl2_num_open_windows > 0) + if (bitmap && (bitmap->last_draw_loc == SG_BITMAP_TEXTURE) && (_sgsdl2_num_open_windows > 0)) { - // read pixels from the texture - _sgsdl2_set_renderer_target(0, bitmap_be); - _sgsdl2_get_pixels_from_renderer(_sgsdl2_open_windows[0]->renderer, 0, 0, w, h, pixels); - _sgsdl2_restore_default_render_target(_sgsdl2_open_windows[0], bitmap_be); + SDL_Rect rect = {0, 0, bitmap->surface->w, bitmap->surface->h}; + _sgsdl2_set_renderer_target(0, bitmap); + + SDL_RenderReadPixels( + _sgsdl2_open_windows[0]->renderer, + &rect, + SDL_PIXELFORMAT_RGBA8888, + bitmap->surface->pixels, + bitmap->surface->w * 4 + ); + + bitmap->last_draw_loc = SG_BITMAP_NONE; } - else +} + +void _sgsdl2_texture_to_surface(sg_drawing_surface *drawing) +{ + if (drawing && (_sgsdl2_num_open_windows > 0)) { - // cannot read pixels ... make black image - for (int i = 0; i < sz; i++) { - pixels[i] = 255; - } + _sgsdl2_bitmap_be_texture_to_surface(static_cast(drawing->_data)); } } -void _sgsdl2_restore_surfaces() +void _sgsdl2_bitmaps_to_surface() { - Uint32 rmask, gmask, bmask, amask; - - /* SDL interprets each pixel as a 32-bit number, so our masks must depend - on the endianness (byte order) of the machine */ -#if SDL_BYTEORDER == SDL_BIG_ENDIAN - rmask = 0x000000ff; - gmask = 0x0000ff00; - bmask = 0x00ff0000; - amask = 0xff000000; -#else - rmask = 0xff000000; - gmask = 0x00ff0000; - bmask = 0x0000ff00; - amask = 0x000000ff; -#endif - for (uint i = 0; i < _sgsdl2_num_open_bitmaps; i++) { - if ( ! _sgsdl2_open_bitmaps[i]->surface ) - { - int w, h; - SDL_QueryTexture(_sgsdl2_open_bitmaps[i]->texture[0], NULL, NULL, &w, &h); - - int sz = 4 * w * h; - int pixels[w * h]; - -// std::cout << "sz = " << sz << " size of pixels = " << sizeof(pixels) << std::endl; - - memset(pixels, 0, sizeof(pixels)); - - _sgsdl2_bitmap_be_texture_to_pixels(_sgsdl2_open_bitmaps[i], pixels, sz, w, h); + _sgsdl2_bitmap_be_texture_to_surface(_sgsdl2_open_bitmaps[i]); + } +} - _sgsdl2_open_bitmaps[i]->surface = SDL_CreateRGBSurface(0, w, h, 32, rmask, gmask, bmask, amask); +void _sgsdl2_bitmap_be_surface_to_texture(sg_bitmap_be *bitmap) +{ + if (bitmap && (bitmap->last_draw_loc == SG_BITMAP_SURFACE) && (_sgsdl2_num_open_windows > 0)) + { + for( Uint32 i = 0; i < _sgsdl2_num_open_windows; i++ ) + { + SDL_UpdateTexture( + bitmap->texture[i], + NULL, + bitmap->surface->pixels, + bitmap->surface->pitch + ); + } - SDL_LockSurface(_sgsdl2_open_bitmaps[i]->surface); + bitmap->last_draw_loc = SG_BITMAP_NONE; + } +} - int x = 0, y = 0; - int *p = (int*)_sgsdl2_open_bitmaps[i]->surface->pixels; - for (int px = 0; px < (w * h); px++) - { - p[x + (y * _sgsdl2_open_bitmaps[i]->surface->pitch / 4)] = pixels[px]; -// std::cout << "Set pixel[" << x <<","<surface->pitch / 4) << " = " << p[x + (y * _sgsdl2_open_bitmaps[i]->surface->pitch / 4)] << " " << pixels[px] << std::endl; - x++; - if ( x >= w ) - { - x = 0; - y++; - } - } - - SDL_UnlockSurface(_sgsdl2_open_bitmaps[i]->surface); - } +void _sgsdl2_surface_to_texture(sg_drawing_surface *drawing) +{ + if (drawing && (_sgsdl2_num_open_windows > 0)) + { + _sgsdl2_bitmap_be_surface_to_texture(static_cast(drawing->_data)); } } + void _sgsdl2_remove_window(sg_window_be * window_be) { unsigned int idx = window_be->idx; @@ -438,10 +377,10 @@ void _sgsdl2_remove_window(sg_window_be * window_be) exit(-1); } - if ( _sgsdl2_num_open_windows == 1 && _sgsdl2_has_open_bitmap_without_surface() ) + if ( _sgsdl2_num_open_windows == 1 ) { // Need to keep a window open to retain the bitmap surface - _sgsdl2_restore_surfaces(); + _sgsdl2_bitmaps_to_surface(); } // Remove all of the textures for this window @@ -616,6 +555,110 @@ void _sgsdl2_destroy_bitmap(sg_bitmap_be *bitmap_be) free(bitmap_be); } +// +// Pixel Functions +// + +Uint32 _get_pixel(SDL_Surface *surface, int x, int y) +{ + Uint8 *p; + + if(!surface->pixels) return 0; + + p = static_cast(surface->pixels) + + y * surface->pitch + + x * surface->format->BytesPerPixel; + + if(x < 0 || y < 0 || x >= surface->w || y >= surface->h) return 0; + + uint32_t color; + + switch(surface->format->BytesPerPixel) { + case 1: + color = *p; + break; + case 2: + color = *reinterpret_cast(p); + break; + case 3: +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + color = static_cast(p[0] << 16 | p[1] << 8 | p[2]); +#else + color = static_cast(p[0] | p[1] << 8 | p[2] << 16); +#endif + break; + case 4: + color = *reinterpret_cast(p); + break; + default: + color = 0; + } + + uint8_t r, g, b, a; + + SDL_GetRGBA(color, surface->format, &r, &g, &b, &a); + return (uint32_t)(r << 24 | g << 16 | b << 8 | a); + +// switch(surface->format->BytesPerPixel) { +// case 1: +// return *p; +// case 2: +// return *(Uint16 *)p; +// case 3: +//#if SDL_BYTEORDER == SDL_BIG_ENDIAN +// return static_cast(p[0] << 16 | p[1] << 8 | p[2]); +//#else +// return static_cast(p[0] | p[1] << 8 | p[2] << 16); +//#endif +// case 4: +// uint32_t color; +// uint8_t r, g, b, a; +// color = *(Uint32 *)p; +// +// r = (uint8_t)((color & surface->format->Rmask) >> (surface->format->Rshift)); +// g = (uint8_t)((color & surface->format->Gmask) >> (surface->format->Gshift)); +// b = (uint8_t)((color & surface->format->Bmask) >> (surface->format->Bshift)); +// a = (uint8_t)((color & surface->format->Amask) >> (surface->format->Ashift)); +// return (uint32_t)(r << 24 | g << 16 | b << 8 | a); +// default: +// return 0; +// } +} + +void _set_pixel(SDL_Surface *surface, sg_color clr, int x, int y) +{ + Uint8 *p; + + if(!surface->pixels) return; + + p = static_cast(surface->pixels) + + y * surface->pitch + + x * surface->format->BytesPerPixel; + + if(x < 0 || y < 0 || x >= surface->w || y >= surface->h) return; + + Uint32 pixel = SDL_MapRGBA( + surface->format, + static_cast(clr.r * 255), + static_cast(clr.g * 255), + static_cast(clr.b * 255), + static_cast(clr.a * 255) + ); + + // Convert Uint32 into 4 bytes (now in the correct order, as dictated by SDL_MapRGBA) +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + p[0] = static_cast(pixel>>24); + p[1] = static_cast(pixel>>16); + p[2] = static_cast(pixel>>8); + p[3] = static_cast(pixel); +#else + p[0] = static_cast(pixel); + p[1] = static_cast(pixel>>8); + p[2] = static_cast(pixel>>16); + p[3] = static_cast(pixel>>24); +#endif +} + //-------------------------------------------------------------------------------------- // @@ -623,6 +666,7 @@ void _sgsdl2_destroy_bitmap(sg_bitmap_be *bitmap_be) // //-------------------------------------------------------------------------------------- + bool _sgsdl2_open_window(const char *title, int width, int height, unsigned int options, sg_window_be *window_be) { if( _sgsdl2_has_initial_window ) @@ -774,14 +818,27 @@ void _sgsdl2_clear_window(sg_drawing_surface *window, sg_color clr) } } +void _sgsdl2_clear_sdl_surface(SDL_Surface *surface, sg_color clr) +{ + if ( surface ) + { + for(int y = 0; y < surface->h; y++) + { + for(int x = 0; x < surface->w; x++) + { + _set_pixel(surface, clr, x, y); + } + } + } +} + + void _sgsdl2_clear_bitmap(sg_drawing_surface *bitmap, sg_color clr) { sg_bitmap_be * bitmap_be = static_cast(bitmap->_data); if ( bitmap_be ) { - if ( ! bitmap_be->drawable ) _sgsdl2_make_drawable( bitmap_be ); - for (unsigned int i = 0; i < _sgsdl2_num_open_windows; i++) { sg_window_be *window = _sgsdl2_open_windows[i]; @@ -793,6 +850,8 @@ void _sgsdl2_clear_bitmap(sg_drawing_surface *bitmap, sg_color clr) _sgsdl2_restore_default_render_target(window, bitmap_be); } + + _sgsdl2_clear_sdl_surface(bitmap_be->surface, clr); } } @@ -851,7 +910,6 @@ SDL_Renderer * _sgsdl2_prepared_renderer(sg_drawing_surface *surface, unsigned i case SGDS_Bitmap: { sg_bitmap_be *bitmap_be = static_cast(surface->_data); - if ( ! bitmap_be->drawable ) _sgsdl2_make_drawable( bitmap_be ); _sgsdl2_set_renderer_target(idx, bitmap_be); if (idx < _sgsdl2_num_open_windows) @@ -913,6 +971,9 @@ void sgsdl2_draw_aabb_rect(sg_drawing_surface *surface, sg_color clr, float *dat unsigned int count = _sgsdl2_renderer_count(surface); + _sgsdl2_surface_to_texture(surface); + static_cast(surface->_data)->last_draw_loc = SG_BITMAP_TEXTURE; + for (unsigned int i = 0; i < count; i++) { SDL_Renderer *renderer = _sgsdl2_prepared_renderer(surface, i); @@ -941,6 +1002,9 @@ void sgsdl2_fill_aabb_rect(sg_drawing_surface *surface, sg_color clr, float *dat unsigned int count = _sgsdl2_renderer_count(surface); + _sgsdl2_surface_to_texture(surface); + static_cast(surface->_data)->last_draw_loc = SG_BITMAP_TEXTURE; + for (unsigned int i = 0; i < count; i++) { SDL_Renderer *renderer = _sgsdl2_prepared_renderer(surface, i); @@ -978,6 +1042,9 @@ void sgsdl2_draw_rect(sg_drawing_surface *surface, sg_color clr, float *data, in unsigned int count = _sgsdl2_renderer_count(surface); + _sgsdl2_surface_to_texture(surface); + static_cast(surface->_data)->last_draw_loc = SG_BITMAP_TEXTURE; + for (unsigned int i = 0; i < count; i++) { SDL_Renderer *renderer = _sgsdl2_prepared_renderer(surface, i); @@ -1024,6 +1091,9 @@ void sgsdl2_fill_rect(sg_drawing_surface *surface, sg_color clr, float *data, in unsigned int count = _sgsdl2_renderer_count(surface); + _sgsdl2_surface_to_texture(surface); + static_cast(surface->_data)->last_draw_loc = SG_BITMAP_TEXTURE; + for (unsigned int i = 0; i < count; i++) { SDL_Renderer *renderer = _sgsdl2_prepared_renderer(surface, i); @@ -1063,6 +1133,9 @@ void sgsdl2_draw_triangle(sg_drawing_surface *surface, sg_color clr, float *data unsigned int count = _sgsdl2_renderer_count(surface); + _sgsdl2_surface_to_texture(surface); + static_cast(surface->_data)->last_draw_loc = SG_BITMAP_TEXTURE; + for (unsigned int i = 0; i < count; i++) { SDL_Renderer *renderer = _sgsdl2_prepared_renderer(surface, i); @@ -1089,9 +1162,11 @@ void sgsdl2_fill_triangle(sg_drawing_surface *surface, sg_color clr, float *data float x2 = data[2], y2 = data[3]; float x3 = data[4], y3 = data[5]; - unsigned int count = _sgsdl2_renderer_count(surface); + _sgsdl2_surface_to_texture(surface); + static_cast(surface->_data)->last_draw_loc = SG_BITMAP_TEXTURE; + for (unsigned int i = 0; i < count; i++) { SDL_Renderer *renderer = _sgsdl2_prepared_renderer(surface, i); @@ -1129,6 +1204,9 @@ void sgsdl2_draw_ellipse(sg_drawing_surface *surface, sg_color clr, float *data, unsigned int count = _sgsdl2_renderer_count(surface); + _sgsdl2_surface_to_texture(surface); + static_cast(surface->_data)->last_draw_loc = SG_BITMAP_TEXTURE; + for (unsigned int i = 0; i < count; i++) { SDL_Renderer *renderer = _sgsdl2_prepared_renderer(surface, i); @@ -1161,6 +1239,9 @@ void sgsdl2_fill_ellipse(sg_drawing_surface *surface, sg_color clr, float *data, unsigned int count = _sgsdl2_renderer_count(surface); + _sgsdl2_surface_to_texture(surface); + static_cast(surface->_data)->last_draw_loc = SG_BITMAP_TEXTURE; + for (unsigned int i = 0; i < count; i++) { SDL_Renderer *renderer = _sgsdl2_prepared_renderer(surface, i); @@ -1195,6 +1276,18 @@ void sgsdl2_draw_pixel(sg_drawing_surface *surface, sg_color clr, float *data, i // 2 values = 1 point int x1 = static_cast(data[0]), y1 = static_cast(data[1]); + if (surface->kind == SGDS_Bitmap) + { + sg_bitmap_be *bitmap_be = static_cast(surface->_data); + + _sgsdl2_texture_to_surface(surface); + bitmap_be->last_draw_loc = SG_BITMAP_SURFACE; + + _set_pixel(bitmap_be->surface, clr, x1, y1); + + return; + } + unsigned int count = _sgsdl2_renderer_count(surface); for (unsigned int i = 0; i < count; i++) @@ -1267,6 +1360,9 @@ void sgsdl2_draw_circle(sg_drawing_surface *surface, sg_color clr, float *data, unsigned int count = _sgsdl2_renderer_count(surface); + _sgsdl2_surface_to_texture(surface); + static_cast(surface->_data)->last_draw_loc = SG_BITMAP_TEXTURE; + for (unsigned int i = 0; i < count; i++) { SDL_Renderer *renderer = _sgsdl2_prepared_renderer(surface, i); @@ -1302,6 +1398,9 @@ void sgsdl2_fill_circle(sg_drawing_surface *surface, sg_color clr, float *data, unsigned int count = _sgsdl2_renderer_count(surface); + _sgsdl2_surface_to_texture(surface); + static_cast(surface->_data)->last_draw_loc = SG_BITMAP_TEXTURE; + for (unsigned int i = 0; i < count; i++) { SDL_Renderer *renderer = _sgsdl2_prepared_renderer(surface, i); @@ -1347,6 +1446,9 @@ void sgsdl2_draw_line(sg_drawing_surface *surface, sg_color clr, float *data, in unsigned int count = _sgsdl2_renderer_count(surface); + _sgsdl2_surface_to_texture(surface); + static_cast(surface->_data)->last_draw_loc = SG_BITMAP_TEXTURE; + for (unsigned int i = 0; i < count; i++) { SDL_Renderer *renderer = _sgsdl2_prepared_renderer(surface, i); @@ -1470,81 +1572,16 @@ void sgsdl2_clear_clip_rect(sg_drawing_surface *surface) } } -Uint32 _get_pixel(SDL_Surface *surface, int x, int y) -{ - Uint8 *p; - - if(!surface->pixels) return 0; - - p = static_cast(surface->pixels) - + y * surface->pitch - + x * surface->format->BytesPerPixel; - - if(x < 0 || y < 0 || x >= surface->w || y >= surface->h) return 0; - - uint32_t color; - - switch(surface->format->BytesPerPixel) { - case 1: - color = *p; - break; - case 2: - color = *reinterpret_cast(p); - break; - case 3: -#if SDL_BYTEORDER == SDL_BIG_ENDIAN - color = static_cast(p[0] << 16 | p[1] << 8 | p[2]); -#else - color = static_cast(p[0] | p[1] << 8 | p[2] << 16); -#endif - break; - case 4: - color = *reinterpret_cast(p); - break; - default: - color = 0; - } - - uint8_t r, g, b, a; - - SDL_GetRGBA(color, surface->format, &r, &g, &b, &a); - return (uint32_t)(r << 24 | g << 16 | b << 8 | a); - -// switch(surface->format->BytesPerPixel) { -// case 1: -// return *p; -// case 2: -// return *(Uint16 *)p; -// case 3: -//#if SDL_BYTEORDER == SDL_BIG_ENDIAN -// return static_cast(p[0] << 16 | p[1] << 8 | p[2]); -//#else -// return static_cast(p[0] | p[1] << 8 | p[2] << 16); -//#endif -// case 4: -// uint32_t color; -// uint8_t r, g, b, a; -// color = *(Uint32 *)p; -// -// r = (uint8_t)((color & surface->format->Rmask) >> (surface->format->Rshift)); -// g = (uint8_t)((color & surface->format->Gmask) >> (surface->format->Gshift)); -// b = (uint8_t)((color & surface->format->Bmask) >> (surface->format->Bshift)); -// a = (uint8_t)((color & surface->format->Amask) >> (surface->format->Ashift)); -// return (uint32_t)(r << 24 | g << 16 | b << 8 | a); -// default: -// return 0; -// } -} // // To Pixels // - -void sgsdl2_to_pixels(sg_drawing_surface *surface, int *pixels, int sz); void sgsdl2_to_pixels(sg_drawing_surface *surface, int *pixels, int sz) { if ( ! surface || ! surface->_data || surface->width * surface->height != sz) return; + SDL_Rect rect = {0, 0, surface->width, surface->height}; + switch (surface->kind) { case SGDS_Window: @@ -1562,19 +1599,13 @@ void sgsdl2_to_pixels(sg_drawing_surface *surface, int *pixels, int sz) { sg_bitmap_be * bitmap_be = static_cast(surface->_data); - if ( ! bitmap_be->surface ) // read from texture - { - _sgsdl2_bitmap_be_texture_to_pixels(bitmap_be, pixels, sz, surface->width, surface->height); - } - else + _sgsdl2_texture_to_surface(surface); + + for (int y = 0; y < surface->height; y++) { - // read from surface - for (int y = 0; y < surface->height; y++) + for(int x = 0; x < surface->width; x++) { - for(int x = 0; x < surface->width; x++) - { - pixels[y * surface->width + x] = static_cast(_get_pixel(bitmap_be->surface, x, y)); - } + pixels[y * surface->width + x] = static_cast(_get_pixel(bitmap_be->surface, x, y)); } } break; @@ -1607,8 +1638,6 @@ void sgsdl2_show_border(sg_drawing_surface *surface, int border) } case SGDS_Bitmap: - break; - case SGDS_Unknown: break; } @@ -1631,8 +1660,6 @@ void sgsdl2_show_fullscreen(sg_drawing_surface *surface, int fullscreen) } case SGDS_Bitmap: - break; - case SGDS_Unknown: break; } @@ -1690,8 +1717,6 @@ void sgsdl2_resize(sg_drawing_surface *surface, int width, int height) } case SGDS_Bitmap: - break; - case SGDS_Unknown: break; } @@ -1825,11 +1850,12 @@ void sgsdl2_load_graphics_fns(sg_interface * functions) sg_drawing_surface sgsdl2_create_bitmap(int width, int height) { internal_sgsdl2_init(); - if ( _sgsdl2_num_open_windows == 0 ) _sgsdl2_create_initial_window(); + //if ( _sgsdl2_num_open_windows == 0 ) _sgsdl2_create_initial_window(); sg_drawing_surface result = { SGDS_Unknown, 0, 0, NULL }; result.kind = SGDS_Bitmap; + sg_bitmap_be *data = static_cast(malloc(sizeof(sg_bitmap_be))); result._data = data; @@ -1838,20 +1864,32 @@ sg_drawing_surface sgsdl2_create_bitmap(int width, int height) data->clipped = false; data->clip = {0, 0, width, height}; - data->drawable = true; - data->surface = NULL; - data->texture = static_cast(malloc(sizeof(SDL_Texture*) * _sgsdl2_num_open_windows)); - for (unsigned int i = 0; i < _sgsdl2_num_open_windows; i++) + data->last_draw_loc = SG_BITMAP_NONE; + + data->surface = SDL_CreateRGBSurface(0, width, height, 32, 0xff000000, 0xff0000, 0xff00, 0xff); + _sgsdl2_clear_sdl_surface(data->surface,{0xff, 0xff, 0xff, 0xff}); + + + if (_sgsdl2_num_open_windows > 0) { - data->texture[i] = SDL_CreateTexture(_sgsdl2_open_windows[i]->renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, width, height); + data->texture = static_cast(malloc(sizeof(SDL_Texture*) * _sgsdl2_num_open_windows)); + + for (unsigned int i = 0; i < _sgsdl2_num_open_windows; i++) + { + data->texture[i] = SDL_CreateTexture(_sgsdl2_open_windows[i]->renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, width, height); - SDL_SetTextureBlendMode(data->texture[i], SDL_BLENDMODE_BLEND); + SDL_SetTextureBlendMode(data->texture[i], SDL_BLENDMODE_BLEND); - _sgsdl2_set_renderer_target(i, data); - SDL_SetRenderDrawColor(_sgsdl2_open_windows[i]->renderer, 255, 255, 255, 0); - SDL_RenderClear(_sgsdl2_open_windows[i]->renderer); - _sgsdl2_restore_default_render_target(i, data); + _sgsdl2_set_renderer_target(i, data); + SDL_SetRenderDrawColor(_sgsdl2_open_windows[i]->renderer, 0xff, 0xff, 0xff, 0); + SDL_RenderClear(_sgsdl2_open_windows[i]->renderer); + _sgsdl2_restore_default_render_target(i, data); + } + } + else + { + data->texture = nullptr; } _sgsdl2_add_bitmap(data); @@ -1863,40 +1901,23 @@ sg_drawing_surface sgsdl2_load_bitmap(const char * filename) internal_sgsdl2_init(); sg_drawing_surface result = { SGDS_Unknown, 0, 0, NULL }; - SDL_Surface *surface; - surface = IMG_Load(filename); + SDL_Surface *surface = IMG_Load(filename); if ( ! surface ) { std::cout << "error loading image " << IMG_GetError() << std::endl; return result; } - sg_bitmap_be *data = static_cast(malloc(sizeof(sg_bitmap_be))); - result._data = data; + result = sgsdl2_create_bitmap(surface->w, surface->h); - // Allocate space for one texture per window - if (_sgsdl2_num_open_windows > 0) - data->texture = static_cast(malloc(sizeof(SDL_Texture*) * _sgsdl2_num_open_windows)); - else - data->texture = NULL; + sg_bitmap_be *bitmap = static_cast(result._data); - for (unsigned int i = 0; i < _sgsdl2_num_open_windows; i++) - { - // Create a texture for each window - data->texture[i] = SDL_CreateTextureFromSurface(_sgsdl2_open_windows[i]->renderer, surface); - } - - data->surface = surface; - data->drawable = false; - data->clipped = false; - data->clip = {0,0,0,0}; + SDL_BlitSurface(surface, NULL, bitmap->surface, NULL); - result.kind = SGDS_Bitmap; - result.width = surface->w; - result.height = surface->h; + bitmap->last_draw_loc = SG_BITMAP_SURFACE; - _sgsdl2_add_bitmap(data); + SDL_FreeSurface(surface); return result; } @@ -1957,6 +1978,14 @@ void sgsdl2_draw_bitmap( sg_drawing_surface * src, sg_drawing_surface * dst, flo unsigned int count = _sgsdl2_renderer_count(dst); + //TODO: All we're doing here is making sure they're both in GPU memory. A better way to handle + // things would be to check if src & dst are both bitmaps and if their last draw op was + // done to their surfaces (rather than textures). If that's the case, we can simply blit + // their surfaces together. + _sgsdl2_surface_to_texture(src); + _sgsdl2_surface_to_texture(dst); + static_cast(dst->_data)->last_draw_loc = SG_BITMAP_TEXTURE; + for (unsigned int i = 0; i < count; i++) { SDL_Renderer *renderer = _sgsdl2_prepared_renderer(dst, i); diff --git a/Backend/SGSDL2/src/SGSDL2Graphics.h b/Backend/SGSDL2/src/SGSDL2Graphics.h index 3d105799..e9821383 100644 --- a/Backend/SGSDL2/src/SGSDL2Graphics.h +++ b/Backend/SGSDL2/src/SGSDL2Graphics.h @@ -27,6 +27,13 @@ unsigned int _sgsdl2_renderer_count(sg_drawing_surface *surface); SDL_Renderer * _sgsdl2_prepared_renderer(sg_drawing_surface* surface, unsigned int idx); void _sgsdl2_complete_render(sg_drawing_surface* surface, unsigned int idx); +typedef enum sg_bitmap_draw_loc +{ + SG_BITMAP_TEXTURE, + SG_BITMAP_SURFACE, + SG_BITMAP_NONE +} sg_bitmap_draw_loc; + typedef struct sg_window_be { SDL_Window * window; @@ -35,7 +42,7 @@ typedef struct sg_window_be bool clipped; SDL_Rect clip; unsigned int idx; - + // Event data store sg_window_data event_data; sg_drawing_surface *surface; @@ -44,12 +51,11 @@ typedef struct sg_window_be typedef struct sg_bitmap_be { // 1 texture per open window - SDL_Texture ** texture; - SDL_Surface * surface; - bool clipped; - SDL_Rect clip; - - bool drawable; // can be drawn on + SDL_Texture ** texture; + SDL_Surface * surface; + sg_bitmap_draw_loc last_draw_loc; + bool clipped; + SDL_Rect clip; } sg_bitmap_be; diff --git a/Backend/Test/src/main.cpp b/Backend/Test/src/main.cpp index 59842305..34fff043 100644 --- a/Backend/Test/src/main.cpp +++ b/Backend/Test/src/main.cpp @@ -29,60 +29,64 @@ sg_interface * _sg_functions = NULL; sg_drawing_surface img, img2; sg_drawing_surface bmp; -enum test_options -{ +enum test_options +{ BASIC_DRAWING = 1, - WINDOW_OPERATIONS = 2, - BITMAP_DRAWING = 4, + WINDOW_OPERATIONS = 2, + BITMAP_DRAWING = 4, AUDIO = 8, INPUT = 16, TEXT = 32, NETWORK = 64 -}; +}; -enum test_drawing_options +enum test_drawing_options { TEST_COLORS = 1, - TEST_READ_PIXELS = 2, - TEST_POSITIONS = 4, - TEST_ALPHA = 8, - TEST_CLIP = 16, - TEST_PIXELS = 32, - TEST_SHAPES = 64, - TEST_RESIZE = 128, + TEST_READ_PIXELS = 2, + TEST_POSITIONS = 4, + TEST_ALPHA = 8, + TEST_CLIP = 16, + TEST_PIXELS = 32, + TEST_SHAPES = 64, + TEST_RESIZE = 128, TEST_LINES = 256, - TEST_BITMAPS = 512, + TEST_BITMAPS = 512, TEST_INPUT = 1024, - TEST_FULLSCREEN = 2048 + TEST_FULLSCREEN = 2048, + TEST_DIRECT_PIXSPEED = 4096, + TEST_BITMAP_PIXSPEED = 8192 }; -void print_options() +void print_options() { - cout << "0: all " << endl; - cout << "1: basic drawing functions" << endl; - cout << "2: window operations" << endl; - cout << "4: bitmap drawing" << endl; - cout << "8: audio " << endl; - cout << "16: input " << endl; + cout << "0: all " << endl; + cout << "1: basic drawing functions" << endl; + cout << "2: window operations" << endl; + cout << "4: bitmap drawing" << endl; + cout << "8: audio " << endl; + cout << "16: input " << endl; cout << "32: text " << endl; cout << "64: network " << endl; } -void print_drawing_options() +void print_drawing_options() { - cout << "0: all " << endl; - cout << "1: colors" << endl; - cout << "2: read pixels" << endl; - cout << "4: test positions" << endl; - cout << "8: test alpha" << endl; - cout << "16: test clip" << endl; - cout << "32 test pixels" << endl; - cout << "64: test shapes" << endl; - cout << "128: test resize " << endl; - cout << "256: test lines " << endl; - cout << "512: test bitmaps " << endl; - cout << "1024: test input " << endl; - cout << "2048: test fullscreen " << endl; + cout << "0: all " << endl; + cout << "1: colors" << endl; + cout << "2: read pixels" << endl; + cout << "4: test positions" << endl; + cout << "8: test alpha" << endl; + cout << "16: test clip" << endl; + cout << "32 test pixels" << endl; + cout << "64: test shapes" << endl; + cout << "128: test resize " << endl; + cout << "256: test lines " << endl; + cout << "512: test bitmaps " << endl; + cout << "1024: test input " << endl; + cout << "2048: test fullscreen " << endl; + cout << "4096: test direct pixel drawing speed " << endl; + cout << "8192: test bitmap pixel drawing speed " << endl; } @@ -91,21 +95,21 @@ void print_drawing_options() // and initialised? // bool test_core_functions() -{ +{ cout << "Testing Core Functions!" << endl; - + cout << "Calling load_sg..." << endl; _sg_functions = sg_load(get_input_callbacks()); - + if ( !_sg_functions ) { cout << "Failed to load functions!" << endl; return false; } - + cout << "Calling init..." << endl; _sg_functions->init(); - + return false == _sg_functions->has_error; } @@ -122,10 +126,10 @@ void refresh_or_draw(sg_drawing_surface *surf) // if we are refreshing a window... do normal processing if (surf->kind == SGDS_Window) { - _sg_functions->input.process_events(); + _sg_functions->input.process_events(); if (_sg_functions->input.window_close_requested(surf)) - { - exit(0); + { + exit(0); } _sg_functions->graphics.refresh_window(surf); @@ -146,7 +150,7 @@ void refresh_or_draw(sg_drawing_surface *surf) void test_colors(sg_drawing_surface *window_arr, int sz) { cout << "Testing Colors" << endl; - + for (int w = 0; w < sz; w++) { cout << " - Clearning the surface to..." << endl; @@ -154,22 +158,22 @@ void test_colors(sg_drawing_surface *window_arr, int sz) _sg_functions->graphics.clear_drawing_surface(&window_arr[w], {1.0, 0.0, 0.0, 1.0}); refresh_or_draw(&window_arr[w]); _sg_functions->utils.delay(200); - + cout << " - WHITE" << endl; _sg_functions->graphics.clear_drawing_surface(&window_arr[w], {1.0, 1.0, 1.0, 1.0}); refresh_or_draw(&window_arr[w]); _sg_functions->utils.delay(500); - + cout << " - GREEN" << endl; _sg_functions->graphics.clear_drawing_surface(&window_arr[w], {0.0, 1.0, 0.0, 1.0}); refresh_or_draw(&window_arr[w]); _sg_functions->utils.delay(200); - + cout << " - BLUE" << endl; _sg_functions->graphics.clear_drawing_surface(&window_arr[w], {0.0, 0.0, 1.0, 1.0}); refresh_or_draw(&window_arr[w]); _sg_functions->utils.delay(200); - + cout << " - WHITE" << endl; _sg_functions->graphics.clear_drawing_surface(&window_arr[w], {1.0, 1.0, 1.0, 1.0}); refresh_or_draw(&window_arr[w]); @@ -180,22 +184,22 @@ void test_colors(sg_drawing_surface *window_arr, int sz) void test_read_pixels(sg_drawing_surface *window) { cout << "Testing Reading of Pixel data" << endl; - - + + _sg_functions->graphics.clear_drawing_surface(window, {1.0, 0.0, 0.0, 1.0}); sg_color clr = _sg_functions->graphics.read_pixel(window, 10, 10); - + cout << " - Color at 10,10 is RGBA " << clr.r << "," << clr.g << "," << clr.b << "," << clr.a << endl; cout << " - Match 1,0,0,1" << endl; - + clr = _sg_functions->graphics.read_pixel(window, -10, -10); cout << " - Color at -10,-10 is RGBA " << clr.r << "," << clr.g << "," << clr.b << "," << clr.a << endl; cout << " Match 0,0,0,0" << endl; - + _sg_functions->graphics.clear_drawing_surface(window, {1.0, 1.0, 1.0, 1.0}); refresh_or_draw(window); clr = _sg_functions->graphics.read_pixel(window, 10, 10); - + cout << " - Color at 10,10 is RGBA " << clr.r << "," << clr.g << "," << clr.b << "," << clr.a << endl; cout << " - Match 1,1,1,1" << endl; } @@ -216,7 +220,7 @@ void test_rects(sg_drawing_surface *window_arr, int sz) { _sg_functions->graphics.clear_drawing_surface(&window_arr[w], {1.0, 1.0, 1.0, 1.0}); } - + for (int i = 0; i < SHAPE_COUNT; i++) { float data[] = { rand() / (float)RAND_MAX * 800, @@ -224,7 +228,7 @@ void test_rects(sg_drawing_surface *window_arr, int sz) rand() / (float)RAND_MAX * 100, rand() / (float)RAND_MAX * 100 }; - + for (int w = 0; w < sz; w++) { _sg_functions->graphics.draw_aabb_rect(&window_arr[w], random_color(), data, 4 ); @@ -236,7 +240,7 @@ void test_rects(sg_drawing_surface *window_arr, int sz) { _sg_functions->graphics.clear_drawing_surface(&window_arr[w], {1.0, 1.0, 1.0, 1.0}); } - + for (int i = 0; i < SHAPE_COUNT; i++) { float data[] = { rand() / (float)RAND_MAX * 800, @@ -244,57 +248,57 @@ void test_rects(sg_drawing_surface *window_arr, int sz) rand() / (float)RAND_MAX * 100, rand() / (float)RAND_MAX * 100 }; - + for (int w = 0; w < sz; w++) { _sg_functions->graphics.fill_aabb_rect(&window_arr[w], random_color(), data, 4 ); refresh_or_draw(&window_arr[w]); } } - + for (int w = 0; w < sz; w++) { _sg_functions->graphics.clear_drawing_surface(&window_arr[w], {1.0, 1.0, 1.0, 1.0}); } - + for (int i = 0; i < SHAPE_COUNT; i++) { float x, y; - + x = rand() / (float)RAND_MAX * 800; y = rand() / (float)RAND_MAX * 600; - + float data[] = { x, y, x + 100, y, x, y + 100, x + 100, y + 100 }; - + for (int w = 0; w < sz; w++) { _sg_functions->graphics.draw_rect(&window_arr[w], random_color(), data, 8 ); refresh_or_draw(&window_arr[w]); } } - + for (int w = 0; w < sz; w++) { _sg_functions->graphics.clear_drawing_surface(&window_arr[w], {1.0, 1.0, 1.0, 1.0}); } - + for (int i = 0; i < SHAPE_COUNT; i++) { float x = rand() / (float)RAND_MAX * 800; float y = rand() / (float)RAND_MAX * 600; - + float data[] = { x, y, x + 100, y, x, y + 100, x + 100, y + 100 }; - + for (int w = 0; w < sz; w++) { _sg_functions->graphics.fill_rect(&window_arr[w], random_color(), data, 8 ); @@ -314,7 +318,7 @@ void test_triangles(sg_drawing_surface *window_arr, int sz) refresh_or_draw(&window_arr[w]); } - + for (int i = 0; i < SHAPE_COUNT; i++) { float data[] = { rand() / (float)RAND_MAX * 800, @@ -324,19 +328,19 @@ void test_triangles(sg_drawing_surface *window_arr, int sz) rand() / (float)RAND_MAX * 800, rand() / (float)RAND_MAX * 600 }; - + for (int w = 0; w < sz; w++) { _sg_functions->graphics.draw_triangle(&window_arr[w], random_color(), data, 6 ); refresh_or_draw(&window_arr[w]); } } - + for (int w = 0; w < sz; w++) { _sg_functions->graphics.clear_drawing_surface(&window_arr[w], {1.0, 1.0, 1.0, 1.0}); } - + for (int i = 0; i < SHAPE_COUNT; i++) { float data[] = { rand() / (float)RAND_MAX * 800, @@ -346,7 +350,7 @@ void test_triangles(sg_drawing_surface *window_arr, int sz) rand() / (float)RAND_MAX * 800, rand() / (float)RAND_MAX * 600 }; - + for (int w = 0; w < sz; w++) { _sg_functions->graphics.fill_triangle(&window_arr[w], random_color(), data, 6 ); @@ -365,7 +369,7 @@ void test_pixels(sg_drawing_surface *window_arr, int sz) refresh_or_draw(&window_arr[w]); _sg_functions->input.process_events(); } - + _sg_functions->input.process_events(); for (int i = 0; i < SHAPE_COUNT; i++) { @@ -380,21 +384,21 @@ void test_pixels(sg_drawing_surface *window_arr, int sz) _sg_functions->graphics.draw_pixel(&window_arr[w], clr, data, 2 ); } - + _sg_functions->input.process_events(); refresh_or_draw(&window_arr[w]); } } - + _sg_functions->input.process_events(); for (int w = 0; w < sz; w++) { sg_drawing_surface *wnd = &window_arr[w]; int sz = window_arr[w].width * window_arr[w].height; int pixels[sz]; - + _sg_functions->graphics.to_pixels(wnd, pixels, sz); - + int count = 0; for (int x = 0; x < window_arr[w].width; x++) { @@ -405,11 +409,97 @@ void test_pixels(sg_drawing_surface *window_arr, int sz) _sg_functions->input.process_events(); } cout << "Window " << w << " has " << count << " white pixels" << endl; - + _sg_functions->graphics.clear_drawing_surface(&window_arr[w], {1.0, 1.0, 1.0, 1.0}); refresh_or_draw(&window_arr[w]); + _sg_functions->input.process_events(); + } +} + + +void test_direct_pixel_speed(sg_drawing_surface *window_arr, int sz) +{ + cout << "Testing Direct pixel drawing speed" << endl; + _sg_functions->input.process_events(); + for (int cnt = 0; cnt < 5; cnt++) + { + for (int w = 0; w < sz; w++) + { + float data[] = {0,0}; + int start_time = _sg_functions->utils.get_ticks(); + for (int y = 0; y < (120 * cnt); y++) + { + for (int x = 0; x < 800; x++) + { + data[0] = x; + data[1] = y; + _sg_functions->graphics.draw_pixel(&window_arr[w], {1.0,0,0,1.0}, data, 2 ); + } + } + + int end_time = _sg_functions->utils.get_ticks(); + + _sg_functions->input.process_events(); + refresh_or_draw(&window_arr[w]); + + cout << " Direct pixel drawing time for window " << w + << " with area of 800x" << cnt * 120 << " was " << end_time - start_time << "ms" << endl; + } + } + cout << endl; +} + +void test_bitmap_pixel_speed(sg_drawing_surface *window_arr, int sz) +{ + cout << "Testing bitmap pixel drawing speed" << endl; _sg_functions->input.process_events(); + for (int w = 0; w < sz; w++) + { + _sg_functions->graphics.clear_drawing_surface(&window_arr[w], {1.0, 1.0, 1.0, 1.0}); + refresh_or_draw(&window_arr[w]); + _sg_functions->input.process_events(); } + + _sg_functions->input.process_events(); + sg_drawing_surface bitmap = _sg_functions->image.create_bitmap(800, 600); + for (int cnt = 0; cnt < 5; cnt++) + { + for (int w = 0; w < sz; w++) + { + float data[2]; + int start_time = _sg_functions->utils.get_ticks(); + + _sg_functions->graphics.clear_drawing_surface( &bitmap, {1,1,1,1} ); + + for (int y = 0; y < (120 * cnt); y++) + { + for (int x = 0; x < 800; x++) + { + data[0] = x; + data[1] = y; + _sg_functions->graphics.draw_pixel(&bitmap, {0,0,1,1}, data, 2 ); + } + } + + int mid_time = _sg_functions->utils.get_ticks(); + + float srcDat[] = { 0, 0, 0, 0, 0, 1, 1 }; + float dstDat[] = { 0, 0, 0, 0 }; + + _sg_functions->image.draw_bitmap(&bitmap, &window_arr[w],srcDat,7,dstDat,4,SG_FLIP_NONE); + + int end_time = _sg_functions->utils.get_ticks(); + + _sg_functions->input.process_events(); + refresh_or_draw(&window_arr[w]); + + cout << " Pixel drawing time to bitmap was " << mid_time - start_time << "ms" << endl; + cout << " Drawing time from bitmap to window " << w << " was " + << end_time - mid_time << "ms" << endl; + } + } + _sg_functions->graphics.close_drawing_surface(&bitmap); + cout << endl; } @@ -419,33 +509,33 @@ void test_circles(sg_drawing_surface *window_arr, int sz) { _sg_functions->graphics.clear_drawing_surface(&window_arr[w], {1.0, 1.0, 1.0, 1.0}); } - + for (int i = 0; i < SHAPE_COUNT; i++) { float data[] = { rand() / (float)RAND_MAX * 800, rand() / (float)RAND_MAX * 600, rand() / (float)RAND_MAX * 100 }; - + for (int w = 0; w < sz; w++) { _sg_functions->graphics.draw_circle(&window_arr[w], random_color(), data, 3 ); refresh_or_draw(&window_arr[w]); } } - + for (int w = 0; w < sz; w++) { _sg_functions->graphics.clear_drawing_surface(&window_arr[w], {1.0, 1.0, 1.0, 1.0}); } - + for (int i = 0; i < SHAPE_COUNT; i++) { float data[] = { rand() / (float)RAND_MAX * 800, rand() / (float)RAND_MAX * 600, rand() / (float)RAND_MAX * 100 }; - + for (int w = 0; w < sz; w++) { _sg_functions->graphics.fill_circle(&window_arr[w], random_color(), data, 3 ); @@ -460,7 +550,7 @@ void test_ellipses(sg_drawing_surface *window_arr, int sz) { _sg_functions->graphics.clear_drawing_surface(&window_arr[w], {1.0, 1.0, 1.0, 1.0}); } - + for (int i = 0; i < SHAPE_COUNT; i++) { float data[] = { rand() / (float)RAND_MAX * 800, @@ -468,19 +558,19 @@ void test_ellipses(sg_drawing_surface *window_arr, int sz) rand() / (float)RAND_MAX * 100, rand() / (float)RAND_MAX * 100 }; - + for (int w = 0; w < sz; w++) { _sg_functions->graphics.draw_ellipse(&window_arr[w], random_color(), data, 4 ); refresh_or_draw(&window_arr[w]); } } - + for (int w = 0; w < sz; w++) { _sg_functions->graphics.clear_drawing_surface(&window_arr[w], {1.0, 1.0, 1.0, 1.0}); } - + for (int i = 0; i < SHAPE_COUNT; i++) { float data[] = { rand() / (float)RAND_MAX * 800, @@ -488,7 +578,7 @@ void test_ellipses(sg_drawing_surface *window_arr, int sz) rand() / (float)RAND_MAX * 100, rand() / (float)RAND_MAX * 100 }; - + for (int w = 0; w < sz; w++) { _sg_functions->graphics.fill_ellipse(&window_arr[w], random_color(), data, 4 ); @@ -503,7 +593,7 @@ void test_lines(sg_drawing_surface *window_arr, int sz) { _sg_functions->graphics.clear_drawing_surface(&window_arr[w], {1.0, 1.0, 1.0, 1.0}); } - + for (int i = 0; i < SHAPE_COUNT; i++) { float data[] = { rand() / (float)RAND_MAX * 800, @@ -512,7 +602,7 @@ void test_lines(sg_drawing_surface *window_arr, int sz) rand() / (float)RAND_MAX * 600, 1 + rand() / (float)RAND_MAX * 30 }; - + for (int w = 0; w < sz; w++) { _sg_functions->graphics.draw_line(&window_arr[w], random_color(), data, 5 ); @@ -524,34 +614,34 @@ void test_lines(sg_drawing_surface *window_arr, int sz) void test_clip(sg_drawing_surface *window_arr, int sz) { cout << "Testing Clipping" << endl; - + for (int w = 0; w < sz; w++) { _sg_functions->graphics.clear_drawing_surface(&window_arr[w], {0.0, 0.0, 1.0, 1.0}); - + float data[] = { 0.0f, 0.0f, window_arr[w].width * 0.9f, window_arr[w].height * 0.9f }; - + for (int c = 0; c < 8; c++) { data[2] = window_arr[w].width * (0.9 - c * 0.1); data[3] = window_arr[w].height * (0.9 - c * 0.1); - + _sg_functions->graphics.set_clip_rect(&window_arr[w], data, 4); _sg_functions->graphics.clear_drawing_surface(&window_arr[w], {1.0f - c * 0.1f, 0.0, 0.0, 1.0}); } refresh_or_draw(&window_arr[w]); - + data[2] = window_arr[w].width * 0.4; data[3] = window_arr[w].height * 0.4; _sg_functions->graphics.set_clip_rect(&window_arr[w], data, 4); _sg_functions->graphics.clear_drawing_surface(&window_arr[w], {0.0, 1.0f, 0.0, 1.0f}); } - + _sg_functions->utils.delay(3000); - + for (int w = 0; w < sz; w++) { _sg_functions->graphics.clear_clip_rect(&window_arr[w]); @@ -564,22 +654,22 @@ bool test_positions(sg_drawing_surface *window_arr, int sz) for (int i = 0; i < sz; i++) { _sg_functions->graphics.clear_drawing_surface(&window_arr[i], {1.0, 1.0, 1.0, 1.0}); - + float data[] = {0.0f, 0.0f, 50.0f, 50.0f}; float data1[] = {window_arr[i].width - 50.0f, 0.0f, 50.0f, 50.0f}; float data2[] = {0.0f, window_arr[i].height - 50.0f, 50.0f, 50.0f}; float data3[] = {window_arr[i].width - 50.0f, window_arr[i].height - 50.0f, 50.0f, 50.0f}; - + _sg_functions->graphics.fill_aabb_rect(&window_arr[i], {1.0f, 0.0f, 0.0f, 1.0f}, data, 4); _sg_functions->graphics.fill_aabb_rect(&window_arr[i], {0.0f, 1.0f, 0.0f, 1.0f}, data1, 4); _sg_functions->graphics.fill_aabb_rect(&window_arr[i], {0.0f, 0.0f, 1.0f, 1.0f}, data2, 4); _sg_functions->graphics.fill_aabb_rect(&window_arr[i], {0.0f, 0.0f, 0.0f, 1.0f}, data3, 4); - + refresh_or_draw(&window_arr[i]); } _sg_functions->utils.delay(2000); - + return true; } @@ -588,7 +678,7 @@ bool test_alpha(sg_drawing_surface *window_arr, int sz) for (int i = 0; i < sz; i++) { _sg_functions->graphics.clear_drawing_surface(&window_arr[i], {1.0, 1.0, 1.0, 1.0}); - + float data[] = {0.0f, 0.0f, window_arr[i].width / 11.0f, window_arr[i].height * 1.0f}; for (int j = 0; j < 11; j++) @@ -596,12 +686,12 @@ bool test_alpha(sg_drawing_surface *window_arr, int sz) data[0] = j * data[2]; _sg_functions->graphics.fill_ellipse(&window_arr[i], {1.0f, 0.0f, 0.0f, 0.1f * j}, data, 4); } - + refresh_or_draw(&window_arr[i]); } - + _sg_functions->utils.delay(2000); - + return true; } @@ -613,12 +703,12 @@ void test_resize(sg_drawing_surface * window_arr, int sz) int w, h; w = window_arr[i].width; h = window_arr[i].height; - + _sg_functions->graphics.resize(&window_arr[i], 320, 240); _sg_functions->graphics.clear_drawing_surface(&window_arr[i], random_color()); _sg_functions->graphics.refresh_window(&window_arr[i]); _sg_functions->utils.delay(1000); - + _sg_functions->graphics.resize(&window_arr[i], 640, 480); _sg_functions->graphics.clear_drawing_surface(&window_arr[i], random_color()); _sg_functions->graphics.refresh_window(&window_arr[i]); @@ -628,14 +718,14 @@ void test_resize(sg_drawing_surface * window_arr, int sz) _sg_functions->graphics.clear_drawing_surface(&window_arr[i], random_color()); _sg_functions->graphics.refresh_window(&window_arr[i]); _sg_functions->utils.delay(1000); - + _sg_functions->graphics.resize(&window_arr[i], 1024, 768); _sg_functions->graphics.clear_drawing_surface(&window_arr[i], random_color()); _sg_functions->graphics.refresh_window(&window_arr[i]); _sg_functions->graphics.clear_drawing_surface(&window_arr[i], random_color()); _sg_functions->graphics.refresh_window(&window_arr[i]); _sg_functions->utils.delay(1000); - + _sg_functions->graphics.resize(&window_arr[i], w, h); _sg_functions->graphics.clear_drawing_surface(&window_arr[i], {1.0f, 1.0f, 1.0f, 1.0f}); _sg_functions->graphics.refresh_window(&window_arr[i]); @@ -649,7 +739,7 @@ void test_bitmaps(sg_drawing_surface * window_arr, int sz) float src_data[] = {0, 0, static_cast(img.width), static_cast(img.height)}; float bmp_src_data[] = {0, 0, static_cast(bmp.width), static_cast(bmp.height)}; float dst_data[] = {0, 0, 0, 0, 0, 1, 1}; - + //Draw at TOP LEFT (shows that the scaling of the draw coordinates works) for (int i = 0; i < sz; i++) { @@ -658,15 +748,15 @@ void test_bitmaps(sg_drawing_surface * window_arr, int sz) _sg_functions->image.draw_bitmap( &bmp, &window_arr[i], bmp_src_data, 4, dst_data, 7, SG_FLIP_NONE); _sg_functions->graphics.refresh_window(&window_arr[i]); _sg_functions->utils.delay(5000); - + _sg_functions->image.draw_bitmap( &img, &window_arr[i], src_data, 4, dst_data, 7, SG_FLIP_NONE); _sg_functions->graphics.refresh_window(&window_arr[i]); _sg_functions->utils.delay(1000); } - + dst_data[0] = 300.0f; dst_data[1] = 300.0f; - + //Test rotation (should rotate around centre) for (int u = 0; u <= 360; u += 4) { @@ -674,12 +764,12 @@ void test_bitmaps(sg_drawing_surface * window_arr, int sz) { //use sin _sg_functions->graphics.clear_drawing_surface(&window_arr[i], {1, 1, 1, 1}); - + dst_data[2] = static_cast(u); - + _sg_functions->image.draw_bitmap( &img, &window_arr[i], src_data, 4, dst_data, 7, SG_FLIP_NONE); _sg_functions->image.draw_bitmap( &img2, &window_arr[i], src_data, 4, dst_data, 7, SG_FLIP_NONE); - _sg_functions->graphics.refresh_window(&window_arr[i]); + _sg_functions->graphics.refresh_window(&window_arr[i]); } } _sg_functions->utils.delay(200); @@ -687,9 +777,9 @@ void test_bitmaps(sg_drawing_surface * window_arr, int sz) dst_data[0] = 150.0f; dst_data[1] = 150.0f; dst_data[2] = 0; - + //Test scale - for (int u = 0; u <= 90; u++) + for (int u = 0; u <= 90; u++) { for (int i = 0; i < sz; i++) { @@ -704,9 +794,9 @@ void test_bitmaps(sg_drawing_surface * window_arr, int sz) _sg_functions->graphics.refresh_window(&window_arr[i]); } } - + //Test rotate and scale (should rotate around centre) - for (int u = 0; u <= 360; u += 2) + for (int u = 0; u <= 360; u += 2) { for (int i = 0; i < sz; i++) { @@ -730,7 +820,7 @@ void test_bitmaps(sg_drawing_surface * window_arr, int sz) dst_data[2] = static_cast(u * 2); dst_data[5] = static_cast(u / 360.0); dst_data[6] = static_cast((720 - u) / 360.0); - + //use sin _sg_functions->graphics.clear_drawing_surface(&window_arr[i], {1, 1, 1, 1}); _sg_functions->image.draw_bitmap( &img, &window_arr[i], src_data, 4, dst_data, 7, SG_FLIP_NONE); @@ -747,7 +837,7 @@ void test_bitmaps(sg_drawing_surface * window_arr, int sz) dst_data[2] = static_cast(u * 2); dst_data[5] = static_cast(u / 360.0); dst_data[6] = static_cast((720 - u) / 360.0); - + //use sin _sg_functions->graphics.clear_drawing_surface(&window_arr[i], {1, 1, 1, 1}); _sg_functions->image.draw_bitmap( &img, &window_arr[i], src_data, 4, dst_data, 7, SG_FLIP_NONE); @@ -755,11 +845,11 @@ void test_bitmaps(sg_drawing_surface * window_arr, int sz) _sg_functions->graphics.refresh_window(&window_arr[i]); } } - + dst_data[2] = 0; dst_data[5] = 1; dst_data[6] = 1; - + //Test flip for (int u = 0; u < 240; u++) { @@ -772,7 +862,7 @@ void test_bitmaps(sg_drawing_surface * window_arr, int sz) _sg_functions->graphics.refresh_window(&window_arr[i]); } } - + //Test pretty // double scale; for (int u = 0; u <= 720; u += 4) @@ -781,18 +871,18 @@ void test_bitmaps(sg_drawing_surface * window_arr, int sz) { // scale = sin(u/90.0) + 0.5; // scale = scale > 0.2 ? scale : 0.2; - + dst_data[2] = u; dst_data[3] = 100 + sin(u/60.0)*100; dst_data[4] = -u; - + //use sin _sg_functions->graphics.clear_drawing_surface(&window_arr[i], {1, 1, 1, 1}); _sg_functions->image.draw_bitmap( &img, &window_arr[i], src_data, 4, dst_data, 7, SG_FLIP_NONE); - _sg_functions->graphics.refresh_window(&window_arr[i]); + _sg_functions->graphics.refresh_window(&window_arr[i]); } } - + _sg_functions->utils.delay(300); _sg_functions->input.process_events(); } @@ -802,19 +892,19 @@ bool test_draw_bitmap_without_window() sg_drawing_surface window; cout << "Creating bitmap" << endl; - + bmp = _sg_functions->image.create_bitmap(100, 100); cout << "Drawing to bitmap" << endl; - + _sg_functions->graphics.clear_drawing_surface(&bmp, {1.0f, 0.0f, 0.0f, 1.0f}); float data_t[] = {0.0f, 99.0f, 99.0f, 99.0f, 50.0f, 1.0f}; _sg_functions->graphics.fill_triangle(&bmp, {1.0,1.0,1.0,1.0}, data_t, 6 ); - + float data[] = {0.0f, 20.0f, 80.0f, 20.0f}; _sg_functions->graphics.fill_aabb_rect(&bmp, {0.0f, 1.0f, 0.0f, 1.0f}, data, 4); - + data[1] = 40.0f; data[2] = 60.0f; _sg_functions->graphics.fill_aabb_rect(&bmp, {0.0f, 0.0f, 1.0f, 1.0f}, data, 4); @@ -828,7 +918,7 @@ bool test_draw_bitmap_without_window() _sg_functions->graphics.fill_aabb_rect(&bmp, {1.0f, 1.0f, 0.0f, 1.0f}, data, 4); cout << "Saving bitmap" << endl; - + #ifdef WINDOWS _sg_functions->graphics.save_png(&bmp, "c:\\Users\\acain\\Desktop\\test1.png"); #else @@ -836,35 +926,35 @@ bool test_draw_bitmap_without_window() #endif float src_data[] = {0, 0, static_cast(bmp.width), static_cast(bmp.height)}; float dst_data[] = {0, 0, 0, 0, 0, 1, 1}; - + window = _sg_functions->graphics.open_window("Test Bitmap Drawing", 600, 600); _sg_functions->graphics.clear_drawing_surface(&window, {0.0f, 0.0f, 0.0f, 1.0f}); _sg_functions->image.draw_bitmap( &bmp, &window, src_data, 4, dst_data, 7, SG_FLIP_NONE); _sg_functions->graphics.refresh_window(&window); - + _sg_functions->input.process_events(); _sg_functions->utils.delay(2000); - + #ifdef WINDOWS _sg_functions->graphics.save_png(&window, "c:\\Users\\acain\\Desktop\\test2.png"); #else _sg_functions->graphics.save_png(&window, "/Users/acain/Desktop/test2.png"); -#endif +#endif sg_color clr = _sg_functions->graphics.read_pixel(&bmp, 5, 5); cout << "Bmp Color is : " << clr.r << ":" << clr.g << ":" << clr.b << ":" << clr.a << endl; clr = _sg_functions->graphics.read_pixel(&window, 0, 0); cout << "Wnd Color is : " << clr.r << ":" << clr.g << ":" << clr.b << ":" << clr.a << endl; - + _sg_functions->graphics.close_drawing_surface(&window); - + #ifdef WINDOWS _sg_functions->graphics.save_png(&bmp, "c:\\Users\\acain\\Desktop\\test3.png"); -#else +#else _sg_functions->graphics.save_png(&bmp, "/Users/acain/Desktop/test3.png"); #endif - + window = _sg_functions->graphics.open_window("Draw in new window!", 600, 600); _sg_functions->input.process_events(); @@ -872,7 +962,7 @@ bool test_draw_bitmap_without_window() _sg_functions->image.draw_bitmap( &bmp, &window, src_data, 4, dst_data, 7, SG_FLIP_NONE); _sg_functions->graphics.refresh_window(&window); _sg_functions->utils.delay(2000); - + _sg_functions->graphics.close_drawing_surface(&window); return true; @@ -881,8 +971,13 @@ bool test_draw_bitmap_without_window() bool test_basic_drawing(int drawing_test_run) { cout << "Testing Basic Drawing!" << endl; - cout << drawing_test_run << endl; - + cout << drawing_test_run << endl; + + if (!drawing_test_run) + { + drawing_test_run = -1; + } + sg_drawing_surface window; window = _sg_functions->graphics.open_window("Test Basic Drawing", 800, 600); @@ -891,67 +986,67 @@ bool test_basic_drawing(int drawing_test_run) img2 = _sg_functions->image.create_bitmap(100, 50); _sg_functions->graphics.clear_drawing_surface(&img2, {1.0f, 0.0f, 0.0f, 1.0f}); - - if (drawing_test_run & TEST_COLORS) + + if (drawing_test_run & TEST_COLORS) { test_colors(&window, 1); } - if (drawing_test_run & TEST_PIXELS) + if (drawing_test_run & TEST_PIXELS) { test_read_pixels(&window); } - if (drawing_test_run & TEST_POSITIONS) + if (drawing_test_run & TEST_POSITIONS) { test_positions(&window, 1); } - if (drawing_test_run & TEST_ALPHA) + if (drawing_test_run & TEST_ALPHA) { test_alpha(&window, 1); } - if (drawing_test_run & TEST_CLIP) + if (drawing_test_run & TEST_CLIP) { test_clip( &window, 1); } - - if (drawing_test_run & TEST_PIXELS) + + if (drawing_test_run & TEST_PIXELS) { test_pixels( &window, 1); } - - if (drawing_test_run & TEST_FULLSCREEN) + + if (drawing_test_run & TEST_FULLSCREEN) { _sg_functions->graphics.show_fullscreen(&window, true); test_rects( &window, 1); - + _sg_functions->graphics.show_fullscreen(&window, false); } - - if (drawing_test_run & TEST_SHAPES) + + if (drawing_test_run & TEST_SHAPES) { test_triangles( &window, 1); } - if (drawing_test_run & TEST_SHAPES) + if (drawing_test_run & TEST_SHAPES) { test_circles( &window, 1); } - - if (drawing_test_run & TEST_RESIZE) + + if (drawing_test_run & TEST_RESIZE) { test_resize(&window, 1); } - - if (drawing_test_run & TEST_SHAPES) + + if (drawing_test_run & TEST_SHAPES) { test_ellipses( &window, 1); } - if (drawing_test_run & TEST_LINES) + if (drawing_test_run & TEST_LINES) { test_lines( &window, 1); } @@ -964,14 +1059,24 @@ bool test_basic_drawing(int drawing_test_run) _sg_functions->graphics.clear_drawing_surface(&window, {1.0f, 1.0f, 1.0f, 1.0f}); test_bitmaps( &window, 1); } - - if (drawing_test_run & TEST_INPUT) + + if (drawing_test_run & TEST_INPUT) { test_input(&window, 1); } + if (drawing_test_run & TEST_DIRECT_PIXSPEED) + { + test_direct_pixel_speed(&window, 1); + } + + if (drawing_test_run & TEST_BITMAP_PIXSPEED) + { + test_bitmap_pixel_speed(&window, 1); + } + _sg_functions->graphics.close_drawing_surface(&window); - + return false == _sg_functions->has_error; } @@ -979,22 +1084,22 @@ bool test_window_operations() { cout << "Testing Window Operations!" << endl; _sg_functions->input.process_events(); - + sg_drawing_surface w[2]; w[0] = _sg_functions->graphics.open_window("Window 1", 800, 600); w[1] = _sg_functions->graphics.open_window("Window 2", 300, 300); - + _sg_functions->input.move_window(&w[1], 0, 0); - + _sg_functions->graphics.show_border(&w[0], false); - + if ( w[0].width != 800 ) cout << " >> Error with w[0] width! " << w[0].width << endl; if ( w[1].width != 300 ) cout << " >> Error with w[1] width! " << w[1].width << endl; - + if ( w[0].height != 600 ) cout << " >> Error with w[0] height! " << w[0].height << endl; if ( w[1].height != 300 ) cout << " >> Error with w[1] height! " << w[1].height << endl; - + test_colors(w, 2); test_clip(w, 2); test_pixels(w, 2); @@ -1004,7 +1109,7 @@ bool test_window_operations() test_ellipses(w, 2); test_lines(w, 2); test_bitmaps(w, 2); - + test_input(w, 2); _sg_functions->graphics.close_drawing_surface(&w[0]); @@ -1016,51 +1121,51 @@ bool test_window_operations() bool test_bitmap_dest_drawing() { cout << "Testing Drawing to Bitmap!" << endl; - + sg_drawing_surface window; window = _sg_functions->graphics.open_window("Drawing to Bitmap", 800, 600); _bmp_wnd = &window; - + sg_drawing_surface bmp = _sg_functions->image.create_bitmap(640, 480); - + float src_data[] = {0, 0, static_cast(img.width), static_cast(img.height)}; float dst_data[] = {0, 0, 0, 0, 0, 1, 1}; - + _sg_functions->image.draw_bitmap( &img, &bmp, src_data, 4, dst_data, 7, SG_FLIP_NONE); - + refresh_or_draw(&bmp); _sg_functions->utils.delay(3000); - + test_colors(&bmp, 1); test_positions(&bmp, 1); test_alpha(&bmp, 1); - + test_clip( &bmp, 1); test_pixels( &bmp, 1); - + test_rects( &bmp, 1); - + test_triangles( &bmp, 1); test_circles( &bmp, 1); - + test_ellipses( &bmp, 1); test_lines( &bmp, 1); dst_data[0] = 50; dst_data[1] = 50; - + src_data[2] = img2.width; src_data[3] = img2.height; - - + + _sg_functions->image.draw_bitmap( &img, &bmp, src_data, 4, dst_data, 7, SG_FLIP_NONE); refresh_or_draw(&bmp); _sg_functions->utils.delay(3000); - + _sg_functions->graphics.close_drawing_surface(&bmp); _sg_functions->graphics.close_drawing_surface(&window); _bmp_wnd = NULL; - + return false == _sg_functions->has_error; } @@ -1069,11 +1174,11 @@ void test_bitmap_loading_saving() sg_drawing_surface lines = _sg_functions->image.load_bitmap("Lines.png"); int sz = lines.width * lines.height; int pixels[sz]; - + for (int i = 0; i < sz; i++) pixels[i] = 0; - + _sg_functions->graphics.to_pixels(&lines, pixels, sz); - + for (int i = 0; i < sz; i++) { cout << std::hex << pixels[i] << std::dec << " "; @@ -1082,12 +1187,12 @@ void test_bitmap_loading_saving() cout << endl; } } - + sg_color clr = _sg_functions->graphics.read_pixel(&lines, 0, 0); cout << "Lines color is : " << clr.r << ":" << clr.g << ":" << clr.b << ":" << clr.a << endl; - + _sg_functions->graphics.save_png(&lines, "/Users/acain/Desktop/test.png"); - + _sg_functions->graphics.close_drawing_surface(&lines); } @@ -1095,9 +1200,9 @@ void test_bitmap_loading_saving() void output_system_details() { sg_system_data *data = _sg_functions->read_system_data(); - + cout << "Display count: " << data->num_displays << endl; - + for (int i = 0; i < data->num_displays; i++) { cout << " -> Display[" << i << "] = " << data->displays[i].name << endl; @@ -1108,7 +1213,7 @@ void output_system_details() cout << " " << data->displays[i].modes[m].width << " x " << data->displays[i].modes[m].height << endl; } } - + cout << "Time is " << _sg_functions->utils.get_ticks() << endl; } @@ -1116,41 +1221,41 @@ void test_fullscreen() { cout << "Calling load_sg..." << endl; _sg_functions = sg_load(get_input_callbacks()); - + if ( !_sg_functions ) { cout << "Failed to load functions!" << endl; return; } - + cout << "Calling init..." << endl; _sg_functions->init(); sg_drawing_surface window; window = _sg_functions->graphics.open_window("Test Basic Drawing", 800, 600); - + _sg_functions->graphics.show_fullscreen(&window, false); - + _sg_functions->graphics.clear_drawing_surface(&window, {1.0f, 1.0f, 1.0f, 1.0f}); _sg_functions->graphics.refresh_window(&window); _sg_functions->input.process_events(); _sg_functions->utils.delay(2000); - + _sg_functions->graphics.show_fullscreen(&window, true); - + // test_rects( &window, 1); _sg_functions->graphics.clear_drawing_surface(&window, {1.0f, 1.0f, 1.0f, 1.0f}); _sg_functions->graphics.refresh_window(&window); _sg_functions->input.process_events(); _sg_functions->utils.delay(2000); - + _sg_functions->graphics.show_fullscreen(&window, false); - + _sg_functions->graphics.clear_drawing_surface(&window, {1.0f, 0.0f, 0.0f, 1.0f}); _sg_functions->graphics.refresh_window(&window); _sg_functions->input.process_events(); _sg_functions->utils.delay(2000); - + _sg_functions->graphics.close_drawing_surface(&window); } @@ -1168,57 +1273,57 @@ int main(int argc, const char * argv[]) test_bitmap_loading_saving(); - cout << " Which tests do you want to run? " << endl; - print_options(); + cout << " Which tests do you want to run? " << endl; + print_options(); - int test_run = 0; - int test_drawing_run = INT_MAX; + int test_run = 0; + int test_drawing_run = INT_MAX; scanf("%d", &test_run); - - if (test_run == 0) + + if (test_run == 0) { - test_run |= 255; + test_run |= 255; } - else if (test_run & BASIC_DRAWING) + else if (test_run & BASIC_DRAWING) { - cout << "Which drawing functions would you like to run? " << endl; - print_drawing_options(); - scanf("%d", &test_drawing_run); + cout << "Which drawing functions would you like to run? " << endl; + print_drawing_options(); + scanf("%d", &test_drawing_run); } output_system_details(); - + if (test_run & BASIC_DRAWING && ! test_draw_bitmap_without_window() ) { cout << "Drawing to bitmap without window failed..." << endl; return -1; } - + if (test_run & BASIC_DRAWING && ! test_basic_drawing(test_drawing_run) ) { cout << "Basic drawing failed with error: " << endl; //cout << _sg_functions->current_error << endl; return -1; } - + _sg_functions->input.process_events(); - - if (test_run & WINDOW_OPERATIONS) + + if (test_run & WINDOW_OPERATIONS) { test_window_operations(); } - - if (test_run & BITMAP_DRAWING) + + if (test_run & BITMAP_DRAWING) { test_bitmap_dest_drawing(); test_bitmap_loading_saving(); } - + _sg_functions->graphics.close_drawing_surface(&img); _sg_functions->graphics.close_drawing_surface(&img2); - - if (test_run & AUDIO) + + if (test_run & AUDIO) { test_audio(); } @@ -1230,19 +1335,19 @@ int main(int argc, const char * argv[]) test_input(w, 1); } - if (test_run & TEXT) + if (test_run & TEXT) { test_text(); } - + if (test_run & NETWORK) { test_network(); } - + _sg_functions->finalise(); cout << "Success" << endl; - + return 0; }