comparison src/video/SDL_renderer_gl.c @ 1920:8a162bfdc838

Convert SDL_malloc to SDL_calloc if appropriate, slightly faster on operating systems which map the zero page for memory allocations. OpenGL renderer in progress
author Sam Lantinga <slouken@libsdl.org>
date Sat, 22 Jul 2006 08:33:18 +0000
parents 00816063b9c9
children f3399f779a1d
comparison
equal deleted inserted replaced
1919:00816063b9c9 1920:8a162bfdc838
20 slouken@libsdl.org 20 slouken@libsdl.org
21 */ 21 */
22 #include "SDL_config.h" 22 #include "SDL_config.h"
23 23
24 #if SDL_VIDEO_OPENGL 24 #if SDL_VIDEO_OPENGL
25 #if 0 25
26 #include "SDL_win32video.h" 26 #include "SDL_video.h"
27 #include "SDL_opengl.h"
28 #include "SDL_sysvideo.h"
29 #include "SDL_pixels_c.h"
30 #include "SDL_rect_c.h"
31 #include "SDL_yuv_sw_c.h"
27 32
28 /* OpenGL renderer implementation */ 33 /* OpenGL renderer implementation */
29 34
30 static SDL_Renderer *GL_CreateRenderer(SDL_Window * window, Uint32 flags); 35 static SDL_Renderer *GL_CreateRenderer(SDL_Window * window, Uint32 flags);
31 static int GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture); 36 static int GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture);
64 (SDL_TextureBlendMode_None | SDL_TextureBlendMode_Mask | 69 (SDL_TextureBlendMode_None | SDL_TextureBlendMode_Mask |
65 SDL_TextureBlendMode_Blend | SDL_TextureBlendMode_Add | 70 SDL_TextureBlendMode_Blend | SDL_TextureBlendMode_Add |
66 SDL_TextureBlendMode_Mod), 71 SDL_TextureBlendMode_Mod),
67 (SDL_TextureScaleMode_None | SDL_TextureScaleMode_Fast | 72 (SDL_TextureScaleMode_None | SDL_TextureScaleMode_Fast |
68 SDL_TextureScaleMode_Best), 73 SDL_TextureScaleMode_Best),
69 12, 74 18,
70 { 75 {
76 SDL_PixelFormat_Index1LSB,
77 SDL_PixelFormat_Index1MSB,
71 SDL_PixelFormat_Index8, 78 SDL_PixelFormat_Index8,
72 SDL_PixelFormat_RGB332, 79 SDL_PixelFormat_RGB332,
73 SDL_PixelFormat_RGB444, 80 SDL_PixelFormat_RGB444,
74 SDL_PixelFormat_RGB555, 81 SDL_PixelFormat_RGB555,
75 SDL_PixelFormat_ARGB4444, 82 SDL_PixelFormat_ARGB4444,
76 SDL_PixelFormat_ARGB1555, 83 SDL_PixelFormat_ARGB1555,
77 SDL_PixelFormat_RGB565, 84 SDL_PixelFormat_RGB565,
85 SDL_PixelFormat_RGB24,
86 SDL_PixelFormat_BGR24,
78 SDL_PixelFormat_RGB888, 87 SDL_PixelFormat_RGB888,
88 SDL_PixelFormat_BGR888,
79 SDL_PixelFormat_ARGB8888, 89 SDL_PixelFormat_ARGB8888,
80 SDL_PixelFormat_ARGB2101010, 90 SDL_PixelFormat_RGBA8888,
81 SDL_PixelFormat_UYVY, 91 SDL_PixelFormat_ABGR8888,
82 SDL_PixelFormat_YUY2}, 92 SDL_PixelFormat_BGRA8888,
93 SDL_PixelFormat_ARGB2101010}, /* FIXME: YUV texture support */
83 0, 94 0,
84 0} 95 0}
85 }; 96 };
86 97
87 typedef struct 98 typedef struct
88 { 99 {
89 SDL_GLContext context; 100 SDL_GLContext context;
90 SDL_bool beginScene;
91 } GL_RenderData; 101 } GL_RenderData;
92 102
93 typedef struct 103 typedef struct
94 { 104 {
95 GLuint texture; 105 GLuint texture;
106 GLenum type;
96 GLfloat texw; 107 GLfloat texw;
97 GLfloat texh; 108 GLfloat texh;
109 GLenum format;
110 GLenum formattype;
98 void *pixels; 111 void *pixels;
99 int pitch; 112 int pitch;
113 SDL_DirtyRectList dirty;
100 } GL_TextureData; 114 } GL_TextureData;
101 115
102 static GLFORMAT
103 PixelFormatToOpenGL(Uint32 format,)
104 {
105 switch (format) {
106 case SDL_PixelFormat_Index8:
107 return GLFMT_P8;
108 case SDL_PixelFormat_RGB332:
109 return GLFMT_R3G3B2;
110 case SDL_PixelFormat_RGB444:
111 return GLFMT_X4R4G4B4;
112 case SDL_PixelFormat_RGB555:
113 return GLFMT_X1R5G5B5;
114 case SDL_PixelFormat_ARGB4444:
115 return GLFMT_A4R4G4B4;
116 case SDL_PixelFormat_ARGB1555:
117 return GLFMT_A1R5G5B5;
118 case SDL_PixelFormat_RGB565:
119 return GLFMT_R5G6B5;
120 case SDL_PixelFormat_RGB888:
121 return GLFMT_X8R8G8B8;
122 case SDL_PixelFormat_ARGB8888:
123 return GLFMT_A8R8G8B8;
124 case SDL_PixelFormat_ARGB2101010:
125 return GLFMT_A2R10G10B10;
126 case SDL_PixelFormat_UYVY:
127 return GLFMT_UYVY;
128 case SDL_PixelFormat_YUY2:
129 return GLFMT_YUY2;
130 default:
131 return GLFMT_UNKNOWN;
132 }
133 }
134 116
135 void 117 void
136 GL_AddRenderDriver(_THIS) 118 GL_AddRenderDriver(_THIS)
137 { 119 {
138 SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; 120 if (_this->GL_CreateContext) {
139
140 if (data->d3d) {
141 SDL_AddRenderDriver(0, &GL_RenderDriver); 121 SDL_AddRenderDriver(0, &GL_RenderDriver);
142 } 122 }
143 } 123 }
144 124
145 SDL_Renderer * 125 SDL_Renderer *
146 GL_CreateRenderer(SDL_Window * window, Uint32 flags) 126 GL_CreateRenderer(SDL_Window * window, Uint32 flags)
147 { 127 {
148 SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
149 SDL_VideoData *videodata = (SDL_VideoData *) display->device->driverdata;
150 SDL_WindowData *windowdata = (SDL_WindowData *) window->driverdata;
151 SDL_Renderer *renderer; 128 SDL_Renderer *renderer;
152 GL_RenderData *data; 129 GL_RenderData *data;
153 HRESULT result;
154 GLPRESENT_PARAMETERS pparams;
155 IDirect3DSwapChain9 *chain;
156 130
157 if (!(window->flags & SDL_WINDOW_OPENGL)) { 131 if (!(window->flags & SDL_WINDOW_OPENGL)) {
158 SDL_SetError 132 SDL_SetError
159 ("The OpenGL renderer can only be used on OpenGL windows"); 133 ("The OpenGL renderer can only be used on OpenGL windows");
160 return NULL; 134 return NULL;
161 } 135 }
162 136
163 renderer = (SDL_Renderer *) SDL_malloc(sizeof(*renderer)); 137 renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
164 if (!renderer) { 138 if (!renderer) {
165 SDL_OutOfMemory(); 139 SDL_OutOfMemory();
166 return NULL; 140 return NULL;
167 } 141 }
168 SDL_zerop(renderer); 142
169 143 data = (GL_RenderData *) SDL_calloc(1, sizeof(*data));
170 data = (GL_RenderData *) SDL_malloc(sizeof(*data));
171 if (!data) { 144 if (!data) {
172 GL_DestroyRenderer(renderer); 145 GL_DestroyRenderer(renderer);
173 SDL_OutOfMemory(); 146 SDL_OutOfMemory();
174 return NULL; 147 return NULL;
175 } 148 }
176 SDL_zerop(data);
177 149
178 renderer->CreateTexture = GL_CreateTexture; 150 renderer->CreateTexture = GL_CreateTexture;
179 renderer->SetTexturePalette = GL_SetTexturePalette; 151 renderer->SetTexturePalette = GL_SetTexturePalette;
180 renderer->GetTexturePalette = GL_GetTexturePalette; 152 renderer->GetTexturePalette = GL_GetTexturePalette;
181 renderer->UpdateTexture = GL_UpdateTexture; 153 renderer->UpdateTexture = GL_UpdateTexture;
201 } 173 }
202 if (SDL_GL_MakeCurrent(window->id, data->context) < 0) { 174 if (SDL_GL_MakeCurrent(window->id, data->context) < 0) {
203 GL_DestroyRenderer(renderer); 175 GL_DestroyRenderer(renderer);
204 return NULL; 176 return NULL;
205 } 177 }
206 data->beginScene = SDL_TRUE;
207 178
208 if (flags & SDL_Renderer_PresentVSync) { 179 if (flags & SDL_Renderer_PresentVSync) {
209 SDL_GL_SetSwapInterval(1); 180 SDL_GL_SetSwapInterval(1);
210 } else { 181 } else {
211 SDL_GL_SetSwapInterval(0); 182 SDL_GL_SetSwapInterval(0);
212 } 183 }
213 if (SDL_GL_GetSwapInterval() > 0) { 184 if (SDL_GL_GetSwapInterval() > 0) {
214 renderer->info.flags |= SDL_Renderer_PresentVSync; 185 renderer->info.flags |= SDL_Renderer_PresentVSync;
215 } 186 }
216 187
188 /* FIXME: Add a function to make the rendering context current when selecting the renderer */
189
190 /* FIXME: Query maximum texture size */
191
192 /* FIXME: Check for GL_ARB_texture_rectangle and GL_EXT_texture_rectangle */
193
217 /* Set up parameters for rendering */ 194 /* Set up parameters for rendering */
218 glDisable(GL_DEPTH_TEST); 195 glDisable(GL_DEPTH_TEST);
219 glDisable(GL_CULL_FACE); 196 glDisable(GL_CULL_FACE);
220 glEnable(GL_TEXTURE_2D); 197 glEnable(GL_TEXTURE_2D);
198 glEnable(GL_TEXTURE_RECTANGLE_ARB);
199 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
221 glMatrixMode(GL_PROJECTION); 200 glMatrixMode(GL_PROJECTION);
222 glLoadIdentity(); 201 glLoadIdentity();
223 glMatrixMode(GL_MODELVIEW); 202 glMatrixMode(GL_MODELVIEW);
224 glLoadIdentity(); 203 glLoadIdentity();
225 glViewport(0, 0, window->w, window->h); 204 glViewport(0, 0, window->w, window->h);
226 glOrtho(0.0, (GLdouble) window->w, (GLdouble) window->h, 0.0, 0.0, 1.0); 205 glOrtho(0.0, (GLdouble) window->w, (GLdouble) window->h, 0.0, 0.0, 1.0);
227 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
228 206
229 return renderer; 207 return renderer;
230 }
231
232 /* Quick utility function for texture creation */
233 static int
234 power_of_two(int input)
235 {
236 int value = 1;
237
238 while (value < input) {
239 value <<= 1;
240 }
241 return value;
242 } 208 }
243 209
244 static int 210 static int
245 GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) 211 GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
246 { 212 {
247 GL_RenderData *renderdata = (GL_RenderData *) renderer->driverdata; 213 GL_RenderData *renderdata = (GL_RenderData *) renderer->driverdata;
248 SDL_Window *window = SDL_GetWindowFromID(renderer->window); 214 SDL_Window *window = SDL_GetWindowFromID(renderer->window);
249 SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
250 GL_TextureData *data; 215 GL_TextureData *data;
251 GLPOOL pool; 216 GLint internalFormat;
252 HRESULT result; 217 GLenum format, type;
253 218
254 data = (GL_TextureData *) SDL_malloc(sizeof(*data)); 219 switch (texture->format) {
220 case SDL_PixelFormat_Index1LSB:
221 case SDL_PixelFormat_Index1MSB:
222 internalFormat = GL_RGB;
223 format = GL_COLOR_INDEX;
224 type = GL_BITMAP;
225 break;
226 case SDL_PixelFormat_Index8:
227 internalFormat = GL_RGB;
228 format = GL_COLOR_INDEX;
229 type = GL_UNSIGNED_BYTE;
230 break;
231 case SDL_PixelFormat_RGB332:
232 internalFormat = GL_R3_G3_B2;
233 format = GL_RGB;
234 type = GL_UNSIGNED_BYTE_3_3_2;
235 break;
236 case SDL_PixelFormat_RGB444:
237 internalFormat = GL_RGB4;
238 format = GL_RGB;
239 type = GL_UNSIGNED_SHORT_4_4_4_4;
240 break;
241 case SDL_PixelFormat_RGB555:
242 internalFormat = GL_RGB5;
243 format = GL_RGB;
244 type = GL_UNSIGNED_SHORT_5_5_5_1;
245 break;
246 case SDL_PixelFormat_ARGB4444:
247 internalFormat = GL_RGBA4;
248 format = GL_BGRA;
249 type = GL_UNSIGNED_SHORT_4_4_4_4_REV;
250 break;
251 case SDL_PixelFormat_ARGB1555:
252 internalFormat = GL_RGB5_A1;
253 format = GL_BGRA;
254 type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
255 break;
256 case SDL_PixelFormat_RGB565:
257 internalFormat = GL_RGB8;
258 format = GL_RGB;
259 type = GL_UNSIGNED_SHORT_5_6_5;
260 break;
261 case SDL_PixelFormat_RGB24:
262 internalFormat = GL_RGB8;
263 format = GL_RGB;
264 type = GL_UNSIGNED_BYTE;
265 break;
266 case SDL_PixelFormat_RGB888:
267 internalFormat = GL_RGB8;
268 format = GL_RGB;
269 type = GL_UNSIGNED_INT_8_8_8_8;
270 break;
271 case SDL_PixelFormat_BGR24:
272 internalFormat = GL_RGB8;
273 format = GL_BGR;
274 type = GL_UNSIGNED_BYTE;
275 break;
276 case SDL_PixelFormat_BGR888:
277 internalFormat = GL_RGB8;
278 format = GL_BGR;
279 type = GL_UNSIGNED_INT_8_8_8_8;
280 break;
281 case SDL_PixelFormat_ARGB8888:
282 internalFormat = GL_RGBA8;
283 format = GL_BGRA;
284 type = GL_UNSIGNED_INT_8_8_8_8_REV;
285 break;
286 case SDL_PixelFormat_RGBA8888:
287 internalFormat = GL_RGBA8;
288 format = GL_BGRA;
289 type = GL_UNSIGNED_INT_8_8_8_8;
290 break;
291 case SDL_PixelFormat_ABGR8888:
292 internalFormat = GL_RGBA8;
293 format = GL_RGBA;
294 type = GL_UNSIGNED_INT_8_8_8_8_REV;
295 break;
296 case SDL_PixelFormat_BGRA8888:
297 internalFormat = GL_RGBA8;
298 format = GL_BGRA;
299 type = GL_UNSIGNED_INT_8_8_8_8;
300 break;
301 case SDL_PixelFormat_ARGB2101010:
302 internalFormat = GL_RGB10_A2;
303 format = GL_BGRA;
304 type = GL_UNSIGNED_INT_2_10_10_10_REV;
305 break;
306 default:
307 SDL_SetError("Unsupported texture format");
308 return -1;
309 }
310
311 data = (GL_TextureData *) SDL_calloc(1, sizeof(*data));
255 if (!data) { 312 if (!data) {
256 SDL_OutOfMemory(); 313 SDL_OutOfMemory();
257 return -1; 314 return -1;
258 } 315 }
259 SDL_zerop(data);
260 316
261 texture->driverdata = data; 317 texture->driverdata = data;
262 318
263 if (texture->access == SDL_TextureAccess_Local) { 319 /* FIXME: Check for GL_ARB_texture_rectangle and GL_EXT_texture_rectangle */
264 pool = GLPOOL_MANAGED; 320 glGenTextures(1, &data->texture);
265 } else { 321 data->type = GL_TEXTURE_RECTANGLE_ARB;
266 pool = GLPOOL_DEFAULT; 322 data->texw = (GLfloat) texture->w;
267 } 323 data->texh = (GLfloat) texture->h;
268 result = 324 data->format = format;
269 IDirect3DDevice9_CreateTexture(renderdata->device, texture->w, 325 data->formattype = type;
270 texture->h, 1, 0, 326 glBindTexture(data->type, data->texture);
271 PixelFormatToGLFMT(texture->format), 327 glTexImage2D(data->type, 0, internalFormat, texture->w, texture->h, 0,
272 pool, &data->texture, NULL); 328 format, type, NULL);
273 if (FAILED(result)) {
274 SDL_free(data);
275 GL_SetError("CreateTexture()", result);
276 return -1;
277 }
278 329
279 return 0; 330 return 0;
280 } 331 }
281 332
282 static int 333 static int
301 static int 352 static int
302 GL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, 353 GL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
303 const SDL_Rect * rect, const void *pixels, int pitch) 354 const SDL_Rect * rect, const void *pixels, int pitch)
304 { 355 {
305 GL_TextureData *data = (GL_TextureData *) texture->driverdata; 356 GL_TextureData *data = (GL_TextureData *) texture->driverdata;
306 GL_RenderData *renderdata = (GL_RenderData *) renderer->driverdata; 357
307 IDirect3DTexture9 *temp; 358 glPixelStorei(GL_UNPACK_ALIGNMENT, 1); /* FIXME, what to use for RGB 4 byte formats? */
308 RECT d3drect; 359 glPixelStorei(GL_UNPACK_ROW_LENGTH,
309 GLLOCKED_RECT locked; 360 pitch / SDL_BYTESPERPIXEL(texture->format));
310 const Uint8 *src; 361 glBindTexture(data->type, data->texture);
311 Uint8 *dst; 362 glTexSubImage2D(data->type, 0, rect->x, rect->y, rect->w, rect->h,
312 int row, length; 363 data->format, data->formattype, pixels);
313 HRESULT result; 364 /* FIXME: check for errors */
314
315 result =
316 IDirect3DDevice9_CreateTexture(renderdata->device, texture->w,
317 texture->h, 1, 0,
318 PixelFormatToGLFMT(texture->format),
319 GLPOOL_SYSTEMMEM, &temp, NULL);
320 if (FAILED(result)) {
321 GL_SetError("CreateTexture()", result);
322 return -1;
323 }
324
325 d3drect.left = rect->x;
326 d3drect.right = rect->x + rect->w;
327 d3drect.top = rect->y;
328 d3drect.bottom = rect->y + rect->h;
329
330 result = IDirect3DTexture9_LockRect(temp, 0, &locked, &d3drect, 0);
331 if (FAILED(result)) {
332 IDirect3DTexture9_Release(temp);
333 GL_SetError("LockRect()", result);
334 return -1;
335 }
336
337 src = pixels;
338 dst = locked.pBits;
339 length = rect->w * SDL_BYTESPERPIXEL(texture->format);
340 for (row = 0; row < rect->h; ++row) {
341 SDL_memcpy(dst, src, length);
342 src += pitch;
343 dst += locked.Pitch;
344 }
345 IDirect3DTexture9_UnlockRect(temp, 0);
346
347 result =
348 IDirect3DDevice9_UpdateTexture(renderdata->device,
349 (IDirect3DBaseTexture9 *) temp,
350 (IDirect3DBaseTexture9 *) data->
351 texture);
352 IDirect3DTexture9_Release(temp);
353 if (FAILED(result)) {
354 GL_SetError("UpdateTexture()", result);
355 return -1;
356 }
357 return 0; 365 return 0;
358 } 366 }
359 367
360 static int 368 static int
361 GL_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, 369 GL_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
362 const SDL_Rect * rect, int markDirty, void **pixels, 370 const SDL_Rect * rect, int markDirty, void **pixels,
363 int *pitch) 371 int *pitch)
364 { 372 {
365 GL_TextureData *data = (GL_TextureData *) texture->driverdata; 373 GL_TextureData *data = (GL_TextureData *) texture->driverdata;
366 RECT d3drect; 374
367 GLLOCKED_RECT locked; 375 if (!data->pixels) {
368 HRESULT result; 376 data->pitch = texture->w * SDL_BYTESPERPIXEL(texture->format);
369 377 data->pixels = SDL_malloc(texture->h * data->pitch);
370 if (texture->access != SDL_TextureAccess_Local) { 378 if (!data->pixels) {
371 SDL_SetError("Can't lock remote video memory"); 379 SDL_OutOfMemory();
372 return -1; 380 return -1;
373 } 381 }
374 382 }
375 d3drect.left = rect->x; 383
376 d3drect.right = rect->x + rect->w; 384 if (markDirty) {
377 d3drect.top = rect->y; 385 SDL_AddDirtyRect(&data->dirty, rect);
378 d3drect.bottom = rect->y + rect->h; 386 }
379 387
380 result = 388 *pixels =
381 IDirect3DTexture9_LockRect(data->texture, 0, &locked, &d3drect, 389 (void *) ((Uint8 *) data->pixels + rect->y * data->pitch +
382 markDirty ? 0 : GLLOCK_NO_DIRTY_UPDATE); 390 rect->x * SDL_BYTESPERPIXEL(texture->format));
383 if (FAILED(result)) { 391 *pitch = data->pitch;
384 GL_SetError("LockRect()", result);
385 return -1;
386 }
387 *pixels = locked.pBits;
388 *pitch = locked.Pitch;
389 return 0; 392 return 0;
390 } 393 }
391 394
392 static void 395 static void
393 GL_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) 396 GL_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
394 { 397 {
395 GL_TextureData *data = (GL_TextureData *) texture->driverdata;
396
397 IDirect3DTexture9_UnlockRect(data->texture, 0);
398 } 398 }
399 399
400 static void 400 static void
401 GL_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture, int numrects, 401 GL_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture, int numrects,
402 const SDL_Rect * rects) 402 const SDL_Rect * rects)
403 { 403 {
404 GL_TextureData *data = (GL_TextureData *) texture->driverdata; 404 GL_TextureData *data = (GL_TextureData *) texture->driverdata;
405 RECT d3drect;
406 int i; 405 int i;
407 406
408 for (i = 0; i < numrects; ++i) { 407 for (i = 0; i < numrects; ++i) {
409 const SDL_Rect *rect = &rects[i]; 408 SDL_AddDirtyRect(&data->dirty, &rects[i]);
410
411 d3drect.left = rect->x;
412 d3drect.right = rect->x + rect->w;
413 d3drect.top = rect->y;
414 d3drect.bottom = rect->y + rect->h;
415
416 IDirect3DTexture9_AddDirtyRect(data->texture, &d3drect);
417 } 409 }
418 } 410 }
419 411
420 static int 412 static int
421 GL_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect, Uint32 color) 413 GL_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect, Uint32 color)
444 GL_RenderData *data = (GL_RenderData *) renderer->driverdata; 436 GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
445 GL_TextureData *texturedata = (GL_TextureData *) texture->driverdata; 437 GL_TextureData *texturedata = (GL_TextureData *) texture->driverdata;
446 int minx, miny, maxx, maxy; 438 int minx, miny, maxx, maxy;
447 GLfloat minu, maxu, minv, maxv; 439 GLfloat minu, maxu, minv, maxv;
448 440
441 if (texturedata->dirty.count > 0) {
442 SDL_DirtyRect *dirty;
443 void *pixels;
444 int bpp = SDL_BYTESPERPIXEL(texture->format);
445 int pitch = texturedata->pitch;
446
447 glPixelStorei(GL_UNPACK_ALIGNMENT, 1); /* FIXME, what to use for RGB 4 byte formats? */
448 glPixelStorei(GL_UNPACK_ROW_LENGTH,
449 pitch / SDL_BYTESPERPIXEL(texture->format));
450 glBindTexture(texturedata->type, texturedata->texture);
451 for (dirty = texturedata->dirty.list; dirty; dirty = dirty->next) {
452 SDL_Rect *rect = &dirty->rect;
453 pixels =
454 (void *) ((Uint8 *) texturedata->pixels + rect->y * pitch +
455 rect->x * bpp);
456 glTexSubImage2D(texturedata->type, 0, rect->x, rect->y, rect->w,
457 rect->h, texturedata->format,
458 texturedata->formattype, pixels);
459 }
460 SDL_ClearDirtyRects(&texturedata->dirty);
461 }
462
449 minx = dstrect->x; 463 minx = dstrect->x;
450 miny = dstrect->y; 464 miny = dstrect->y;
451 maxx = dstrect->x + dstrect->w; 465 maxx = dstrect->x + dstrect->w;
452 maxy = dstrect->y + dstrect->h; 466 maxy = dstrect->y + dstrect->h;
453 467
454 minu = (GLfloat) srcrect->x / texture->w; 468 minu = (GLfloat) srcrect->x / texture->w;
469 minu *= texturedata->texw;
455 maxu = (GLfloat) (srcrect->x + srcrect->w) / texture->w; 470 maxu = (GLfloat) (srcrect->x + srcrect->w) / texture->w;
471 maxu *= texturedata->texw;
456 minv = (GLfloat) srcrect->y / texture->h; 472 minv = (GLfloat) srcrect->y / texture->h;
473 minv *= texturedata->texh;
457 maxv = (GLfloat) (srcrect->y + srcrect->h) / texture->h; 474 maxv = (GLfloat) (srcrect->y + srcrect->h) / texture->h;
458 475 maxv *= texturedata->texh;
459 glBindTexture(GL_TEXTURE_2D, texturedata->texture); 476
477 glBindTexture(texturedata->type, texturedata->texture);
460 478
461 switch (blendMode) { 479 switch (blendMode) {
462 case SDL_TextureBlendMode_None: 480 case SDL_TextureBlendMode_None:
463 glDisable(GL_BLEND); 481 glDisable(GL_BLEND);
464 break; 482 break;
478 } 496 }
479 497
480 switch (scaleMode) { 498 switch (scaleMode) {
481 case SDL_TextureScaleMode_None: 499 case SDL_TextureScaleMode_None:
482 case SDL_TextureScaleMode_Fast: 500 case SDL_TextureScaleMode_Fast:
483 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 501 glTexParameteri(texturedata->type, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
484 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 502 glTexParameteri(texturedata->type, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
485 break; 503 break;
486 case SDL_TextureScaleMode_Slow: 504 case SDL_TextureScaleMode_Slow:
487 case SDL_TextureScaleMode_Best: 505 case SDL_TextureScaleMode_Best:
488 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 506 glTexParameteri(texturedata->type, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
489 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 507 glTexParameteri(texturedata->type, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
490 break; 508 break;
491 } 509 }
492 510
493 glBegin(GL_TRIANGLE_STRIP); 511 glBegin(GL_TRIANGLE_STRIP);
494 glTexCoord2f(minu, minv); 512 glTexCoord2f(minu, minv);
517 535
518 if (!data) { 536 if (!data) {
519 return; 537 return;
520 } 538 }
521 if (data->texture) { 539 if (data->texture) {
522 IDirect3DTexture9_Release(data->texture); 540 glDeleteTextures(1, &data->texture);
523 } 541 }
542 if (data->pixels) {
543 SDL_free(data->pixels);
544 }
545 SDL_FreeDirtyRects(&data->dirty);
524 SDL_free(data); 546 SDL_free(data);
525 texture->driverdata = NULL; 547 texture->driverdata = NULL;
526 } 548 }
527 549
528 void 550 void
529 GL_DestroyRenderer(SDL_Renderer * renderer) 551 GL_DestroyRenderer(SDL_Renderer * renderer)
530 { 552 {
531 GL_RenderData *data = (GL_RenderData *) renderer->driverdata; 553 GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
532 554
533 if (data) { 555 if (data) {
534 if (data->device) { 556 if (data->context) {
535 IDirect3DDevice9_Release(data->device); 557 SDL_GL_MakeCurrent(0, NULL);
558 SDL_GL_DeleteContext(data->context);
536 } 559 }
537 SDL_free(data); 560 SDL_free(data);
538 } 561 }
539 SDL_free(renderer); 562 SDL_free(renderer);
540 } 563 }
541 564
542 #endif /* 0 */
543 #endif /* SDL_VIDEO_OPENGL */ 565 #endif /* SDL_VIDEO_OPENGL */
544 566
545 /* vi: set ts=4 sw=4 expandtab: */ 567 /* vi: set ts=4 sw=4 expandtab: */