Skip to content

Commit bb5bd00

Browse files
committed
opengles2: Add support for paletted textures
1 parent 8aba47a commit bb5bd00

File tree

3 files changed

+96
-5
lines changed

3 files changed

+96
-5
lines changed

src/render/opengles2/SDL_render_gles2.c

Lines changed: 76 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ typedef struct GLES2_TextureData
7474
GLuint texture_v;
7575
GLuint texture_u;
7676
#endif
77+
SDL_bool palette;
78+
GLenum texture_p;
7779
GLES2_FBOList *fbo;
7880
} GLES2_TextureData;
7981

@@ -106,6 +108,7 @@ typedef enum
106108
{
107109
GLES2_UNIFORM_PROJECTION,
108110
GLES2_UNIFORM_TEXTURE,
111+
GLES2_UNIFORM_TEXTURE_P,
109112
GLES2_UNIFORM_TEXTURE_U,
110113
GLES2_UNIFORM_TEXTURE_V
111114
} GLES2_Uniform;
@@ -118,6 +121,7 @@ typedef enum
118121
GLES2_IMAGESOURCE_TEXTURE_ARGB,
119122
GLES2_IMAGESOURCE_TEXTURE_RGB,
120123
GLES2_IMAGESOURCE_TEXTURE_BGR,
124+
GLES2_IMAGESOURCE_TEXTURE_PALETTE,
121125
GLES2_IMAGESOURCE_TEXTURE_YUV,
122126
GLES2_IMAGESOURCE_TEXTURE_NV12,
123127
GLES2_IMAGESOURCE_TEXTURE_NV21,
@@ -457,6 +461,8 @@ static GLES2_ProgramCacheEntry *GLES2_CacheProgram(GLES2_RenderData *data, GLuin
457461
data->glGetUniformLocation(entry->id, "u_texture_v");
458462
entry->uniform_locations[GLES2_UNIFORM_TEXTURE_U] =
459463
data->glGetUniformLocation(entry->id, "u_texture_u");
464+
entry->uniform_locations[GLES2_UNIFORM_TEXTURE_P] =
465+
data->glGetUniformLocation(entry->id, "u_texture_p");
460466
entry->uniform_locations[GLES2_UNIFORM_TEXTURE] =
461467
data->glGetUniformLocation(entry->id, "u_texture");
462468

@@ -467,6 +473,9 @@ static GLES2_ProgramCacheEntry *GLES2_CacheProgram(GLES2_RenderData *data, GLuin
467473
if (entry->uniform_locations[GLES2_UNIFORM_TEXTURE_U] != -1) {
468474
data->glUniform1i(entry->uniform_locations[GLES2_UNIFORM_TEXTURE_U], 1); /* always texture unit 1. */
469475
}
476+
if (entry->uniform_locations[GLES2_UNIFORM_TEXTURE_P] != -1) {
477+
data->glUniform1i(entry->uniform_locations[GLES2_UNIFORM_TEXTURE_P], 1); /* always texture unit 1. */
478+
}
470479
if (entry->uniform_locations[GLES2_UNIFORM_TEXTURE] != -1) {
471480
data->glUniform1i(entry->uniform_locations[GLES2_UNIFORM_TEXTURE], 0); /* always texture unit 0. */
472481
}
@@ -624,6 +633,9 @@ static int GLES2_SelectProgram(GLES2_RenderData *data, GLES2_ImageSource source,
624633
case GLES2_IMAGESOURCE_TEXTURE_BGR:
625634
ftype = GLES2_SHADER_FRAGMENT_TEXTURE_BGR;
626635
break;
636+
case GLES2_IMAGESOURCE_TEXTURE_PALETTE:
637+
ftype = GLES2_SHADER_FRAGMENT_TEXTURE_PALETTE;
638+
break;
627639
#if SDL_HAVE_YUV
628640
case GLES2_IMAGESOURCE_TEXTURE_YUV:
629641
switch (SDL_GetYUVConversionModeForResolution(w, h)) {
@@ -1077,6 +1089,9 @@ static int SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, vo
10771089
break;
10781090
}
10791091
break;
1092+
case SDL_PIXELFORMAT_INDEX8:
1093+
sourceType = GLES2_IMAGESOURCE_TEXTURE_PALETTE;
1094+
break;
10801095
#if SDL_HAVE_YUV
10811096
case SDL_PIXELFORMAT_IYUV:
10821097
case SDL_PIXELFORMAT_YV12:
@@ -1112,6 +1127,9 @@ static int SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, vo
11121127
case SDL_PIXELFORMAT_BGR888:
11131128
sourceType = GLES2_IMAGESOURCE_TEXTURE_BGR;
11141129
break;
1130+
case SDL_PIXELFORMAT_INDEX8:
1131+
sourceType = GLES2_IMAGESOURCE_TEXTURE_PALETTE;
1132+
break;
11151133
#if SDL_HAVE_YUV
11161134
case SDL_PIXELFORMAT_IYUV:
11171135
case SDL_PIXELFORMAT_YV12:
@@ -1150,8 +1168,14 @@ static int SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, vo
11501168
data->glBindTexture(tdata->texture_type, tdata->texture_u);
11511169

11521170
data->glActiveTexture(GL_TEXTURE0);
1153-
}
1171+
} else
11541172
#endif
1173+
if (tdata->palette) {
1174+
data->glActiveTexture(GL_TEXTURE1);
1175+
data->glBindTexture(tdata->texture_type, tdata->texture_p);
1176+
1177+
data->glActiveTexture(GL_TEXTURE0);
1178+
}
11551179
data->glBindTexture(tdata->texture_type, tdata->texture);
11561180
data->drawstate.texture = texture;
11571181
}
@@ -1434,10 +1458,11 @@ static int GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture)
14341458
case SDL_PIXELFORMAT_YV12:
14351459
case SDL_PIXELFORMAT_NV12:
14361460
case SDL_PIXELFORMAT_NV21:
1461+
#endif
1462+
case SDL_PIXELFORMAT_INDEX8:
14371463
format = GL_LUMINANCE;
14381464
type = GL_UNSIGNED_BYTE;
14391465
break;
1440-
#endif
14411466
#ifdef GL_TEXTURE_EXTERNAL_OES
14421467
case SDL_PIXELFORMAT_EXTERNAL_OES:
14431468
format = GL_NONE;
@@ -1472,6 +1497,8 @@ static int GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture)
14721497
data->texture_u = 0;
14731498
data->texture_v = 0;
14741499
#endif
1500+
data->palette = (texture->format == SDL_PIXELFORMAT_INDEX8);
1501+
data->texture_p = 0;
14751502
scaleMode = (texture->scaleMode == SDL_ScaleModeNearest) ? GL_NEAREST : GL_LINEAR;
14761503

