mirror of
https://github.com/libsdl-org/SDL.git
synced 2025-05-21 04:08:27 +00:00
Implemented more flexible blending modes for accelerated renderers
This fixes bug 2594 - Propose new blend mode, SDL_BLENDMODE_BLEND_DSTA blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_SRC_ALPHA, SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA, SDL_BLENDOPERATION_ADD, SDL_BLENDFACTOR_ZERO, SDL_BLENDFACTOR_ONE, SDL_BLENDOPERATION_ADD); This fixes bug 2828 - Subtractive Blending blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_SRC_ALPHA, SDL_BLENDFACTOR_ONE, SDL_BLENDOPERATION_SUBTRACT, SDL_BLENDFACTOR_ZERO, SDL_BLENDFACTOR_ONE, SDL_BLENDOPERATION_SUBTRACT); This goes partway to fixing bug 3684 - Add support for a pre-multiplied alpha blending mode blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_ONE, SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA, SDL_BLENDOPERATION_ADD, SDL_BLENDFACTOR_ONE, SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA, SDL_BLENDOPERATION_ADD);
This commit is contained in:
parent
f8e1874d01
commit
c59d9923b3
16 changed files with 718 additions and 778 deletions
|
@ -56,6 +56,7 @@ static SDL_Renderer *GLES_CreateRenderer(SDL_Window * window, Uint32 flags);
|
|||
static void GLES_WindowEvent(SDL_Renderer * renderer,
|
||||
const SDL_WindowEvent *event);
|
||||
static int GLES_GetOutputSize(SDL_Renderer * renderer, int *w, int *h);
|
||||
static SDL_bool GLES_SupportsBlendMode(SDL_Renderer * renderer, SDL_BlendMode blendMode);
|
||||
static int GLES_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture);
|
||||
static int GLES_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
|
||||
const SDL_Rect * rect, const void *pixels,
|
||||
|
@ -116,7 +117,7 @@ typedef struct
|
|||
SDL_GLContext context;
|
||||
struct {
|
||||
Uint32 color;
|
||||
int blendMode;
|
||||
SDL_BlendMode blendMode;
|
||||
SDL_bool tex_coords;
|
||||
} current;
|
||||
|
||||
|
@ -130,6 +131,8 @@ typedef struct
|
|||
GLuint window_framebuffer;
|
||||
|
||||
SDL_bool GL_OES_blend_func_separate_supported;
|
||||
SDL_bool GL_OES_blend_equation_separate_supported;
|
||||
SDL_bool GL_OES_blend_subtract_supported;
|
||||
} GLES_RenderData;
|
||||
|
||||
typedef struct
|
||||
|
@ -262,7 +265,7 @@ GLES_ResetState(SDL_Renderer *renderer)
|
|||
}
|
||||
|
||||
data->current.color = 0xffffffff;
|
||||
data->current.blendMode = -1;
|
||||
data->current.blendMode = SDL_BLENDMODE_INVALID;
|
||||
data->current.tex_coords = SDL_FALSE;
|
||||
|
||||
data->glDisable(GL_DEPTH_TEST);
|
||||
|
@ -319,6 +322,7 @@ GLES_CreateRenderer(SDL_Window * window, Uint32 flags)
|
|||
|
||||
renderer->WindowEvent = GLES_WindowEvent;
|
||||
renderer->GetOutputSize = GLES_GetOutputSize;
|
||||
renderer->SupportsBlendMode = GLES_SupportsBlendMode;
|
||||
renderer->CreateTexture = GLES_CreateTexture;
|
||||
renderer->UpdateTexture = GLES_UpdateTexture;
|
||||
renderer->LockTexture = GLES_LockTexture;
|
||||
|
@ -388,6 +392,12 @@ GLES_CreateRenderer(SDL_Window * window, Uint32 flags)
|
|||
if (SDL_GL_ExtensionSupported("GL_OES_blend_func_separate")) {
|
||||
data->GL_OES_blend_func_separate_supported = SDL_TRUE;
|
||||
}
|
||||
if (SDL_GL_ExtensionSupported("GL_OES_blend_equation_separate")) {
|
||||
data->GL_OES_blend_equation_separate_supported = SDL_TRUE;
|
||||
}
|
||||
if (SDL_GL_ExtensionSupported("GL_OES_blend_subtract")) {
|
||||
data->GL_OES_blend_subtract_supported = SDL_TRUE;
|
||||
}
|
||||
|
||||
/* Set up parameters for rendering */
|
||||
GLES_ResetState(renderer);
|
||||
|
@ -430,6 +440,79 @@ GLES_GetOutputSize(SDL_Renderer * renderer, int *w, int *h)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static GLenum GetBlendFunc(SDL_BlendFactor factor)
|
||||
{
|
||||
switch (factor) {
|
||||
case SDL_BLENDFACTOR_ZERO:
|
||||
return GL_ZERO;
|
||||
case SDL_BLENDFACTOR_ONE:
|
||||
return GL_ONE;
|
||||
case SDL_BLENDFACTOR_SRC_COLOR:
|
||||
return GL_SRC_COLOR;
|
||||
case SDL_BLENDFACTOR_ONE_MINUS_SRC_COLOR:
|
||||
return GL_ONE_MINUS_SRC_COLOR;
|
||||
case SDL_BLENDFACTOR_SRC_ALPHA:
|
||||
return GL_SRC_ALPHA;
|
||||
case SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA:
|
||||
return GL_ONE_MINUS_SRC_ALPHA;
|
||||
case SDL_BLENDFACTOR_DST_COLOR:
|
||||
return GL_DST_COLOR;
|
||||
case SDL_BLENDFACTOR_ONE_MINUS_DST_COLOR:
|
||||
return GL_ONE_MINUS_DST_COLOR;
|
||||
case SDL_BLENDFACTOR_DST_ALPHA:
|
||||
return GL_DST_ALPHA;
|
||||
case SDL_BLENDFACTOR_ONE_MINUS_DST_ALPHA:
|
||||
return GL_ONE_MINUS_DST_ALPHA;
|
||||
default:
|
||||
return GL_INVALID_ENUM;
|
||||
}
|
||||
}
|
||||
|
||||
static GLenum GetBlendEquation(SDL_BlendOperation operation)
|
||||
{
|
||||
switch (operation) {
|
||||
case SDL_BLENDOPERATION_ADD:
|
||||
return GL_FUNC_ADD_OES;
|
||||
case SDL_BLENDOPERATION_SUBTRACT:
|
||||
return GL_FUNC_SUBTRACT_OES;
|
||||
case SDL_BLENDOPERATION_REV_SUBTRACT:
|
||||
return GL_FUNC_REVERSE_SUBTRACT_OES;
|
||||
default:
|
||||
return GL_INVALID_ENUM;
|
||||
}
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
GLES_SupportsBlendMode(SDL_Renderer * renderer, SDL_BlendMode blendMode)
|
||||
{
|
||||
GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
|
||||
SDL_BlendFactor srcColorFactor = SDL_GetBlendModeSrcColorFactor(blendMode);
|
||||
SDL_BlendFactor srcAlphaFactor = SDL_GetBlendModeSrcAlphaFactor(blendMode);
|
||||
SDL_BlendOperation colorOperation = SDL_GetBlendModeColorOperation(blendMode);
|
||||
SDL_BlendFactor dstColorFactor = SDL_GetBlendModeDstColorFactor(blendMode);
|
||||
SDL_BlendFactor dstAlphaFactor = SDL_GetBlendModeDstAlphaFactor(blendMode);
|
||||
SDL_BlendOperation alphaOperation = SDL_GetBlendModeAlphaOperation(blendMode);
|
||||
|
||||
if (GetBlendFunc(srcColorFactor) == GL_INVALID_ENUM ||
|
||||
GetBlendFunc(srcAlphaFactor) == GL_INVALID_ENUM ||
|
||||
GetBlendEquation(colorOperation) == GL_INVALID_ENUM ||
|
||||
GetBlendFunc(dstColorFactor) == GL_INVALID_ENUM ||
|
||||
GetBlendFunc(dstAlphaFactor) == GL_INVALID_ENUM ||
|
||||
GetBlendEquation(alphaOperation) == GL_INVALID_ENUM) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
if ((srcColorFactor != srcAlphaFactor || dstColorFactor != dstAlphaFactor) && !data->GL_OES_blend_func_separate_supported) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
if (colorOperation != alphaOperation && !data->GL_OES_blend_equation_separate_supported) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
if (colorOperation != SDL_BLENDOPERATION_ADD && !data->GL_OES_blend_subtract_supported) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
static SDL_INLINE int
|
||||
power_of_2(int input)
|
||||
{
|
||||
|
@ -739,37 +822,28 @@ GLES_SetColor(GLES_RenderData * data, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
|
|||
}
|
||||
|
||||
static void
|
||||
GLES_SetBlendMode(GLES_RenderData * data, int blendMode)
|
||||
GLES_SetBlendMode(GLES_RenderData * data, SDL_BlendMode blendMode)
|
||||
{
|
||||
if (blendMode != data->current.blendMode) {
|
||||
switch (blendMode) {
|
||||
case SDL_BLENDMODE_NONE:
|
||||
if (blendMode == SDL_BLENDMODE_NONE) {
|
||||
data->glDisable(GL_BLEND);
|
||||
break;
|
||||
case SDL_BLENDMODE_BLEND:
|
||||
} else {
|
||||
data->glEnable(GL_BLEND);
|
||||
if (data->GL_OES_blend_func_separate_supported) {
|
||||
data->glBlendFuncSeparateOES(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
data->glBlendFuncSeparateOES(GetBlendFunc(SDL_GetBlendModeSrcColorFactor(blendMode)),
|
||||
GetBlendFunc(SDL_GetBlendModeDstColorFactor(blendMode)),
|
||||
GetBlendFunc(SDL_GetBlendModeSrcAlphaFactor(blendMode)),
|
||||
GetBlendFunc(SDL_GetBlendModeDstAlphaFactor(blendMode)));
|
||||
} else {
|
||||
data->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
data->glBlendFunc(GetBlendFunc(SDL_GetBlendModeSrcColorFactor(blendMode)),
|
||||
GetBlendFunc(SDL_GetBlendModeDstColorFactor(blendMode)));
|
||||
}
|
||||
break;
|
||||
case SDL_BLENDMODE_ADD:
|
||||
data->glEnable(GL_BLEND);
|
||||
if (data->GL_OES_blend_func_separate_supported) {
|
||||
data->glBlendFuncSeparateOES(GL_SRC_ALPHA, GL_ONE, GL_ZERO, GL_ONE);
|
||||
} else {
|
||||
data->glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||
if (data->GL_OES_blend_equation_separate_supported) {
|
||||
data->glBlendEquationSeparateOES(GetBlendEquation(SDL_GetBlendModeColorOperation(blendMode)),
|
||||
GetBlendEquation(SDL_GetBlendModeAlphaOperation(blendMode)));
|
||||
} else if (data->GL_OES_blend_subtract_supported) {
|
||||
data->glBlendEquationOES(GetBlendEquation(SDL_GetBlendModeColorOperation(blendMode)));
|
||||
}
|
||||
break;
|
||||
case SDL_BLENDMODE_MOD:
|
||||
data->glEnable(GL_BLEND);
|
||||
if (data->GL_OES_blend_func_separate_supported) {
|
||||
data->glBlendFuncSeparateOES(GL_ZERO, GL_SRC_COLOR, GL_ZERO, GL_ONE);
|
||||
} else {
|
||||
data->glBlendFunc(GL_ZERO, GL_SRC_COLOR);
|
||||
}
|
||||
break;
|
||||
}
|
||||
data->current.blendMode = blendMode;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue