Mercurial > sdl-ios-xcode
comparison src/video/win32/SDL_gdirender.c @ 3534:9d129e1d0782
Implemented RenderReadPixels() and RenderWritePixels() for GDI renderer.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Mon, 07 Dec 2009 09:44:55 +0000 |
parents | 83518f8fcd61 |
children | b403f790df65 |
comparison
equal
deleted
inserted
replaced
3533:40b9b0177e9a | 3534:9d129e1d0782 |
---|---|
65 static int GDI_RenderLine(SDL_Renderer * renderer, int x1, int y1, int x2, | 65 static int GDI_RenderLine(SDL_Renderer * renderer, int x1, int y1, int x2, |
66 int y2); | 66 int y2); |
67 static int GDI_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect); | 67 static int GDI_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect); |
68 static int GDI_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, | 68 static int GDI_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, |
69 const SDL_Rect * srcrect, const SDL_Rect * dstrect); | 69 const SDL_Rect * srcrect, const SDL_Rect * dstrect); |
70 static int GDI_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, | |
71 Uint32 format, void * pixels, int pitch); | |
72 static int GDI_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect, | |
73 Uint32 format, const void * pixels, int pitch); | |
70 static void GDI_RenderPresent(SDL_Renderer * renderer); | 74 static void GDI_RenderPresent(SDL_Renderer * renderer); |
71 static void GDI_DestroyTexture(SDL_Renderer * renderer, | 75 static void GDI_DestroyTexture(SDL_Renderer * renderer, |
72 SDL_Texture * texture); | 76 SDL_Texture * texture); |
73 static void GDI_DestroyRenderer(SDL_Renderer * renderer); | 77 static void GDI_DestroyRenderer(SDL_Renderer * renderer); |
74 | 78 |
190 renderer->SetDrawBlendMode = GDI_SetDrawBlendMode; | 194 renderer->SetDrawBlendMode = GDI_SetDrawBlendMode; |
191 renderer->RenderPoint = GDI_RenderPoint; | 195 renderer->RenderPoint = GDI_RenderPoint; |
192 renderer->RenderLine = GDI_RenderLine; | 196 renderer->RenderLine = GDI_RenderLine; |
193 renderer->RenderFill = GDI_RenderFill; | 197 renderer->RenderFill = GDI_RenderFill; |
194 renderer->RenderCopy = GDI_RenderCopy; | 198 renderer->RenderCopy = GDI_RenderCopy; |
199 renderer->RenderReadPixels = GDI_RenderReadPixels; | |
200 renderer->RenderWritePixels = GDI_RenderWritePixels; | |
195 renderer->RenderPresent = GDI_RenderPresent; | 201 renderer->RenderPresent = GDI_RenderPresent; |
196 renderer->DestroyTexture = GDI_DestroyTexture; | 202 renderer->DestroyTexture = GDI_DestroyTexture; |
197 renderer->DestroyRenderer = GDI_DestroyRenderer; | 203 renderer->DestroyRenderer = GDI_DestroyRenderer; |
198 renderer->info = GDI_RenderDriver.info; | 204 renderer->info = GDI_RenderDriver.info; |
199 renderer->window = window->id; | 205 renderer->window = window->id; |
295 data->current_hbm = 0; | 301 data->current_hbm = 0; |
296 | 302 |
297 return 0; | 303 return 0; |
298 } | 304 } |
299 | 305 |
300 static int | 306 static HBITMAP |
301 GDI_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) | 307 GDI_CreateDIBSection(HDC hdc, int w, int h, int pitch, Uint32 format, |
302 { | 308 HPALETTE * hpal, void ** pixels) |
303 GDI_RenderData *renderdata = (GDI_RenderData *) renderer->driverdata; | 309 { |
304 SDL_Window *window = SDL_GetWindowFromID(renderer->window); | 310 int bmi_size; |
305 SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window); | 311 LPBITMAPINFO bmi; |
306 GDI_TextureData *data; | 312 |
307 | 313 bmi_size = sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD); |
308 data = (GDI_TextureData *) SDL_calloc(1, sizeof(*data)); | 314 bmi = (LPBITMAPINFO) SDL_calloc(1, bmi_size); |
309 if (!data) { | 315 if (!bmi) { |
310 SDL_OutOfMemory(); | 316 SDL_OutOfMemory(); |
311 return -1; | 317 return NULL; |
312 } | 318 } |
313 | 319 bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); |
314 texture->driverdata = data; | 320 bmi->bmiHeader.biWidth = w; |
315 | 321 bmi->bmiHeader.biHeight = -h; /* topdown bitmap */ |
316 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { | 322 bmi->bmiHeader.biPlanes = 1; |
317 data->yuv = | 323 bmi->bmiHeader.biSizeImage = h * pitch; |
318 SDL_SW_CreateYUVTexture(texture->format, texture->w, texture->h); | 324 bmi->bmiHeader.biXPelsPerMeter = 0; |
319 if (!data->yuv) { | 325 bmi->bmiHeader.biYPelsPerMeter = 0; |
320 return -1; | 326 bmi->bmiHeader.biClrUsed = 0; |
321 } | 327 bmi->bmiHeader.biClrImportant = 0; |
322 data->format = display->current_mode.format; | 328 bmi->bmiHeader.biBitCount = SDL_BYTESPERPIXEL(format) * 8; |
323 } else { | 329 if (SDL_ISPIXELFORMAT_INDEXED(format)) { |
324 data->format = texture->format; | 330 bmi->bmiHeader.biCompression = BI_RGB; |
325 } | 331 if (hpal) { |
326 data->pitch = (texture->w * SDL_BYTESPERPIXEL(data->format)); | |
327 | |
328 if (data->yuv || texture->access == SDL_TEXTUREACCESS_STREAMING | |
329 || texture->format != display->current_mode.format) { | |
330 int bmi_size; | |
331 LPBITMAPINFO bmi; | |
332 | |
333 bmi_size = sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD); | |
334 bmi = (LPBITMAPINFO) SDL_calloc(1, bmi_size); | |
335 if (!bmi) { | |
336 SDL_OutOfMemory(); | |
337 return -1; | |
338 } | |
339 bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); | |
340 bmi->bmiHeader.biWidth = texture->w; | |
341 bmi->bmiHeader.biHeight = -texture->h; /* topdown bitmap */ | |
342 bmi->bmiHeader.biPlanes = 1; | |
343 bmi->bmiHeader.biSizeImage = texture->h * data->pitch; | |
344 bmi->bmiHeader.biXPelsPerMeter = 0; | |
345 bmi->bmiHeader.biYPelsPerMeter = 0; | |
346 bmi->bmiHeader.biClrUsed = 0; | |
347 bmi->bmiHeader.biClrImportant = 0; | |
348 bmi->bmiHeader.biBitCount = SDL_BYTESPERPIXEL(data->format) * 8; | |
349 if (SDL_ISPIXELFORMAT_INDEXED(data->format)) { | |
350 int i, ncolors; | 332 int i, ncolors; |
351 LOGPALETTE *palette; | 333 LOGPALETTE *palette; |
352 | 334 |
353 bmi->bmiHeader.biCompression = BI_RGB; | 335 ncolors = (1 << SDL_BITSPERPIXEL(format)); |
354 ncolors = (1 << SDL_BITSPERPIXEL(data->format)); | |
355 palette = | 336 palette = |
356 (LOGPALETTE *) SDL_malloc(sizeof(*palette) + | 337 (LOGPALETTE *) SDL_malloc(sizeof(*palette) + |
357 ncolors * sizeof(PALETTEENTRY)); | 338 ncolors * sizeof(PALETTEENTRY)); |
358 if (!palette) { | 339 if (!palette) { |
359 SDL_free(bmi); | 340 SDL_free(bmi); |
360 SDL_OutOfMemory(); | 341 SDL_OutOfMemory(); |
361 return -1; | 342 return NULL; |
362 } | 343 } |
363 palette->palVersion = 0x300; | 344 palette->palVersion = 0x300; |
364 palette->palNumEntries = ncolors; | 345 palette->palNumEntries = ncolors; |
365 for (i = 0; i < ncolors; ++i) { | 346 for (i = 0; i < ncolors; ++i) { |
366 palette->palPalEntry[i].peRed = 0xFF; | 347 palette->palPalEntry[i].peRed = 0xFF; |
367 palette->palPalEntry[i].peGreen = 0xFF; | 348 palette->palPalEntry[i].peGreen = 0xFF; |
368 palette->palPalEntry[i].peBlue = 0xFF; | 349 palette->palPalEntry[i].peBlue = 0xFF; |
369 palette->palPalEntry[i].peFlags = 0; | 350 palette->palPalEntry[i].peFlags = 0; |
370 } | 351 } |
371 data->hpal = CreatePalette(palette); | 352 *hpal = CreatePalette(palette); |
372 SDL_free(palette); | 353 SDL_free(palette); |
373 } else { | 354 } |
374 int bpp; | 355 } else { |
375 Uint32 Rmask, Gmask, Bmask, Amask; | 356 int bpp; |
376 | 357 Uint32 Rmask, Gmask, Bmask, Amask; |
377 bmi->bmiHeader.biCompression = BI_BITFIELDS; | 358 |
378 SDL_PixelFormatEnumToMasks(data->format, &bpp, &Rmask, &Gmask, | 359 bmi->bmiHeader.biCompression = BI_BITFIELDS; |
379 &Bmask, &Amask); | 360 SDL_PixelFormatEnumToMasks(format, &bpp, &Rmask, &Gmask, &Bmask, |
380 ((Uint32 *) bmi->bmiColors)[0] = Rmask; | 361 &Amask); |
381 ((Uint32 *) bmi->bmiColors)[1] = Gmask; | 362 ((Uint32 *) bmi->bmiColors)[0] = Rmask; |
382 ((Uint32 *) bmi->bmiColors)[2] = Bmask; | 363 ((Uint32 *) bmi->bmiColors)[1] = Gmask; |
383 data->hpal = NULL; | 364 ((Uint32 *) bmi->bmiColors)[2] = Bmask; |
384 } | 365 if (hpal) { |
385 data->hbm = | 366 *hpal = NULL; |
386 CreateDIBSection(renderdata->memory_hdc, bmi, DIB_RGB_COLORS, | 367 } |
387 &data->pixels, NULL, 0); | 368 } |
388 } else { | 369 return CreateDIBSection(hdc, bmi, DIB_RGB_COLORS, pixels, NULL, 0); |
389 data->hbm = | 370 } |
390 CreateCompatibleBitmap(renderdata->window_hdc, texture->w, | 371 |
391 texture->h); | 372 static int |
392 data->pixels = NULL; | 373 GDI_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) |
374 { | |
375 GDI_RenderData *renderdata = (GDI_RenderData *) renderer->driverdata; | |
376 SDL_Window *window = SDL_GetWindowFromID(renderer->window); | |
377 SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window); | |
378 GDI_TextureData *data; | |
379 | |
380 data = (GDI_TextureData *) SDL_calloc(1, sizeof(*data)); | |
381 if (!data) { | |
382 SDL_OutOfMemory(); | |
383 return -1; | |
384 } | |
385 | |
386 texture->driverdata = data; | |
387 | |
388 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { | |
389 data->yuv = | |
390 SDL_SW_CreateYUVTexture(texture->format, texture->w, texture->h); | |
391 if (!data->yuv) { | |
392 return -1; | |
393 } | |
394 data->format = display->current_mode.format; | |
395 } else { | |
396 data->format = texture->format; | |
397 } | |
398 data->pitch = (texture->w * SDL_BYTESPERPIXEL(data->format)); | |
399 | |
400 if (data->yuv || texture->access == SDL_TEXTUREACCESS_STREAMING | |
401 || texture->format != display->current_mode.format) { | |
402 data->hbm = GDI_CreateDIBSection(renderdata->memory_hdc, | |
403 texture->w, texture->h, | |
404 data->pitch, data->format, | |
405 &data->hpal, &data->pixels); | |
406 } else { | |
407 data->hbm = CreateCompatibleBitmap(renderdata->window_hdc, | |
408 texture->w, texture->h); | |
393 } | 409 } |
394 if (!data->hbm) { | 410 if (!data->hbm) { |
395 WIN_SetError("Couldn't create bitmap"); | 411 WIN_SetError("Couldn't create bitmap"); |
396 return -1; | 412 return -1; |
397 } | 413 } |
819 } | 835 } |
820 } | 836 } |
821 return 0; | 837 return 0; |
822 } | 838 } |
823 | 839 |
840 static int | |
841 GDI_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, | |
842 Uint32 format, void * pixels, int pitch) | |
843 { | |
844 GDI_RenderData *renderdata = (GDI_RenderData *) renderer->driverdata; | |
845 SDL_Window *window = SDL_GetWindowFromID(renderer->window); | |
846 SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window); | |
847 struct { | |
848 HBITMAP hbm; | |
849 void *pixels; | |
850 int pitch; | |
851 Uint32 format; | |
852 } data; | |
853 | |
854 data.format = display->current_mode.format; | |
855 data.pitch = (rect->w * SDL_BYTESPERPIXEL(data.format)); | |
856 | |
857 data.hbm = GDI_CreateDIBSection(renderdata->memory_hdc, rect->w, rect->h, | |
858 data.pitch, data.format, NULL, | |
859 &data.pixels); | |
860 if (!data.hbm) { | |
861 WIN_SetError("Couldn't create bitmap"); | |
862 return -1; | |
863 } | |
864 | |
865 SelectObject(renderdata->memory_hdc, data.hbm); | |
866 if (!BitBlt(renderdata->memory_hdc, 0, 0, rect->w, rect->h, | |
867 renderdata->current_hdc, rect->x, rect->y, SRCCOPY)) { | |
868 WIN_SetError("BitBlt()"); | |
869 DeleteObject(data.hbm); | |
870 return -1; | |
871 } | |
872 | |
873 SDL_ConvertPixels(rect->w, rect->h, | |
874 data.format, data.pixels, data.pitch, | |
875 format, pixels, pitch); | |
876 | |
877 DeleteObject(data.hbm); | |
878 return 0; | |
879 } | |
880 | |
881 static int | |
882 GDI_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect, | |
883 Uint32 format, const void * pixels, int pitch) | |
884 { | |
885 GDI_RenderData *renderdata = (GDI_RenderData *) renderer->driverdata; | |
886 SDL_Window *window = SDL_GetWindowFromID(renderer->window); | |
887 SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window); | |
888 struct { | |
889 HBITMAP hbm; | |
890 void *pixels; | |
891 int pitch; | |
892 Uint32 format; | |
893 } data; | |
894 | |
895 data.format = display->current_mode.format; | |
896 data.pitch = (rect->w * SDL_BYTESPERPIXEL(data.format)); | |
897 | |
898 data.hbm = GDI_CreateDIBSection(renderdata->memory_hdc, rect->w, rect->h, | |
899 data.pitch, data.format, | |
900 NULL, &data.pixels); | |
901 if (!data.hbm) { | |
902 WIN_SetError("Couldn't create bitmap"); | |
903 return -1; | |
904 } | |
905 | |
906 SDL_ConvertPixels(rect->w, rect->h, format, pixels, pitch, | |
907 data.format, data.pixels, data.pitch); | |
908 | |
909 SelectObject(renderdata->memory_hdc, data.hbm); | |
910 if (!BitBlt(renderdata->current_hdc, rect->x, rect->y, rect->w, rect->h, | |
911 renderdata->memory_hdc, 0, 0, SRCCOPY)) { | |
912 WIN_SetError("BitBlt()"); | |
913 DeleteObject(data.hbm); | |
914 return -1; | |
915 } | |
916 | |
917 DeleteObject(data.hbm); | |
918 return 0; | |
919 } | |
920 | |
824 static void | 921 static void |
825 GDI_RenderPresent(SDL_Renderer * renderer) | 922 GDI_RenderPresent(SDL_Renderer * renderer) |
826 { | 923 { |
827 GDI_RenderData *data = (GDI_RenderData *) renderer->driverdata; | 924 GDI_RenderData *data = (GDI_RenderData *) renderer->driverdata; |
828 SDL_DirtyRect *dirty; | 925 SDL_DirtyRect *dirty; |