mirror of
https://github.com/joel16/SDL2.git
synced 2024-12-13 14:07:38 +00:00
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. --HG-- extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%401969
This commit is contained in:
parent
68df2209ba
commit
75ff5f31f2
@ -469,7 +469,8 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags)
|
||||
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;
|
||||
|
@ -72,7 +72,7 @@ SDL_RenderDriver GL_RenderDriver = {
|
||||
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_RenderDriver GL_RenderDriver = {
|
||||
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 @@ typedef struct
|
||||
} 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_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||
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 @@ GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||
GLint internalFormat;
|
||||
GLenum format, type;
|
||||
int texture_w, texture_h;
|
||||
GLenum result;
|
||||
|
||||
switch (texture->format) {
|
||||
case SDL_PixelFormat_Index1LSB:
|
||||
@ -289,8 +326,8 @@ GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||
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 @@ GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||
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 @@ GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||
|
||||
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 @@ GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||
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 @@ GL_GetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture,
|
||||
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 @@ GL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
|
||||
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;
|
||||
|
@ -397,6 +397,7 @@ extern SDL_bool SDL_AddDisplayMode(int displayIndex,
|
||||
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);
|
||||
|
||||
|
@ -833,6 +833,20 @@ SDL_CreateWindowFrom(const void *data)
|
||||
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 @@ SDL_DestroyWindow(SDL_WindowID windowID)
|
||||
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 @@ SDL_CreateTexture(Uint32 format, int access, int w, int h)
|
||||
texture->renderer = renderer;
|
||||
|
||||
if (renderer->CreateTexture(renderer, texture) < 0) {
|
||||
if (renderer->DestroyTexture) {
|
||||
renderer->DestroyTexture(renderer, texture);
|
||||
}
|
||||
SDL_free(texture);
|
||||
return 0;
|
||||
}
|
||||
|
@ -396,7 +396,6 @@ D3D_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||
PixelFormatToD3DFMT(texture->format),
|
||||
pool, &data->texture, NULL);
|
||||
if (FAILED(result)) {
|
||||
SDL_free(data);
|
||||
D3D_SetError("CreateTexture()", result);
|
||||
return -1;
|
||||
}
|
||||
|
@ -249,7 +249,6 @@ GDI_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||
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 @@ GDI_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||
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 @@ GDI_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||
ncolors * sizeof(PALETTEENTRY));
|
||||
if (!palette) {
|
||||
SDL_free(bmi);
|
||||
GDI_DestroyTexture(renderer, texture);
|
||||
SDL_OutOfMemory();
|
||||
return -1;
|
||||
}
|
||||
@ -327,7 +324,6 @@ GDI_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||
data->pixels = NULL;
|
||||
}
|
||||
if (!data->hbm) {
|
||||
GDI_DestroyTexture(renderer, texture);
|
||||
WIN_SetError("Couldn't create bitmap");
|
||||
return -1;
|
||||
}
|
||||
|
@ -55,9 +55,6 @@ CommonArg(CommonState * state, int index)
|
||||
if (!argv[index]) {
|
||||
return -1;
|
||||
}
|
||||
if (SDL_strcasecmp(argv[index], "opengl") == 0) {
|
||||
state->window_flags |= SDL_WINDOW_OPENGL;
|
||||
}
|
||||
state->renderdriver = argv[index];
|
||||
return 2;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user