If the OpenGL renderer is selected for a non-OpenGL window, recreate the window with OpenGL enabled.
Added OpenGL renderer error checking.
Use fast-path texture formats in the OpenGL renderer.
--- a/src/SDL_compat.c Sat Jul 22 19:51:48 2006 +0000
+++ b/src/SDL_compat.c Sat Jul 22 21:02:57 2006 +0000
@@ -469,7 +469,8 @@
height);
if (!SDL_VideoTexture) {
SDL_VideoTexture =
- SDL_CreateTexture(0, SDL_TextureAccess_Local, width, height);
+ SDL_CreateTexture(SDL_PixelFormat_RGB888, SDL_TextureAccess_Local,
+ width, height);
}
if (!SDL_VideoTexture) {
return NULL;
--- a/src/video/SDL_renderer_gl.c Sat Jul 22 19:51:48 2006 +0000
+++ b/src/video/SDL_renderer_gl.c Sat Jul 22 21:02:57 2006 +0000
@@ -72,7 +72,7 @@
SDL_TextureBlendMode_Mod),
(SDL_TextureScaleMode_None | SDL_TextureScaleMode_Fast |
SDL_TextureScaleMode_Slow),
- 18,
+ 16,
{
SDL_PixelFormat_Index1LSB,
SDL_PixelFormat_Index1MSB,
@@ -88,10 +88,8 @@
SDL_PixelFormat_RGB888,
SDL_PixelFormat_BGR888,
SDL_PixelFormat_ARGB8888,
- SDL_PixelFormat_RGBA8888,
SDL_PixelFormat_ABGR8888,
- SDL_PixelFormat_BGRA8888,
- SDL_PixelFormat_ARGB2101010}, /* FIXME: YUV texture support */
+ SDL_PixelFormat_ARGB2101010},
0,
0}
};
@@ -115,6 +113,43 @@
} GL_TextureData;
+static void
+GL_SetError(const char *prefix, GLenum result)
+{
+ const char *error;
+
+ switch (result) {
+ case GL_NO_ERROR:
+ error = "GL_NO_ERROR";
+ break;
+ case GL_INVALID_ENUM:
+ error = "GL_INVALID_ENUM";
+ break;
+ case GL_INVALID_VALUE:
+ error = "GL_INVALID_VALUE";
+ break;
+ case GL_INVALID_OPERATION:
+ error = "GL_INVALID_OPERATION";
+ break;
+ case GL_STACK_OVERFLOW:
+ error = "GL_STACK_OVERFLOW";
+ break;
+ case GL_STACK_UNDERFLOW:
+ error = "GL_STACK_UNDERFLOW";
+ break;
+ case GL_OUT_OF_MEMORY:
+ error = "GL_OUT_OF_MEMORY";
+ break;
+ case GL_TABLE_TOO_LARGE:
+ error = "GL_TABLE_TOO_LARGE";
+ break;
+ default:
+ error = "UNKNOWN";
+ break;
+ }
+ SDL_SetError("%s: %s", prefix, error);
+}
+
void
GL_AddRenderDriver(_THIS)
{
@@ -130,9 +165,10 @@
GL_RenderData *data;
if (!(window->flags & SDL_WINDOW_OPENGL)) {
- SDL_SetError
- ("The OpenGL renderer can only be used on OpenGL windows");
- return NULL;
+ window->flags |= SDL_WINDOW_OPENGL;
+ if (SDL_RecreateWindow(window) < 0) {
+ return NULL;
+ }
}
renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
@@ -239,6 +275,7 @@
GLint internalFormat;
GLenum format, type;
int texture_w, texture_h;
+ GLenum result;
switch (texture->format) {
case SDL_PixelFormat_Index1LSB:
@@ -289,8 +326,8 @@
break;
case SDL_PixelFormat_RGB888:
internalFormat = GL_RGB8;
- format = GL_RGB;
- type = GL_UNSIGNED_INT_8_8_8_8;
+ format = GL_BGRA;
+ type = GL_UNSIGNED_BYTE;
break;
case SDL_PixelFormat_BGR24:
internalFormat = GL_RGB8;
@@ -299,28 +336,18 @@
break;
case SDL_PixelFormat_BGR888:
internalFormat = GL_RGB8;
- format = GL_BGR;
- type = GL_UNSIGNED_INT_8_8_8_8;
+ format = GL_RGBA;
+ type = GL_UNSIGNED_BYTE;
break;
case SDL_PixelFormat_ARGB8888:
internalFormat = GL_RGBA8;
format = GL_BGRA;
- type = GL_UNSIGNED_INT_8_8_8_8_REV;
- break;
- case SDL_PixelFormat_RGBA8888:
- internalFormat = GL_RGBA8;
- format = GL_RGBA;
- type = GL_UNSIGNED_INT_8_8_8_8;
+ type = GL_UNSIGNED_BYTE;
break;
case SDL_PixelFormat_ABGR8888:
internalFormat = GL_RGBA8;
format = GL_RGBA;
- type = GL_UNSIGNED_INT_8_8_8_8_REV;
- break;
- case SDL_PixelFormat_BGRA8888:
- internalFormat = GL_RGBA8;
- format = GL_BGRA;
- type = GL_UNSIGNED_INT_8_8_8_8;
+ type = GL_UNSIGNED_BYTE;
break;
case SDL_PixelFormat_ARGB2101010:
internalFormat = GL_RGB10_A2;
@@ -340,7 +367,7 @@
texture->driverdata = data;
- /* FIXME: Check for GL_ARB_texture_rectangle and GL_EXT_texture_rectangle */
+ glGetError();
glGenTextures(1, &data->texture);
#ifdef USE_GL_TEXTURE_RECTANGLE
data->type = GL_TEXTURE_RECTANGLE_ARB;
@@ -360,7 +387,11 @@
glBindTexture(data->type, data->texture);
glTexImage2D(data->type, 0, internalFormat, texture_w, texture_h, 0,
format, type, NULL);
-
+ result = glGetError();
+ if (result != GL_NO_ERROR) {
+ GL_SetError("glTexImage2D()", result);
+ return -1;
+ }
return 0;
}
@@ -383,19 +414,36 @@
return 0;
}
+static void
+SetupTextureUpdate(SDL_Texture * texture, int pitch)
+{
+ if (texture->format == SDL_PixelFormat_Index1LSB) {
+ glPixelStorei(GL_UNPACK_LSB_FIRST, 1);
+ } else if (texture->format == SDL_PixelFormat_Index1MSB) {
+ glPixelStorei(GL_UNPACK_LSB_FIRST, 0);
+ }
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH,
+ pitch / SDL_BYTESPERPIXEL(texture->format));
+}
+
static int
GL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
const SDL_Rect * rect, const void *pixels, int pitch)
{
GL_TextureData *data = (GL_TextureData *) texture->driverdata;
+ GLenum result;
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1); /* FIXME, what to use for RGB 4 byte formats? */
- glPixelStorei(GL_UNPACK_ROW_LENGTH,
- pitch / SDL_BYTESPERPIXEL(texture->format));
+ glGetError();
+ SetupTextureUpdate(texture, pitch);
glBindTexture(data->type, data->texture);
glTexSubImage2D(data->type, 0, rect->x, rect->y, rect->w, rect->h,
data->format, data->formattype, pixels);
- /* FIXME: check for errors */
+ result = glGetError();
+ if (result != GL_NO_ERROR) {
+ GL_SetError("glTexSubImage2D()", result);
+ return -1;
+ }
return 0;
}
@@ -478,9 +526,7 @@
int bpp = SDL_BYTESPERPIXEL(texture->format);
int pitch = texturedata->pitch;
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1); /* FIXME, what to use for RGB 4 byte formats? */
- glPixelStorei(GL_UNPACK_ROW_LENGTH,
- pitch / SDL_BYTESPERPIXEL(texture->format));
+ SetupTextureUpdate(texture, pitch);
glBindTexture(texturedata->type, texturedata->texture);
for (dirty = texturedata->dirty.list; dirty; dirty = dirty->next) {
SDL_Rect *rect = &dirty->rect;
--- a/src/video/SDL_sysvideo.h Sat Jul 22 19:51:48 2006 +0000
+++ b/src/video/SDL_sysvideo.h Sat Jul 22 21:02:57 2006 +0000
@@ -397,6 +397,7 @@
extern void SDL_AddRenderDriver(int displayIndex,
const SDL_RenderDriver * driver);
+extern int SDL_RecreateWindow(SDL_Window * window);
extern SDL_Window *SDL_GetWindowFromID(SDL_WindowID windowID);
extern SDL_VideoDisplay *SDL_GetDisplayFromWindow(SDL_Window * window);
--- a/src/video/SDL_video.c Sat Jul 22 19:51:48 2006 +0000
+++ b/src/video/SDL_video.c Sat Jul 22 21:02:57 2006 +0000
@@ -833,6 +833,20 @@
return window.id;
}
+int
+SDL_RecreateWindow(SDL_Window * window)
+{
+ if ((window->flags & SDL_WINDOW_OPENGL) && !_this->GL_CreateContext) {
+ window->flags &= ~SDL_WINDOW_OPENGL;
+ SDL_SetError("No OpenGL support in video driver");
+ return -1;
+ }
+ if (_this->DestroyWindow) {
+ _this->DestroyWindow(_this, window);
+ }
+ return _this->CreateWindow(_this, window);
+}
+
SDL_Window *
SDL_GetWindowFromID(SDL_WindowID windowID)
{
@@ -1259,6 +1273,7 @@
if (window->title) {
SDL_free(window->title);
}
+ SDL_free(window);
if (j != display->num_windows - 1) {
SDL_memcpy(&display->windows[i],
&display->windows[i + 1],
@@ -1421,6 +1436,9 @@
texture->renderer = renderer;
if (renderer->CreateTexture(renderer, texture) < 0) {
+ if (renderer->DestroyTexture) {
+ renderer->DestroyTexture(renderer, texture);
+ }
SDL_free(texture);
return 0;
}
--- a/src/video/win32/SDL_d3drender.c Sat Jul 22 19:51:48 2006 +0000
+++ b/src/video/win32/SDL_d3drender.c Sat Jul 22 21:02:57 2006 +0000
@@ -396,7 +396,6 @@
PixelFormatToD3DFMT(texture->format),
pool, &data->texture, NULL);
if (FAILED(result)) {
- SDL_free(data);
D3D_SetError("CreateTexture()", result);
return -1;
}
--- a/src/video/win32/SDL_gdirender.c Sat Jul 22 19:51:48 2006 +0000
+++ b/src/video/win32/SDL_gdirender.c Sat Jul 22 21:02:57 2006 +0000
@@ -249,7 +249,6 @@
if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
data->yuv = SDL_SW_CreateYUVTexture(texture);
if (!data->yuv) {
- GDI_DestroyTexture(renderer, texture);
return -1;
}
data->format = display->current_mode.format;
@@ -266,7 +265,6 @@
bmi_size = sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD);
bmi = (LPBITMAPINFO) SDL_calloc(1, bmi_size);
if (!bmi) {
- GDI_DestroyTexture(renderer, texture);
SDL_OutOfMemory();
return -1;
}
@@ -291,7 +289,6 @@
ncolors * sizeof(PALETTEENTRY));
if (!palette) {
SDL_free(bmi);
- GDI_DestroyTexture(renderer, texture);
SDL_OutOfMemory();
return -1;
}
@@ -327,7 +324,6 @@
data->pixels = NULL;
}
if (!data->hbm) {
- GDI_DestroyTexture(renderer, texture);
WIN_SetError("Couldn't create bitmap");
return -1;
}
--- a/test/common.c Sat Jul 22 19:51:48 2006 +0000
+++ b/test/common.c Sat Jul 22 21:02:57 2006 +0000
@@ -55,9 +55,6 @@
if (!argv[index]) {
return -1;
}
- if (SDL_strcasecmp(argv[index], "opengl") == 0) {
- state->window_flags |= SDL_WINDOW_OPENGL;
- }
state->renderdriver = argv[index];
return 2;
}