14771504
/* Allocate a blob for image renderdata */
@@ -1541,8 +1568,24 @@ static int GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture)
15411568
if (GL_CheckError("glTexImage2D()", renderer) < 0) {
15421569
return -1;
15431570
}
1544-
}
1571+
} else
15451572
#endif
1573+
if (data->palette) {
1574+
renderdata->glGenTextures(1, &data->texture_p);
1575+
if (GL_CheckError("glGenTexures()", renderer) < 0) {
1576+
return -1;
1577+
}
1578+
renderdata->glActiveTexture(GL_TEXTURE1);
1579+
renderdata->glBindTexture(data->texture_type, data->texture_p);
1580+
renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_MIN_FILTER, scaleMode);
1581+
renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_MAG_FILTER, scaleMode);
1582+
renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1583+
renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1584+
renderdata->glTexImage2D(data->texture_type, 0, GL_RGBA, 256, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
1585+
if (GL_CheckError("glTexImage2D()", renderer) < 0) {
1586+
return -1;
1587+
}
1588+
}
15461589

15471590
renderdata->glGenTextures(1, &data->texture);
15481591
if (GL_CheckError("glGenTexures()", renderer) < 0) {
@@ -1802,6 +1845,22 @@ static int GLES2_UpdateTextureNV(SDL_Renderer *renderer, SDL_Texture *texture,
18021845
}
18031846
#endif
18041847

1848+
static int GLES2_SetTexturePalette(SDL_Renderer *renderer, SDL_Texture *texture,
1849+
const SDL_Color *colors, int firstcolor, int ncolors)
1850+
{
1851+
GLES2_RenderData *data = (GLES2_RenderData *)renderer->driverdata;
1852+
GLES2_TextureData *tdata = (GLES2_TextureData *)texture->driverdata;
1853+
1854+
GLES2_ActivateRenderer(renderer);
1855+
1856+
data->drawstate.texture = NULL; /* we trash this state. */
1857+
1858+
data->glBindTexture(tdata->texture_type, tdata->texture_p);
1859+
data->glTexSubImage2D(tdata->texture_type, 0, firstcolor, 0, ncolors, 1, GL_RGBA, GL_UNSIGNED_BYTE, colors);
1860+
1861+
return GL_CheckError("glTexSubImage2D()", renderer);
1862+
}
1863+
18051864
static int GLES2_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect,
18061865
void **pixels, int *pitch)
18071866
{
@@ -1854,6 +1913,13 @@ static void GLES2_SetTextureScaleMode(SDL_Renderer *renderer, SDL_Texture *textu
18541913
}
18551914
#endif
18561915

1916+
if (data->palette) {
1917+
renderdata->glActiveTexture(GL_TEXTURE1);
1918+
renderdata->glBindTexture(data->texture_type, data->texture_p);
1919+
renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_MIN_FILTER, glScaleMode);
1920+
renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_MAG_FILTER, glScaleMode);
1921+
}
1922+
18571923
renderdata->glActiveTexture(GL_TEXTURE0);
18581924
renderdata->glBindTexture(data->texture_type, data->texture);
18591925
renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_MIN_FILTER, glScaleMode);
@@ -1909,6 +1975,9 @@ static void GLES2_DestroyTexture(SDL_Renderer *renderer, SDL_Texture *texture)
19091975
data->glDeleteTextures(1, &tdata->texture_u);
19101976
}
19111977
#endif
1978+
if (tdata->texture_p) {
1979+
data->glDeleteTextures(1, &tdata->texture_p);
1980+
}
19121981
SDL_free(tdata->pixel_data);
19131982
SDL_free(tdata);
19141983
texture->driverdata = NULL;
@@ -2186,6 +2255,7 @@ static SDL_Renderer *GLES2_CreateRenderer(SDL_Window *window, Uint32 flags)
21862255
renderer->UpdateTextureYUV = GLES2_UpdateTextureYUV;
21872256
renderer->UpdateTextureNV = GLES2_UpdateTextureNV;
21882257
#endif
2258+
renderer->SetTexturePalette = GLES2_SetTexturePalette;
21892259
renderer->LockTexture = GLES2_LockTexture;
21902260
renderer->UnlockTexture = GLES2_UnlockTexture;
21912261
renderer->SetTextureScaleMode = GLES2_SetTextureScaleMode;
@@ -2261,11 +2331,12 @@ SDL_RenderDriver GLES2_RenderDriver = {
22612331
GLES2_CreateRenderer,
22622332
{ "opengles2",
22632333
(SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE),
2264-
4,
2334+
5,
22652335
{ SDL_PIXELFORMAT_ARGB8888,
22662336
SDL_PIXELFORMAT_ABGR8888,
22672337
SDL_PIXELFORMAT_RGB888,
2268-
SDL_PIXELFORMAT_BGR888 },
2338+
SDL_PIXELFORMAT_BGR888,
2339+
SDL_PIXELFORMAT_INDEX8 },
22692340
0,
22702341
0 }
22712342
};

src/render/opengles2/SDL_shaders_gles2.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,23 @@ static const char GLES2_Fragment_TextureBGR[] = \
151151
"}\n" \
152152
;
153153

154+
/* Palette to ABGR conversion */
155+
static const char GLES2_Fragment_TexturePalette[] = \
156+
"uniform sampler2D u_texture;\n" \
157+
"uniform sampler2D u_texture_p;\n" \
158+
"varying mediump vec4 v_color;\n" \
159+
"varying SDL_TEXCOORD_PRECISION vec2 v_texCoord;\n" \
160+
"\n" \
161+
"void main()\n" \
162+
"{\n" \
163+
" float index = texture2D(u_texture, v_texCoord).r * 255.0;\n" \
164+
" SDL_TEXCOORD_PRECISION vec2 paletteXY = vec2((index + 0.5) / 256.0, 0.5);\n" \
165+
" mediump vec4 rgba = texture2D(u_texture_p, paletteXY);\n" \
166+
" gl_FragColor = rgba;\n" \
167+
" gl_FragColor *= v_color;\n" \
168+
"}\n" \
169+
;
170+
154171
#if SDL_HAVE_YUV
155172

156173
#define JPEG_SHADER_CONSTANTS \
@@ -413,6 +430,8 @@ const char *GLES2_GetShader(GLES2_ShaderType type)
413430
return GLES2_Fragment_TextureRGB;
414431
case GLES2_SHADER_FRAGMENT_TEXTURE_BGR:
415432
return GLES2_Fragment_TextureBGR;
433+
case GLES2_SHADER_FRAGMENT_TEXTURE_PALETTE:
434+
return GLES2_Fragment_TexturePalette;
416435
#if SDL_HAVE_YUV
417436
case GLES2_SHADER_FRAGMENT_TEXTURE_YUV_JPEG:
418437
return GLES2_Fragment_TextureYUVJPEG;

src/render/opengles2/SDL_shaders_gles2.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ typedef enum
4343
GLES2_SHADER_FRAGMENT_TEXTURE_ARGB,
4444
GLES2_SHADER_FRAGMENT_TEXTURE_BGR,
4545
GLES2_SHADER_FRAGMENT_TEXTURE_RGB,
46+
GLES2_SHADER_FRAGMENT_TEXTURE_PALETTE,
4647
#if SDL_HAVE_YUV
4748
GLES2_SHADER_FRAGMENT_TEXTURE_YUV_JPEG,
4849
GLES2_SHADER_FRAGMENT_TEXTURE_YUV_BT601,

0 commit comments

Comments
 (0)