this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Changed GPU_UpdateImage() parameters so the rect comes last and the semantics are more explicit (it's a source rect now). Added GPU_UpdateSubImage(), which can take a portion of a surface to update a portion of an image. Added upload-image demo (having "update" in the name apparently causes Windows to flag the exe as needing admin privileges).

+315 -19
+82 -11
SDL_gpu/GL_common/SDL_gpu_GL_common.inl
··· 2354 2354 2355 2355 2356 2356 2357 - // From SDL_UpdateTexture() 2358 - static void UpdateImage(GPU_Renderer* renderer, GPU_Image* image, const GPU_Rect* rect, SDL_Surface* surface) 2357 + 2358 + static void UpdateImage(GPU_Renderer* renderer, GPU_Image* image, SDL_Surface* surface, const GPU_Rect* surface_rect) 2359 + { 2360 + renderer->UpdateSubImage(renderer, image, NULL, surface, surface_rect); 2361 + } 2362 + 2363 + 2364 + static void UpdateSubImage(GPU_Renderer* renderer, GPU_Image* image, const GPU_Rect* image_rect, SDL_Surface* surface, const GPU_Rect* surface_rect) 2359 2365 { 2360 2366 if(image == NULL || surface == NULL) 2361 2367 return; ··· 2366 2372 SDL_Surface* newSurface = copySurfaceIfNeeded(renderer, data->format, surface, &original_format); 2367 2373 if(newSurface == NULL) 2368 2374 { 2369 - GPU_PushErrorCode("GPU_UpdateImage", GPU_ERROR_BACKEND_ERROR, "Failed to convert surface to proper pixel format."); 2375 + GPU_PushErrorCode("GPU_UpdateSubImage", GPU_ERROR_BACKEND_ERROR, "Failed to convert surface to proper pixel format."); 2370 2376 return; 2371 2377 } 2372 2378 2373 2379 2374 2380 GPU_Rect updateRect; 2375 - if(rect != NULL) 2376 - updateRect = *rect; 2381 + if(image_rect != NULL) 2382 + { 2383 + updateRect = *image_rect; 2384 + if(updateRect.x < 0) 2385 + { 2386 + updateRect.w += updateRect.x; 2387 + updateRect.x = 0; 2388 + } 2389 + if(updateRect.y < 0) 2390 + { 2391 + updateRect.h += updateRect.y; 2392 + updateRect.y = 0; 2393 + } 2394 + if(updateRect.x + updateRect.w > image->w) 2395 + updateRect.w += image->w - (updateRect.x + updateRect.w); 2396 + if(updateRect.y + updateRect.h > image->h) 2397 + updateRect.h += image->h - (updateRect.y + updateRect.h); 2398 + 2399 + if(updateRect.w <= 0) 2400 + updateRect.w = 0; 2401 + if(updateRect.h <= 0) 2402 + updateRect.h = 0; 2403 + } 2377 2404 else 2378 2405 { 2379 2406 updateRect.x = 0; 2380 2407 updateRect.y = 0; 2381 - updateRect.w = newSurface->w; 2382 - updateRect.h = newSurface->h; 2408 + updateRect.w = image->w; 2409 + updateRect.h = image->h; 2383 2410 if(updateRect.w < 0.0f || updateRect.h < 0.0f) 2384 2411 { 2385 - GPU_PushErrorCode("GPU_UpdateImage", GPU_ERROR_USER_ERROR, "Given negative update rectangle."); 2412 + GPU_PushErrorCode("GPU_UpdateSubImage", GPU_ERROR_USER_ERROR, "Given negative image rectangle."); 2386 2413 return; 2387 2414 } 2388 2415 } 2416 + 2417 + GPU_Rect sourceRect; 2418 + if(surface_rect != NULL) 2419 + { 2420 + sourceRect = *surface_rect; 2421 + if(sourceRect.x < 0) 2422 + { 2423 + sourceRect.w += sourceRect.x; 2424 + sourceRect.x = 0; 2425 + } 2426 + if(sourceRect.y < 0) 2427 + { 2428 + sourceRect.h += sourceRect.y; 2429 + sourceRect.y = 0; 2430 + } 2431 + if(sourceRect.x + sourceRect.w > newSurface->w) 2432 + sourceRect.w += newSurface->w - (sourceRect.x + sourceRect.w); 2433 + if(sourceRect.y + sourceRect.h > newSurface->h) 2434 + sourceRect.h += newSurface->h - (sourceRect.y + sourceRect.h); 2435 + 2436 + if(sourceRect.w <= 0) 2437 + sourceRect.w = 0; 2438 + if(sourceRect.h <= 0) 2439 + sourceRect.h = 0; 2440 + } 2441 + else 2442 + { 2443 + sourceRect.x = 0; 2444 + sourceRect.y = 0; 2445 + sourceRect.w = newSurface->w; 2446 + sourceRect.h = newSurface->h; 2447 + } 2389 2448 2390 2449 2391 2450 changeTexturing(renderer, 1); ··· 2399 2458 #ifdef SDL_GPU_USE_OPENGL 2400 2459 glPixelStorei(GL_UNPACK_ROW_LENGTH, (newSurface->pitch / newSurface->format->BytesPerPixel)); 2401 2460 #endif 2402 - glTexSubImage2D(GL_TEXTURE_2D, 0, updateRect.x, updateRect.y, updateRect.w, 2403 - updateRect.h, original_format, GL_UNSIGNED_BYTE, 2404 - newSurface->pixels); 2461 + 2462 + // Use the smaller of the image and surface rect dimensions 2463 + if(sourceRect.w < updateRect.w) 2464 + updateRect.w = sourceRect.w; 2465 + if(sourceRect.h < updateRect.h) 2466 + updateRect.h = sourceRect.h; 2467 + 2468 + Uint8* pixels = (Uint8*)newSurface->pixels; 2469 + // Shift the pixels pointer to the proper source position 2470 + pixels += (int)(newSurface->pitch * sourceRect.y + (newSurface->format->BytesPerPixel)*sourceRect.x); 2471 + 2472 + glTexSubImage2D(GL_TEXTURE_2D, 0, 2473 + updateRect.x, updateRect.y, updateRect.w, updateRect.h, 2474 + original_format, GL_UNSIGNED_BYTE, pixels); 2405 2475 2406 2476 // Delete temporary surface 2407 2477 if(surface != newSurface) ··· 5205 5275 renderer->SaveImage = &SaveImage; \ 5206 5276 renderer->CopyImage = &CopyImage; \ 5207 5277 renderer->UpdateImage = &UpdateImage; \ 5278 + renderer->UpdateSubImage = &UpdateSubImage; \ 5208 5279 renderer->CopyImageFromSurface = &CopyImageFromSurface; \ 5209 5280 renderer->CopyImageFromTarget = &CopyImageFromTarget; \ 5210 5281 renderer->CopySurfaceFromTarget = &CopySurfaceFromTarget; \
+10 -2
SDL_gpu/SDL_gpu.c
··· 505 505 return current_renderer->CopyImage(current_renderer, image); 506 506 } 507 507 508 - void GPU_UpdateImage(GPU_Image* image, const GPU_Rect* rect, SDL_Surface* surface) 508 + void GPU_UpdateImage(GPU_Image* image, SDL_Surface* surface, const GPU_Rect* surface_rect) 509 509 { 510 510 if(current_renderer == NULL || current_renderer->current_context_target == NULL || current_renderer->UpdateImage == NULL) 511 511 return; 512 512 513 - current_renderer->UpdateImage(current_renderer, image, rect, surface); 513 + current_renderer->UpdateImage(current_renderer, image, surface, surface_rect); 514 + } 515 + 516 + void GPU_UpdateSubImage(GPU_Image* image, const GPU_Rect* image_rect, SDL_Surface* surface, const GPU_Rect* surface_rect) 517 + { 518 + if(current_renderer == NULL || current_renderer->current_context_target == NULL || current_renderer->UpdateSubImage == NULL) 519 + return; 520 + 521 + current_renderer->UpdateSubImage(current_renderer, image, image_rect, surface, surface_rect); 514 522 } 515 523 516 524 SDL_Surface* GPU_LoadSurface(const char* filename)
+8 -2
SDL_gpu/SDL_gpu.h
··· 501 501 GPU_Image* (*CopyImage)(GPU_Renderer* renderer, GPU_Image* image); 502 502 503 503 /*! \see GPU_UpdateImage */ 504 - void (*UpdateImage)(GPU_Renderer* renderer, GPU_Image* image, const GPU_Rect* rect, SDL_Surface* surface); 504 + void (*UpdateImage)(GPU_Renderer* renderer, GPU_Image* image, SDL_Surface* surface, const GPU_Rect* surface_rect); 505 + 506 + /*! \see GPU_UpdateSubImage */ 507 + void (*UpdateSubImage)(GPU_Renderer* renderer, GPU_Image* image, const GPU_Rect* image_rect, SDL_Surface* surface, const GPU_Rect* surface_rect); 505 508 506 509 /*! \see GPU_CopyImageFromSurface() */ 507 510 GPU_Image* (*CopyImageFromSurface)(GPU_Renderer* renderer, SDL_Surface* surface); ··· 1047 1050 void GPU_FreeImage(GPU_Image* image); 1048 1051 1049 1052 /*! Update an image from surface data. */ 1050 - void GPU_UpdateImage(GPU_Image* image, const GPU_Rect* rect, SDL_Surface* surface); 1053 + void GPU_UpdateImage(GPU_Image* image, SDL_Surface* surface, const GPU_Rect* surface_rect); 1054 + 1055 + /*! Update an image from surface data. */ 1056 + void GPU_UpdateSubImage(GPU_Image* image, const GPU_Rect* image_rect, SDL_Surface* surface, const GPU_Rect* surface_rect); 1051 1057 1052 1058 /*! Save image to a file. The file type is deduced from the extension. Supported formats are: png, bmp, tga. Returns 0 on failure. */ 1053 1059 Uint8 GPU_SaveImage(GPU_Image* image, const char* filename);
+4 -1
demos/CMakeLists.txt
··· 111 111 target_link_libraries (triangle-batch-demo SDL_gpu) 112 112 113 113 add_executable(wrap-demo wrap/main.c common/common.c common/demo-font.c) 114 - target_link_libraries (wrap-demo SDL_gpu) 114 + target_link_libraries (wrap-demo SDL_gpu) 115 + 116 + add_executable(upload-image-demo upload-image/main.c common/common.c common/demo-font.c) 117 + target_link_libraries (upload-image-demo SDL_gpu)
+3 -3
demos/color/main.c
··· 19 19 } 20 20 } 21 21 22 - GPU_UpdateImage(image, NULL, surface); 22 + GPU_UpdateImage(image, surface, NULL); 23 23 SDL_FreeSurface(surface); 24 24 } 25 25 ··· 43 43 } 44 44 } 45 45 46 - GPU_UpdateImage(image, NULL, surface); 46 + GPU_UpdateImage(image, surface, NULL); 47 47 SDL_FreeSurface(surface); 48 48 } 49 49 ··· 190 190 } 191 191 } 192 192 193 - GPU_UpdateImage(image, NULL, surface); 193 + GPU_UpdateImage(image, surface, NULL); 194 194 SDL_FreeSurface(surface); 195 195 } 196 196
+1
demos/common/compat.h
··· 23 23 24 24 #else 25 25 26 + #define SDL_Keymod SDLMod 26 27 #define KEY_UP SDLK_UP 27 28 #define KEY_DOWN SDLK_DOWN 28 29 #define KEY_LEFT SDLK_LEFT
+207
demos/upload-image/main.c
··· 1 + #include "SDL.h" 2 + #include "SDL_gpu.h" 3 + #include <math.h> 4 + #include "common.h" 5 + #include "compat.h" 6 + 7 + 8 + 9 + void set_pixel(SDL_Surface* surface, int x, int y, Uint32 color) 10 + { 11 + if(surface == NULL || x < 0 || y < 0 || x >= surface->w || y >= surface->h) 12 + return; 13 + 14 + int bpp = surface->format->BytesPerPixel; 15 + Uint8* bits = ((Uint8 *)surface->pixels) + y*surface->pitch + x*bpp; 16 + 17 + /* Set the pixel */ 18 + switch(bpp) 19 + { 20 + case 1: 21 + *((Uint8 *)(bits)) = (Uint8)color; 22 + break; 23 + case 2: 24 + *((Uint16 *)(bits)) = (Uint16)color; 25 + break; 26 + case 3: { /* Format/endian independent */ 27 + Uint8 r,g,b; 28 + r = (color >> surface->format->Rshift) & 0xFF; 29 + g = (color >> surface->format->Gshift) & 0xFF; 30 + b = (color >> surface->format->Bshift) & 0xFF; 31 + *((bits)+surface->format->Rshift/8) = r; 32 + *((bits)+surface->format->Gshift/8) = g; 33 + *((bits)+surface->format->Bshift/8) = b; 34 + } 35 + break; 36 + case 4: 37 + *((Uint32 *)(bits)) = (Uint32)color; 38 + break; 39 + } 40 + } 41 + 42 + 43 + int main(int argc, char* argv[]) 44 + { 45 + printRenderers(); 46 + 47 + GPU_Target* screen = GPU_Init(800, 600, GPU_DEFAULT_INIT_FLAGS); 48 + if(screen == NULL) 49 + return -1; 50 + 51 + printCurrentRenderer(); 52 + 53 + GPU_Image* image = GPU_CreateImage(400, 400, GPU_FORMAT_RGBA); 54 + if(image == NULL) 55 + return -1; 56 + 57 + Uint32 rmask, gmask, bmask, amask; 58 + 59 + #if SDL_BYTEORDER == SDL_BIG_ENDIAN 60 + rmask = 0xff000000; 61 + gmask = 0x00ff0000; 62 + bmask = 0x0000ff00; 63 + amask = 0x000000ff; 64 + #else 65 + rmask = 0x000000ff; 66 + gmask = 0x0000ff00; 67 + bmask = 0x00ff0000; 68 + amask = 0xff000000; 69 + #endif 70 + 71 + SDL_Surface* surface = SDL_CreateRGBSurface(SDL_SWSURFACE, 400, 400, 32, 72 + rmask, gmask, bmask, amask); 73 + if(surface == NULL) 74 + return -2; 75 + 76 + Uint32 red_pixel = SDL_MapRGBA(surface->format, 255, 0, 0, 255); 77 + Uint32 white_pixel = SDL_MapRGBA(surface->format, 255, 255, 255, 255); 78 + 79 + GPU_Rect image_rect = {0, 0, 400, 400}; 80 + GPU_Rect surface_rect = {0, 0, 400, 400}; 81 + 82 + SDL_Color border_color = {255, 255, 255, 255}; 83 + SDL_Color image_rect_color = {255, 255, 0, 255}; 84 + SDL_Color surface_rect_color = {0, 255, 0, 255}; 85 + 86 + Uint8* keystates = SDL_GetKeyState(NULL); 87 + 88 + Uint32 startTime = SDL_GetTicks(); 89 + long frameCount = 0; 90 + 91 + Uint8 done = 0; 92 + SDL_Event event; 93 + while(!done) 94 + { 95 + while(SDL_PollEvent(&event)) 96 + { 97 + if(event.type == SDL_QUIT) 98 + done = 1; 99 + else if(event.type == SDL_KEYDOWN) 100 + { 101 + if(event.key.keysym.sym == SDLK_ESCAPE) 102 + done = 1; 103 + if(event.key.keysym.sym == SDLK_SPACE) 104 + { 105 + SDL_FillRect(surface, NULL, red_pixel); 106 + } 107 + } 108 + } 109 + 110 + SDL_Keymod kmod = SDL_GetModState(); 111 + if(keystates[KEY_w]) 112 + { 113 + if(kmod & KMOD_SHIFT) 114 + image_rect.h -= 1; 115 + else 116 + image_rect.y -= 1; 117 + } 118 + if(keystates[KEY_s]) 119 + { 120 + if(kmod & KMOD_SHIFT) 121 + image_rect.h += 1; 122 + else 123 + image_rect.y += 1; 124 + } 125 + if(keystates[KEY_a]) 126 + { 127 + if(kmod & KMOD_SHIFT) 128 + image_rect.w -= 1; 129 + else 130 + image_rect.x -= 1; 131 + } 132 + if(keystates[KEY_d]) 133 + { 134 + if(kmod & KMOD_SHIFT) 135 + image_rect.w += 1; 136 + else 137 + image_rect.x += 1; 138 + } 139 + 140 + if(keystates[KEY_UP]) 141 + { 142 + if(kmod & KMOD_SHIFT) 143 + surface_rect.h -= 1; 144 + else 145 + surface_rect.y -= 1; 146 + } 147 + if(keystates[KEY_DOWN]) 148 + { 149 + if(kmod & KMOD_SHIFT) 150 + surface_rect.h += 1; 151 + else 152 + surface_rect.y += 1; 153 + } 154 + if(keystates[KEY_LEFT]) 155 + { 156 + if(kmod & KMOD_SHIFT) 157 + surface_rect.w -= 1; 158 + else 159 + surface_rect.x -= 1; 160 + } 161 + if(keystates[KEY_RIGHT]) 162 + { 163 + if(kmod & KMOD_SHIFT) 164 + surface_rect.w += 1; 165 + else 166 + surface_rect.x += 1; 167 + } 168 + 169 + int mx, my; 170 + Uint32 mouse_state = SDL_GetMouseState(&mx, &my); 171 + if(mouse_state & SDL_BUTTON_LMASK) 172 + { 173 + set_pixel(surface, mx + image->w/2 - screen->w/2, my + image->h/2 - screen->h/2, red_pixel); 174 + } 175 + if(mouse_state & SDL_BUTTON_RMASK) 176 + { 177 + set_pixel(surface, mx + image->w/2 - screen->w/2, my + image->h/2 - screen->h/2, white_pixel); 178 + } 179 + 180 + GPU_Clear(screen); 181 + 182 + GPU_UpdateSubImage(image, &image_rect, surface, &surface_rect); 183 + 184 + GPU_Blit(image, NULL, screen, screen->w/2, screen->h/2); 185 + GPU_Rectangle(screen, screen->w/2 - image->w/2, screen->h/2 - image->h/2, 186 + screen->w/2 + image->w/2, screen->h/2 + image->h/2, border_color); 187 + GPU_Rectangle(screen, image_rect.x + screen->w/2 - image->w/2, image_rect.y + screen->h/2 - image->h/2, 188 + image_rect.x + image_rect.w + screen->w/2 - image->w/2, image_rect.y + image_rect.h + screen->h/2 - image->h/2, image_rect_color); 189 + GPU_Rectangle(screen, surface_rect.x + screen->w/2 - image->w/2, surface_rect.y + screen->h/2 - image->h/2, 190 + surface_rect.x + surface_rect.w + screen->w/2 - image->w/2, surface_rect.y + surface_rect.h + screen->h/2 - image->h/2, surface_rect_color); 191 + 192 + GPU_Flip(screen); 193 + 194 + frameCount++; 195 + if(frameCount%500 == 0) 196 + printf("Average FPS: %.2f\n", 1000.0f*frameCount/(SDL_GetTicks() - startTime)); 197 + } 198 + 199 + printf("Average FPS: %.2f\n", 1000.0f*frameCount/(SDL_GetTicks() - startTime)); 200 + 201 + GPU_FreeImage(image); 202 + GPU_Quit(); 203 + 204 + return 0; 205 + } 206 + 207 +