Make texture scale mode a part of the 2D renderer draw state
Also added texture addressing mode support to the PSP and Vita renderers (untested) Fixes https://github.com/libsdl-org/SDL/issues/12461
This commit is contained in:
parent
6e2d3c9b5d
commit
cb099ebd4f
19 changed files with 477 additions and 302 deletions
|
@ -137,7 +137,6 @@ typedef struct
|
|||
void *pixels;
|
||||
int pitch;
|
||||
SDL_Rect locked_rect;
|
||||
|
||||
#ifdef SDL_HAVE_YUV
|
||||
// YUV texture support
|
||||
bool yuv;
|
||||
|
@ -147,7 +146,8 @@ typedef struct
|
|||
GLuint vtexture;
|
||||
bool vtexture_external;
|
||||
#endif
|
||||
|
||||
SDL_ScaleMode texture_scale_mode;
|
||||
SDL_TextureAddressMode texture_address_mode;
|
||||
GL_FBOList *fbo;
|
||||
} GL_TextureData;
|
||||
|
||||
|
@ -447,7 +447,6 @@ static bool GL_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL_P
|
|||
GLint internalFormat;
|
||||
GLenum format, type;
|
||||
int texture_w, texture_h;
|
||||
GLenum scaleMode;
|
||||
|
||||
GL_ActivateRenderer(renderer);
|
||||
|
||||
|
@ -536,11 +535,10 @@ static bool GL_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL_P
|
|||
|
||||
data->format = format;
|
||||
data->formattype = type;
|
||||
scaleMode = (texture->scaleMode == SDL_SCALEMODE_NEAREST) ? GL_NEAREST : GL_LINEAR;
|
||||
data->texture_scale_mode = SDL_SCALEMODE_INVALID;
|
||||
data->texture_address_mode = SDL_TEXTURE_ADDRESS_INVALID;
|
||||
renderdata->glEnable(textype);
|
||||
renderdata->glBindTexture(textype, data->texture);
|
||||
renderdata->glTexParameteri(textype, GL_TEXTURE_MIN_FILTER, scaleMode);
|
||||
renderdata->glTexParameteri(textype, GL_TEXTURE_MAG_FILTER, scaleMode);
|
||||
#ifdef SDL_PLATFORM_MACOS
|
||||
#ifndef GL_TEXTURE_STORAGE_HINT_APPLE
|
||||
#define GL_TEXTURE_STORAGE_HINT_APPLE 0x85BC
|
||||
|
@ -596,19 +594,11 @@ static bool GL_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL_P
|
|||
}
|
||||
|
||||
renderdata->glBindTexture(textype, data->utexture);
|
||||
renderdata->glTexParameteri(textype, GL_TEXTURE_MIN_FILTER,
|
||||
scaleMode);
|
||||
renderdata->glTexParameteri(textype, GL_TEXTURE_MAG_FILTER,
|
||||
scaleMode);
|
||||
renderdata->glTexImage2D(textype, 0, internalFormat, (texture_w + 1) / 2,
|
||||
(texture_h + 1) / 2, 0, format, type, NULL);
|
||||
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_OPENGL_TEXTURE_U_NUMBER, data->utexture);
|
||||
|
||||
renderdata->glBindTexture(textype, data->vtexture);
|
||||
renderdata->glTexParameteri(textype, GL_TEXTURE_MIN_FILTER,
|
||||
scaleMode);
|
||||
renderdata->glTexParameteri(textype, GL_TEXTURE_MAG_FILTER,
|
||||
scaleMode);
|
||||
renderdata->glTexImage2D(textype, 0, internalFormat, (texture_w + 1) / 2,
|
||||
(texture_h + 1) / 2, 0, format, type, NULL);
|
||||
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_OPENGL_TEXTURE_V_NUMBER, data->vtexture);
|
||||
|
@ -625,10 +615,6 @@ static bool GL_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL_P
|
|||
renderdata->glGenTextures(1, &data->utexture);
|
||||
}
|
||||
renderdata->glBindTexture(textype, data->utexture);
|
||||
renderdata->glTexParameteri(textype, GL_TEXTURE_MIN_FILTER,
|
||||
scaleMode);
|
||||
renderdata->glTexParameteri(textype, GL_TEXTURE_MAG_FILTER,
|
||||
scaleMode);
|
||||
renderdata->glTexImage2D(textype, 0, GL_LUMINANCE_ALPHA, (texture_w + 1) / 2,
|
||||
(texture_h + 1) / 2, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, NULL);
|
||||
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_OPENGL_TEXTURE_UV_NUMBER, data->utexture);
|
||||
|
@ -822,38 +808,6 @@ static void GL_UnlockTexture(SDL_Renderer *renderer, SDL_Texture *texture)
|
|||
GL_UpdateTexture(renderer, texture, rect, pixels, data->pitch);
|
||||
}
|
||||
|
||||
static void GL_SetTextureScaleMode(SDL_Renderer *renderer, SDL_Texture *texture, SDL_ScaleMode scaleMode)
|
||||
{
|
||||
GL_RenderData *renderdata = (GL_RenderData *)renderer->internal;
|
||||
const GLenum textype = renderdata->textype;
|
||||
GL_TextureData *data = (GL_TextureData *)texture->internal;
|
||||
GLenum glScaleMode = (scaleMode == SDL_SCALEMODE_NEAREST) ? GL_NEAREST : GL_LINEAR;
|
||||
|
||||
renderdata->glBindTexture(textype, data->texture);
|
||||
renderdata->glTexParameteri(textype, GL_TEXTURE_MIN_FILTER, glScaleMode);
|
||||
renderdata->glTexParameteri(textype, GL_TEXTURE_MAG_FILTER, glScaleMode);
|
||||
|
||||
#ifdef SDL_HAVE_YUV
|
||||
if (texture->format == SDL_PIXELFORMAT_YV12 ||
|
||||
texture->format == SDL_PIXELFORMAT_IYUV) {
|
||||
renderdata->glBindTexture(textype, data->utexture);
|
||||
renderdata->glTexParameteri(textype, GL_TEXTURE_MIN_FILTER, glScaleMode);
|
||||
renderdata->glTexParameteri(textype, GL_TEXTURE_MAG_FILTER, glScaleMode);
|
||||
|
||||
renderdata->glBindTexture(textype, data->vtexture);
|
||||
renderdata->glTexParameteri(textype, GL_TEXTURE_MIN_FILTER, glScaleMode);
|
||||
renderdata->glTexParameteri(textype, GL_TEXTURE_MAG_FILTER, glScaleMode);
|
||||
}
|
||||
|
||||
if (texture->format == SDL_PIXELFORMAT_NV12 ||
|
||||
texture->format == SDL_PIXELFORMAT_NV21) {
|
||||
renderdata->glBindTexture(textype, data->utexture);
|
||||
renderdata->glTexParameteri(textype, GL_TEXTURE_MIN_FILTER, glScaleMode);
|
||||
renderdata->glTexParameteri(textype, GL_TEXTURE_MAG_FILTER, glScaleMode);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool GL_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture)
|
||||
{
|
||||
GL_RenderData *data = (GL_RenderData *)renderer->internal;
|
||||
|
@ -1120,6 +1074,23 @@ static bool SetDrawState(GL_RenderData *data, const SDL_RenderCommand *cmd, cons
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool SetTextureScaleMode(GL_RenderData *data, GLenum textype, SDL_ScaleMode scaleMode)
|
||||
{
|
||||
switch (scaleMode) {
|
||||
case SDL_SCALEMODE_NEAREST:
|
||||
data->glTexParameteri(textype, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
data->glTexParameteri(textype, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
break;
|
||||
case SDL_SCALEMODE_LINEAR:
|
||||
data->glTexParameteri(textype, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
data->glTexParameteri(textype, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
break;
|
||||
default:
|
||||
return SDL_SetError("Unknown texture scale mode: %d", scaleMode);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool SetTextureAddressMode(GL_RenderData *data, GLenum textype, SDL_TextureAddressMode addressMode)
|
||||
{
|
||||
switch (addressMode) {
|
||||
|
@ -1140,41 +1111,23 @@ static bool SetTextureAddressMode(GL_RenderData *data, GLenum textype, SDL_Textu
|
|||
static bool SetCopyState(GL_RenderData *data, const SDL_RenderCommand *cmd)
|
||||
{
|
||||
SDL_Texture *texture = cmd->data.draw.texture;
|
||||
const GL_TextureData *texturedata = (GL_TextureData *)texture->internal;
|
||||
GL_TextureData *texturedata = (GL_TextureData *)texture->internal;
|
||||
const GLenum textype = data->textype;
|
||||
|
||||
SetDrawState(data, cmd, texturedata->shader, texturedata->shader_params);
|
||||
|
||||
if (texture != data->drawstate.texture) {
|
||||
const GLenum textype = data->textype;
|
||||
#ifdef SDL_HAVE_YUV
|
||||
if (texturedata->yuv) {
|
||||
if (data->GL_ARB_multitexture_supported) {
|
||||
data->glActiveTextureARB(GL_TEXTURE2_ARB);
|
||||
}
|
||||
data->glActiveTextureARB(GL_TEXTURE2_ARB);
|
||||
data->glBindTexture(textype, texturedata->vtexture);
|
||||
|
||||
if (!SetTextureAddressMode(data, textype, cmd->data.draw.texture_address_mode)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (data->GL_ARB_multitexture_supported) {
|
||||
data->glActiveTextureARB(GL_TEXTURE1_ARB);
|
||||
}
|
||||
data->glActiveTextureARB(GL_TEXTURE1_ARB);
|
||||
data->glBindTexture(textype, texturedata->utexture);
|
||||
|
||||
if (!SetTextureAddressMode(data, textype, cmd->data.draw.texture_address_mode)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (texturedata->nv12) {
|
||||
if (data->GL_ARB_multitexture_supported) {
|
||||
data->glActiveTextureARB(GL_TEXTURE1_ARB);
|
||||
}
|
||||
data->glActiveTextureARB(GL_TEXTURE1_ARB);
|
||||
data->glBindTexture(textype, texturedata->utexture);
|
||||
|
||||
if (!SetTextureAddressMode(data, textype, cmd->data.draw.texture_address_mode)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (data->GL_ARB_multitexture_supported) {
|
||||
|
@ -1182,11 +1135,67 @@ static bool SetCopyState(GL_RenderData *data, const SDL_RenderCommand *cmd)
|
|||
}
|
||||
data->glBindTexture(textype, texturedata->texture);
|
||||
|
||||
data->drawstate.texture = texture;
|
||||
}
|
||||
|
||||
if (cmd->data.draw.texture_scale_mode != texturedata->texture_scale_mode) {
|
||||
#ifdef SDL_HAVE_YUV
|
||||
if (texturedata->yuv) {
|
||||
data->glActiveTextureARB(GL_TEXTURE2);
|
||||
if (!SetTextureScaleMode(data, textype, cmd->data.draw.texture_scale_mode)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
data->glActiveTextureARB(GL_TEXTURE1);
|
||||
if (!SetTextureScaleMode(data, textype, cmd->data.draw.texture_scale_mode)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
data->glActiveTextureARB(GL_TEXTURE0);
|
||||
} else if (texturedata->nv12) {
|
||||
data->glActiveTextureARB(GL_TEXTURE1);
|
||||
if (!SetTextureScaleMode(data, textype, cmd->data.draw.texture_scale_mode)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
data->glActiveTextureARB(GL_TEXTURE0);
|
||||
}
|
||||
#endif
|
||||
if (!SetTextureScaleMode(data, textype, cmd->data.draw.texture_scale_mode)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
texturedata->texture_scale_mode = cmd->data.draw.texture_scale_mode;
|
||||
}
|
||||
|
||||
if (cmd->data.draw.texture_address_mode != texturedata->texture_address_mode) {
|
||||
#ifdef SDL_HAVE_YUV
|
||||
if (texturedata->yuv) {
|
||||
data->glActiveTextureARB(GL_TEXTURE2);
|
||||
if (!SetTextureAddressMode(data, textype, cmd->data.draw.texture_address_mode)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
data->glActiveTextureARB(GL_TEXTURE1);
|
||||
if (!SetTextureAddressMode(data, textype, cmd->data.draw.texture_address_mode)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
data->glActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
} else if (texturedata->nv12) {
|
||||
data->glActiveTextureARB(GL_TEXTURE1);
|
||||
if (!SetTextureAddressMode(data, textype, cmd->data.draw.texture_address_mode)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
data->glActiveTextureARB(GL_TEXTURE0);
|
||||
}
|
||||
#endif
|
||||
if (!SetTextureAddressMode(data, textype, cmd->data.draw.texture_address_mode)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
data->drawstate.texture = texture;
|
||||
texturedata->texture_address_mode = cmd->data.draw.texture_address_mode;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -1372,6 +1381,8 @@ static bool GL_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
|
|||
same texture, we can combine them all into a single draw call. */
|
||||
SDL_Texture *thistexture = cmd->data.draw.texture;
|
||||
SDL_BlendMode thisblend = cmd->data.draw.blend;
|
||||
SDL_ScaleMode thisscalemode = cmd->data.draw.texture_scale_mode;
|
||||
SDL_TextureAddressMode thisaddressmode = cmd->data.draw.texture_address_mode;
|
||||
const SDL_RenderCommandType thiscmdtype = cmd->command;
|
||||
SDL_RenderCommand *finalcmd = cmd;
|
||||
SDL_RenderCommand *nextcmd = cmd->next;
|
||||
|
@ -1381,7 +1392,10 @@ static bool GL_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
|
|||
const SDL_RenderCommandType nextcmdtype = nextcmd->command;
|
||||
if (nextcmdtype != thiscmdtype) {
|
||||
break; // can't go any further on this draw call, different render command up next.
|
||||
} else if (nextcmd->data.draw.texture != thistexture || nextcmd->data.draw.blend != thisblend) {
|
||||
} else if (nextcmd->data.draw.texture != thistexture ||
|
||||
nextcmd->data.draw.texture_scale_mode != thisscalemode ||
|
||||
nextcmd->data.draw.texture_address_mode != thisaddressmode ||
|
||||
nextcmd->data.draw.blend != thisblend) {
|
||||
break; // can't go any further on this draw call, different texture/blendmode copy up next.
|
||||
} else {
|
||||
finalcmd = nextcmd; // we can combine copy operations here. Mark this one as the furthest okay command.
|
||||
|
@ -1656,7 +1670,6 @@ static bool GL_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, SDL_Pr
|
|||
#endif
|
||||
renderer->LockTexture = GL_LockTexture;
|
||||
renderer->UnlockTexture = GL_UnlockTexture;
|
||||
renderer->SetTextureScaleMode = GL_SetTextureScaleMode;
|
||||
renderer->SetRenderTarget = GL_SetRenderTarget;
|
||||
renderer->QueueSetViewport = GL_QueueNoOp;
|
||||
renderer->QueueSetDrawColor = GL_QueueNoOp;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue