Initial pass at shader YV12 support - doesn't quite work yet.
This commit is contained in:
parent
8ecd7110d2
commit
53654196fd
3 changed files with 109 additions and 15 deletions
|
@ -124,9 +124,7 @@ enum
|
||||||
#define SDL_BITSPERPIXEL(X) (((X) >> 8) & 0xFF)
|
#define SDL_BITSPERPIXEL(X) (((X) >> 8) & 0xFF)
|
||||||
#define SDL_BYTESPERPIXEL(X) \
|
#define SDL_BYTESPERPIXEL(X) \
|
||||||
(SDL_ISPIXELFORMAT_FOURCC(X) ? \
|
(SDL_ISPIXELFORMAT_FOURCC(X) ? \
|
||||||
((((X) == SDL_PIXELFORMAT_YV12) || \
|
((((X) == SDL_PIXELFORMAT_YUY2) || \
|
||||||
((X) == SDL_PIXELFORMAT_IYUV) || \
|
|
||||||
((X) == SDL_PIXELFORMAT_YUY2) || \
|
|
||||||
((X) == SDL_PIXELFORMAT_UYVY) || \
|
((X) == SDL_PIXELFORMAT_UYVY) || \
|
||||||
((X) == SDL_PIXELFORMAT_YVYU)) ? 2 : 1) : (((X) >> 0) & 0xFF))
|
((X) == SDL_PIXELFORMAT_YVYU)) ? 2 : 1) : (((X) >> 0) & 0xFF))
|
||||||
|
|
||||||
|
|
|
@ -119,6 +119,11 @@ typedef struct
|
||||||
void *pixels;
|
void *pixels;
|
||||||
int pitch;
|
int pitch;
|
||||||
SDL_Rect locked_rect;
|
SDL_Rect locked_rect;
|
||||||
|
|
||||||
|
/* YV12 texture support */
|
||||||
|
SDL_bool yuv;
|
||||||
|
GLuint utexture;
|
||||||
|
GLuint vtexture;
|
||||||
} GL_TextureData;
|
} GL_TextureData;
|
||||||
|
|
||||||
|
|
||||||
|
@ -292,12 +297,11 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||||
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 0
|
|
||||||
/* 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 (data->shaders && data->num_texture_units >= 3) {
|
||||||
renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_YV12;
|
renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_YV12;
|
||||||
|
renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_IYUV;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Set up parameters for rendering */
|
/* Set up parameters for rendering */
|
||||||
data->blendMode = -1;
|
data->blendMode = -1;
|
||||||
|
@ -372,6 +376,12 @@ convert_format(GL_RenderData *renderdata, Uint32 pixel_format,
|
||||||
*format = GL_BGRA;
|
*format = GL_BGRA;
|
||||||
*type = GL_UNSIGNED_INT_8_8_8_8_REV;
|
*type = GL_UNSIGNED_INT_8_8_8_8_REV;
|
||||||
break;
|
break;
|
||||||
|
case SDL_PIXELFORMAT_YV12:
|
||||||
|
case SDL_PIXELFORMAT_IYUV:
|
||||||
|
*internalFormat = GL_LUMINANCE;
|
||||||
|
*format = GL_LUMINANCE;
|
||||||
|
*type = GL_UNSIGNED_BYTE;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return SDL_FALSE;
|
return SDL_FALSE;
|
||||||
}
|
}
|
||||||
|
@ -404,8 +414,15 @@ GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
|
if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
|
||||||
|
size_t size;
|
||||||
data->pitch = texture->w * SDL_BYTESPERPIXEL(texture->format);
|
data->pitch = texture->w * SDL_BYTESPERPIXEL(texture->format);
|
||||||
data->pixels = SDL_malloc(texture->h * data->pitch);
|
size = texture->h * data->pitch;
|
||||||
|
if (texture->format == SDL_PIXELFORMAT_YV12 ||
|
||||||
|
texture->format == SDL_PIXELFORMAT_IYUV) {
|
||||||
|
/* Need to add size for the U and V planes */
|
||||||
|
size += (2 * (texture->h * data->pitch) / 4);
|
||||||
|
}
|
||||||
|
data->pixels = SDL_malloc(size);
|
||||||
if (!data->pixels) {
|
if (!data->pixels) {
|
||||||
SDL_OutOfMemory();
|
SDL_OutOfMemory();
|
||||||
SDL_free(data);
|
SDL_free(data);
|
||||||
|
@ -478,6 +495,41 @@ GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||||
GL_SetError("glTexImage2D()", result);
|
GL_SetError("glTexImage2D()", result);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (texture->format == SDL_PIXELFORMAT_YV12 ||
|
||||||
|
texture->format == SDL_PIXELFORMAT_IYUV) {
|
||||||
|
data->yuv = SDL_TRUE;
|
||||||
|
|
||||||
|
renderdata->glGenTextures(1, &data->utexture);
|
||||||
|
renderdata->glGenTextures(1, &data->vtexture);
|
||||||
|
renderdata->glEnable(data->type);
|
||||||
|
|
||||||
|
renderdata->glBindTexture(data->type, data->utexture);
|
||||||
|
renderdata->glTexParameteri(data->type, GL_TEXTURE_MIN_FILTER,
|
||||||
|
GL_LINEAR);
|
||||||
|
renderdata->glTexParameteri(data->type, GL_TEXTURE_MAG_FILTER,
|
||||||
|
GL_LINEAR);
|
||||||
|
renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_S,
|
||||||
|
GL_CLAMP_TO_EDGE);
|
||||||
|
renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_T,
|
||||||
|
GL_CLAMP_TO_EDGE);
|
||||||
|
renderdata->glTexImage2D(data->type, 0, internalFormat, texture_w/2,
|
||||||
|
texture_h/2, 0, format, type, NULL);
|
||||||
|
|
||||||
|
renderdata->glBindTexture(data->type, data->vtexture);
|
||||||
|
renderdata->glTexParameteri(data->type, GL_TEXTURE_MIN_FILTER,
|
||||||
|
GL_LINEAR);
|
||||||
|
renderdata->glTexParameteri(data->type, GL_TEXTURE_MAG_FILTER,
|
||||||
|
GL_LINEAR);
|
||||||
|
renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_S,
|
||||||
|
GL_CLAMP_TO_EDGE);
|
||||||
|
renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_T,
|
||||||
|
GL_CLAMP_TO_EDGE);
|
||||||
|
renderdata->glTexImage2D(data->type, 0, internalFormat, texture_w/2,
|
||||||
|
texture_h/2, 0, format, type, NULL);
|
||||||
|
|
||||||
|
renderdata->glDisable(data->type);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -500,6 +552,35 @@ GL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
|
||||||
renderdata->glTexSubImage2D(data->type, 0, rect->x, rect->y, rect->w,
|
renderdata->glTexSubImage2D(data->type, 0, rect->x, rect->y, rect->w,
|
||||||
rect->h, data->format, data->formattype,
|
rect->h, data->format, data->formattype,
|
||||||
pixels);
|
pixels);
|
||||||
|
if (data->yuv) {
|
||||||
|
/* Skip to the top of the next texture */
|
||||||
|
const void *top = (const void*)((const Uint8*)pixels + (texture->h-rect->y) * pitch - rect->x);
|
||||||
|
|
||||||
|
/* Skip to the correct offset into the next texture */
|
||||||
|
pixels = (const void*)((const Uint8*)top + (rect->y / 2) * pitch + rect->x / 2);
|
||||||
|
if (texture->format == SDL_PIXELFORMAT_YV12) {
|
||||||
|
renderdata->glBindTexture(data->type, data->vtexture);
|
||||||
|
} else {
|
||||||
|
renderdata->glBindTexture(data->type, data->utexture);
|
||||||
|
}
|
||||||
|
renderdata->glTexSubImage2D(data->type, 0, rect->x/2, rect->y/2,
|
||||||
|
rect->w/2, rect->h/2,
|
||||||
|
data->format, data->formattype, pixels);
|
||||||
|
|
||||||
|
/* Skip to the top of the next texture */
|
||||||
|
top = (const void*)((const Uint8*)top + (texture->h * pitch)/4);
|
||||||
|
|
||||||
|
/* Skip to the correct offset into the next texture */
|
||||||
|
pixels = (const void*)((const Uint8*)top + (rect->y / 2) * pitch + rect->x / 2);
|
||||||
|
if (texture->format == SDL_PIXELFORMAT_YV12) {
|
||||||
|
renderdata->glBindTexture(data->type, data->utexture);
|
||||||
|
} else {
|
||||||
|
renderdata->glBindTexture(data->type, data->vtexture);
|
||||||
|
}
|
||||||
|
renderdata->glTexSubImage2D(data->type, 0, rect->x/2, rect->y/2,
|
||||||
|
rect->w/2, rect->h/2,
|
||||||
|
data->format, data->formattype, pixels);
|
||||||
|
}
|
||||||
renderdata->glDisable(data->type);
|
renderdata->glDisable(data->type);
|
||||||
result = renderdata->glGetError();
|
result = renderdata->glGetError();
|
||||||
if (result != GL_NO_ERROR) {
|
if (result != GL_NO_ERROR) {
|
||||||
|
@ -750,6 +831,13 @@ GL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
|
||||||
maxv *= texturedata->texh;
|
maxv *= texturedata->texh;
|
||||||
|
|
||||||
data->glEnable(texturedata->type);
|
data->glEnable(texturedata->type);
|
||||||
|
if (texturedata->yuv) {
|
||||||
|
data->glActiveTextureARB(GL_TEXTURE2_ARB);
|
||||||
|
data->glBindTexture(texturedata->type, texturedata->vtexture);
|
||||||
|
data->glActiveTextureARB(GL_TEXTURE1_ARB);
|
||||||
|
data->glBindTexture(texturedata->type, texturedata->utexture);
|
||||||
|
data->glActiveTextureARB(GL_TEXTURE0_ARB);
|
||||||
|
}
|
||||||
data->glBindTexture(texturedata->type, texturedata->texture);
|
data->glBindTexture(texturedata->type, texturedata->texture);
|
||||||
|
|
||||||
if (texture->modMode) {
|
if (texture->modMode) {
|
||||||
|
@ -762,7 +850,11 @@ GL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
|
||||||
}
|
}
|
||||||
|
|
||||||
GL_SetBlendMode(data, texture->blendMode);
|
GL_SetBlendMode(data, texture->blendMode);
|
||||||
|
if (texturedata->yuv) {
|
||||||
|
GL_SelectShader(data->shaders, SHADER_YV12);
|
||||||
|
} else {
|
||||||
GL_SelectShader(data->shaders, SHADER_RGB);
|
GL_SelectShader(data->shaders, SHADER_RGB);
|
||||||
|
}
|
||||||
|
|
||||||
data->glBegin(GL_TRIANGLE_STRIP);
|
data->glBegin(GL_TRIANGLE_STRIP);
|
||||||
data->glTexCoord2f(minu, minv);
|
data->glTexCoord2f(minu, minv);
|
||||||
|
@ -848,6 +940,10 @@ GL_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||||
if (data->texture) {
|
if (data->texture) {
|
||||||
renderdata->glDeleteTextures(1, &data->texture);
|
renderdata->glDeleteTextures(1, &data->texture);
|
||||||
}
|
}
|
||||||
|
if (data->yuv) {
|
||||||
|
renderdata->glDeleteTextures(1, &data->utexture);
|
||||||
|
renderdata->glDeleteTextures(1, &data->vtexture);
|
||||||
|
}
|
||||||
if (data->pixels) {
|
if (data->pixels) {
|
||||||
SDL_free(data->pixels);
|
SDL_free(data->pixels);
|
||||||
}
|
}
|
||||||
|
|
|
@ -360,7 +360,7 @@ main(int argc, char **argv)
|
||||||
int fps = 12;
|
int fps = 12;
|
||||||
int fpsdelay;
|
int fpsdelay;
|
||||||
int nodelay = 0;
|
int nodelay = 0;
|
||||||
int overlay_format = SDL_YUY2_OVERLAY;
|
Uint32 pixel_format = SDL_PIXELFORMAT_YV12;
|
||||||
int scale = 5;
|
int scale = 5;
|
||||||
SDL_bool done = SDL_FALSE;
|
SDL_bool done = SDL_FALSE;
|
||||||
|
|
||||||
|
@ -397,15 +397,15 @@ main(int argc, char **argv)
|
||||||
} else if (strcmp(argv[1], "-format") == 0) {
|
} else if (strcmp(argv[1], "-format") == 0) {
|
||||||
if (argv[2]) {
|
if (argv[2]) {
|
||||||
if (!strcmp(argv[2], "YV12"))
|
if (!strcmp(argv[2], "YV12"))
|
||||||
overlay_format = SDL_YV12_OVERLAY;
|
pixel_format = SDL_PIXELFORMAT_YV12;
|
||||||
else if (!strcmp(argv[2], "IYUV"))
|
else if (!strcmp(argv[2], "IYUV"))
|
||||||
overlay_format = SDL_IYUV_OVERLAY;
|
pixel_format = SDL_PIXELFORMAT_IYUV;
|
||||||
else if (!strcmp(argv[2], "YUY2"))
|
else if (!strcmp(argv[2], "YUY2"))
|
||||||
overlay_format = SDL_YUY2_OVERLAY;
|
pixel_format = SDL_PIXELFORMAT_YUY2;
|
||||||
else if (!strcmp(argv[2], "UYVY"))
|
else if (!strcmp(argv[2], "UYVY"))
|
||||||
overlay_format = SDL_UYVY_OVERLAY;
|
pixel_format = SDL_PIXELFORMAT_UYVY;
|
||||||
else if (!strcmp(argv[2], "YVYU"))
|
else if (!strcmp(argv[2], "YVYU"))
|
||||||
overlay_format = SDL_YVYU_OVERLAY;
|
pixel_format = SDL_PIXELFORMAT_YVYU;
|
||||||
else {
|
else {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"The -format option %s is not recognized, see help for info.\n",
|
"The -format option %s is not recognized, see help for info.\n",
|
||||||
|
@ -490,7 +490,7 @@ main(int argc, char **argv)
|
||||||
quit(4);
|
quit(4);
|
||||||
}
|
}
|
||||||
|
|
||||||
MooseTexture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_YV12, SDL_TEXTUREACCESS_STREAMING, MOOSEPIC_W, MOOSEPIC_H);
|
MooseTexture = SDL_CreateTexture(renderer, pixel_format, SDL_TEXTUREACCESS_STREAMING, MOOSEPIC_W, MOOSEPIC_H);
|
||||||
if (!MooseTexture) {
|
if (!MooseTexture) {
|
||||||
fprintf(stderr, "Couldn't set create texture: %s\n", SDL_GetError());
|
fprintf(stderr, "Couldn't set create texture: %s\n", SDL_GetError());
|
||||||
free(RawMooseData);
|
free(RawMooseData);
|
||||||
|
@ -569,7 +569,7 @@ main(int argc, char **argv)
|
||||||
if (!paused) {
|
if (!paused) {
|
||||||
i = (i + 1) % MOOSEFRAMES_COUNT;
|
i = (i + 1) % MOOSEFRAMES_COUNT;
|
||||||
|
|
||||||
SDL_UpdateTexture(MooseTexture, NULL, MooseFrame[i], MOOSEPIC_W*2);
|
SDL_UpdateTexture(MooseTexture, NULL, MooseFrame[i], MOOSEPIC_W*SDL_BYTESPERPIXEL(pixel_format));
|
||||||
}
|
}
|
||||||
SDL_RenderClear(renderer);
|
SDL_RenderClear(renderer);
|
||||||
SDL_RenderCopy(renderer, MooseTexture, NULL, &displayrect);
|
SDL_RenderCopy(renderer, MooseTexture, NULL, &displayrect);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue