Handle partial OpenGL shader availability
The pixelart shaders are not supported on OpenGL 2.1 (GLSL 130 isn't available) Fixes the OpenGL renderer on macOS
This commit is contained in:
@@ -91,6 +91,7 @@ typedef struct
|
|||||||
|
|
||||||
bool debug_enabled;
|
bool debug_enabled;
|
||||||
bool GL_ARB_debug_output_supported;
|
bool GL_ARB_debug_output_supported;
|
||||||
|
bool pixelart_supported;
|
||||||
int errors;
|
int errors;
|
||||||
char **error_messages;
|
char **error_messages;
|
||||||
GLDEBUGPROCARB next_error_callback;
|
GLDEBUGPROCARB next_error_callback;
|
||||||
@@ -455,7 +456,13 @@ static bool SetTextureScaleMode(GL_RenderData *data, GLenum textype, SDL_PixelFo
|
|||||||
data->glTexParameteri(textype, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
data->glTexParameteri(textype, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
data->glTexParameteri(textype, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
data->glTexParameteri(textype, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
break;
|
break;
|
||||||
case SDL_SCALEMODE_PIXELART: // Uses linear sampling
|
case SDL_SCALEMODE_PIXELART: // Uses linear sampling if supported
|
||||||
|
if (!data->pixelart_supported) {
|
||||||
|
data->glTexParameteri(textype, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
data->glTexParameteri(textype, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
SDL_FALLTHROUGH;
|
||||||
case SDL_SCALEMODE_LINEAR:
|
case SDL_SCALEMODE_LINEAR:
|
||||||
if (format == SDL_PIXELFORMAT_INDEX8) {
|
if (format == SDL_PIXELFORMAT_INDEX8) {
|
||||||
// We'll do linear sampling in the shader
|
// We'll do linear sampling in the shader
|
||||||
@@ -1210,19 +1217,22 @@ static bool SetCopyState(GL_RenderData *data, const SDL_RenderCommand *cmd)
|
|||||||
if (cmd->data.draw.texture_scale_mode == SDL_SCALEMODE_LINEAR) {
|
if (cmd->data.draw.texture_scale_mode == SDL_SCALEMODE_LINEAR) {
|
||||||
shader = SHADER_PALETTE_LINEAR;
|
shader = SHADER_PALETTE_LINEAR;
|
||||||
shader_params = texturedata->texel_size;
|
shader_params = texturedata->texel_size;
|
||||||
} else if (cmd->data.draw.texture_scale_mode == SDL_SCALEMODE_PIXELART) {
|
} else if (cmd->data.draw.texture_scale_mode == SDL_SCALEMODE_PIXELART &&
|
||||||
|
data->pixelart_supported) {
|
||||||
shader = SHADER_PALETTE_PIXELART;
|
shader = SHADER_PALETTE_PIXELART;
|
||||||
shader_params = texturedata->texel_size;
|
shader_params = texturedata->texel_size;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SHADER_RGB:
|
case SHADER_RGB:
|
||||||
if (cmd->data.draw.texture_scale_mode == SDL_SCALEMODE_PIXELART) {
|
if (cmd->data.draw.texture_scale_mode == SDL_SCALEMODE_PIXELART &&
|
||||||
|
data->pixelart_supported) {
|
||||||
shader = SHADER_RGB_PIXELART;
|
shader = SHADER_RGB_PIXELART;
|
||||||
shader_params = texturedata->texel_size;
|
shader_params = texturedata->texel_size;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SHADER_RGBA:
|
case SHADER_RGBA:
|
||||||
if (cmd->data.draw.texture_scale_mode == SDL_SCALEMODE_PIXELART) {
|
if (cmd->data.draw.texture_scale_mode == SDL_SCALEMODE_PIXELART &&
|
||||||
|
data->pixelart_supported) {
|
||||||
shader = SHADER_RGBA_PIXELART;
|
shader = SHADER_RGBA_PIXELART;
|
||||||
shader_params = texturedata->texel_size;
|
shader_params = texturedata->texel_size;
|
||||||
}
|
}
|
||||||
@@ -1928,27 +1938,50 @@ static bool GL_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, SDL_Pr
|
|||||||
data->shaders = GL_CreateShaderContext();
|
data->shaders = GL_CreateShaderContext();
|
||||||
SDL_LogInfo(SDL_LOG_CATEGORY_RENDER, "OpenGL shaders: %s",
|
SDL_LogInfo(SDL_LOG_CATEGORY_RENDER, "OpenGL shaders: %s",
|
||||||
data->shaders ? "ENABLED" : "DISABLED");
|
data->shaders ? "ENABLED" : "DISABLED");
|
||||||
if (data->shaders) {
|
if (GL_SupportsShader(data->shaders, SHADER_RGB)) {
|
||||||
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_RGBX32);
|
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_RGBX32);
|
||||||
if (bgra_supported) {
|
if (bgra_supported) {
|
||||||
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_BGRX32);
|
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_BGRX32);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
SDL_LogInfo(SDL_LOG_CATEGORY_RENDER, "OpenGL RGB shaders not supported");
|
||||||
|
}
|
||||||
|
// We support PIXELART mode using a shader
|
||||||
|
if (GL_SupportsShader(data->shaders, SHADER_RGB_PIXELART) &&
|
||||||
|
GL_SupportsShader(data->shaders, SHADER_RGBA_PIXELART)) {
|
||||||
|
data->pixelart_supported = true;
|
||||||
|
} else {
|
||||||
|
SDL_LogInfo(SDL_LOG_CATEGORY_RENDER, "OpenGL PIXELART shaders not supported");
|
||||||
}
|
}
|
||||||
// We support INDEX8 textures using 2 textures and a shader
|
// We support INDEX8 textures using 2 textures and a shader
|
||||||
if (data->shaders && data->num_texture_units >= 2) {
|
if (GL_SupportsShader(data->shaders, SHADER_PALETTE_NEAREST) &&
|
||||||
|
GL_SupportsShader(data->shaders, SHADER_PALETTE_LINEAR) &&
|
||||||
|
(!data->pixelart_supported || GL_SupportsShader(data->shaders, SHADER_PALETTE_PIXELART)) &&
|
||||||
|
data->num_texture_units >= 2) {
|
||||||
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_INDEX8);
|
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_INDEX8);
|
||||||
|
} else {
|
||||||
|
SDL_LogInfo(SDL_LOG_CATEGORY_RENDER, "OpenGL palette shaders not supported");
|
||||||
}
|
}
|
||||||
#ifdef SDL_HAVE_YUV
|
#ifdef SDL_HAVE_YUV
|
||||||
// We support YV12 textures using 3 textures and a shader
|
// We support YV12 textures using 3 textures and a shader
|
||||||
if (data->shaders && data->num_texture_units >= 3) {
|
if (GL_SupportsShader(data->shaders, SHADER_YUV) &&
|
||||||
|
data->num_texture_units >= 3) {
|
||||||
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_YV12);
|
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_YV12);
|
||||||
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_IYUV);
|
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_IYUV);
|
||||||
|
} else {
|
||||||
|
SDL_LogInfo(SDL_LOG_CATEGORY_RENDER, "OpenGL YUV not supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
// We support NV12 textures using 2 textures and a shader
|
// We support NV12 textures using 2 textures and a shader
|
||||||
if (data->shaders && data->num_texture_units >= 2) {
|
if (GL_SupportsShader(data->shaders, SHADER_NV12_RA) &&
|
||||||
|
GL_SupportsShader(data->shaders, SHADER_NV12_RG) &&
|
||||||
|
GL_SupportsShader(data->shaders, SHADER_NV21_RA) &&
|
||||||
|
GL_SupportsShader(data->shaders, SHADER_NV21_RG) &&
|
||||||
|
data->num_texture_units >= 2) {
|
||||||
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_NV12);
|
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_NV12);
|
||||||
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_NV21);
|
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_NV21);
|
||||||
|
} else {
|
||||||
|
SDL_LogInfo(SDL_LOG_CATEGORY_RENDER, "OpenGL NV12/NV21 not supported");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef SDL_PLATFORM_MACOS
|
#ifdef SDL_PLATFORM_MACOS
|
||||||
|
|||||||
@@ -520,10 +520,15 @@ static bool CompileShader(GL_ShaderContext *ctx, GLhandleARB shader, const char
|
|||||||
info = SDL_small_alloc(char, length + 1, &isstack);
|
info = SDL_small_alloc(char, length + 1, &isstack);
|
||||||
if (info) {
|
if (info) {
|
||||||
ctx->glGetInfoLogARB(shader, length, NULL, info);
|
ctx->glGetInfoLogARB(shader, length, NULL, info);
|
||||||
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "Failed to compile shader:");
|
SDL_LogDebug(SDL_LOG_CATEGORY_RENDER, "Failed to compile shader:");
|
||||||
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "%s", defines);
|
if (version) {
|
||||||
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "%s", source);
|
SDL_LogDebug(SDL_LOG_CATEGORY_RENDER, "%s", version);
|
||||||
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "%s", info);
|
}
|
||||||
|
if (defines) {
|
||||||
|
SDL_LogDebug(SDL_LOG_CATEGORY_RENDER, "%s", defines);
|
||||||
|
}
|
||||||
|
SDL_LogDebug(SDL_LOG_CATEGORY_RENDER, "%s", source);
|
||||||
|
SDL_LogDebug(SDL_LOG_CATEGORY_RENDER, "%s", info);
|
||||||
SDL_small_free(info, isstack);
|
SDL_small_free(info, isstack);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -598,9 +603,18 @@ static bool CompileShaderProgram(GL_ShaderContext *ctx, int index, GL_ShaderData
|
|||||||
|
|
||||||
static void DestroyShaderProgram(GL_ShaderContext *ctx, GL_ShaderData *data)
|
static void DestroyShaderProgram(GL_ShaderContext *ctx, GL_ShaderData *data)
|
||||||
{
|
{
|
||||||
ctx->glDeleteObjectARB(data->vert_shader);
|
if (data->vert_shader) {
|
||||||
ctx->glDeleteObjectARB(data->frag_shader);
|
ctx->glDeleteObjectARB(data->vert_shader);
|
||||||
ctx->glDeleteObjectARB(data->program);
|
data->vert_shader = 0;
|
||||||
|
}
|
||||||
|
if (data->frag_shader) {
|
||||||
|
ctx->glDeleteObjectARB(data->frag_shader);
|
||||||
|
data->frag_shader = 0;
|
||||||
|
}
|
||||||
|
if (data->program) {
|
||||||
|
ctx->glDeleteObjectARB(data->program);
|
||||||
|
data->program = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GL_ShaderContext *GL_CreateShaderContext(void)
|
GL_ShaderContext *GL_CreateShaderContext(void)
|
||||||
@@ -669,8 +683,7 @@ GL_ShaderContext *GL_CreateShaderContext(void)
|
|||||||
// Compile all the shaders
|
// Compile all the shaders
|
||||||
for (i = 0; i < NUM_SHADERS; ++i) {
|
for (i = 0; i < NUM_SHADERS; ++i) {
|
||||||
if (!CompileShaderProgram(ctx, i, &ctx->shaders[i])) {
|
if (!CompileShaderProgram(ctx, i, &ctx->shaders[i])) {
|
||||||
GL_DestroyShaderContext(ctx);
|
DestroyShaderProgram(ctx, &ctx->shaders[i]);
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -678,6 +691,11 @@ GL_ShaderContext *GL_CreateShaderContext(void)
|
|||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool GL_SupportsShader(GL_ShaderContext *ctx, GL_Shader shader)
|
||||||
|
{
|
||||||
|
return ctx && ctx->shaders[shader].program;
|
||||||
|
}
|
||||||
|
|
||||||
void GL_SelectShader(GL_ShaderContext *ctx, GL_Shader shader, const float *shader_params)
|
void GL_SelectShader(GL_ShaderContext *ctx, GL_Shader shader, const float *shader_params)
|
||||||
{
|
{
|
||||||
GLint location;
|
GLint location;
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ typedef enum
|
|||||||
typedef struct GL_ShaderContext GL_ShaderContext;
|
typedef struct GL_ShaderContext GL_ShaderContext;
|
||||||
|
|
||||||
extern GL_ShaderContext *GL_CreateShaderContext(void);
|
extern GL_ShaderContext *GL_CreateShaderContext(void);
|
||||||
|
extern bool GL_SupportsShader(GL_ShaderContext *ctx, GL_Shader shader);
|
||||||
extern void GL_SelectShader(GL_ShaderContext *ctx, GL_Shader shader, const float *shader_params);
|
extern void GL_SelectShader(GL_ShaderContext *ctx, GL_Shader shader, const float *shader_params);
|
||||||
extern void GL_DestroyShaderContext(GL_ShaderContext *ctx);
|
extern void GL_DestroyShaderContext(GL_ShaderContext *ctx);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user