Mercurial > sdl-ios-xcode
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: */ |