Added OpenGL state caching for decent speed improvement.
This commit is contained in:
parent
8c64c50659
commit
ee61cc3170
4 changed files with 340 additions and 238 deletions
|
@ -87,7 +87,12 @@ typedef struct
|
|||
{
|
||||
SDL_GLContext context;
|
||||
SDL_bool GL_ARB_texture_rectangle_supported;
|
||||
struct {
|
||||
GL_Shader shader;
|
||||
Uint32 color;
|
||||
int blendMode;
|
||||
GLenum scaleMode;
|
||||
} current;
|
||||
|
||||
/* OpenGL functions */
|
||||
#define SDL_PROC(ret,func,params) ret (APIENTRY *func) params;
|
||||
|
@ -117,6 +122,7 @@ typedef struct
|
|||
GLenum formattype;
|
||||
void *pixels;
|
||||
int pitch;
|
||||
int scaleMode;
|
||||
SDL_Rect locked_rect;
|
||||
|
||||
/* YV12 texture support */
|
||||
|
@ -202,6 +208,32 @@ GL_ActivateRenderer(SDL_Renderer * renderer)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* This is called if we need to invalidate all of the SDL OpenGL state */
|
||||
static void
|
||||
GL_ResetState(SDL_Renderer *renderer)
|
||||
{
|
||||
GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
|
||||
|
||||
if (SDL_CurrentContext == data->context) {
|
||||
GL_UpdateViewport(renderer);
|
||||
} else {
|
||||
GL_ActivateRenderer(renderer);
|
||||
}
|
||||
|
||||
data->current.shader = SHADER_NONE;
|
||||
data->current.color = 0;
|
||||
data->current.blendMode = -1;
|
||||
data->current.scaleMode = 0;
|
||||
|
||||
data->glDisable(GL_DEPTH_TEST);
|
||||
data->glDisable(GL_CULL_FACE);
|
||||
/* This ended up causing video discrepancies between OpenGL and Direct3D */
|
||||
/*data->glEnable(GL_LINE_SMOOTH);*/
|
||||
|
||||
data->glMatrixMode(GL_MODELVIEW);
|
||||
data->glLoadIdentity();
|
||||
}
|
||||
|
||||
SDL_Renderer *
|
||||
GL_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||
{
|
||||
|
@ -320,13 +352,7 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags)
|
|||
}
|
||||
|
||||
/* Set up parameters for rendering */
|
||||
data->blendMode = -1;
|
||||
data->glDisable(GL_DEPTH_TEST);
|
||||
data->glDisable(GL_CULL_FACE);
|
||||
/* This ended up causing video discrepancies between OpenGL and Direct3D */
|
||||
/*data->glEnable(GL_LINE_SMOOTH);*/
|
||||
data->glMatrixMode(GL_MODELVIEW);
|
||||
data->glLoadIdentity();
|
||||
GL_ResetState(renderer);
|
||||
|
||||
return renderer;
|
||||
}
|
||||
|
@ -437,12 +463,9 @@ GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
|||
|
||||
data->format = format;
|
||||
data->formattype = type;
|
||||
data->scaleMode = GL_LINEAR;
|
||||
renderdata->glEnable(data->type);
|
||||
renderdata->glBindTexture(data->type, data->texture);
|
||||
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,
|
||||
|
@ -492,10 +515,6 @@ GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
|||
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,
|
||||
|
@ -504,10 +523,6 @@ GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
|||
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,
|
||||
|
@ -631,10 +646,33 @@ GL_UpdateViewport(SDL_Renderer * renderer)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
GL_SetShader(GL_RenderData * data, GL_Shader shader)
|
||||
{
|
||||
if (data->shaders && shader != data->current.shader) {
|
||||
GL_SelectShader(data->shaders, shader);
|
||||
data->current.shader = shader;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
GL_SetColor(GL_RenderData * data, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
|
||||
{
|
||||
Uint32 color = ((a << 24) | (r << 16) | (g << 8) | b);
|
||||
|
||||
if (color != data->current.color) {
|
||||
data->glColor4f((GLfloat) r * inv255f,
|
||||
(GLfloat) g * inv255f,
|
||||
(GLfloat) b * inv255f,
|
||||
(GLfloat) a * inv255f);
|
||||
data->current.color = color;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
GL_SetBlendMode(GL_RenderData * data, int blendMode)
|
||||
{
|
||||
if (blendMode != data->blendMode) {
|
||||
if (blendMode != data->current.blendMode) {
|
||||
switch (blendMode) {
|
||||
case SDL_BLENDMODE_NONE:
|
||||
data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
||||
|
@ -656,10 +694,27 @@ GL_SetBlendMode(GL_RenderData * data, int blendMode)
|
|||
data->glBlendFunc(GL_ZERO, GL_SRC_COLOR);
|
||||
break;
|
||||
}
|
||||
data->blendMode = blendMode;
|
||||
data->current.blendMode = blendMode;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
GL_SetDrawingState(SDL_Renderer * renderer)
|
||||
{
|
||||
GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
|
||||
|
||||
GL_ActivateRenderer(renderer);
|
||||
|
||||
GL_SetColor(data, (GLfloat) renderer->r,
|
||||
(GLfloat) renderer->g,
|
||||
(GLfloat) renderer->b,
|
||||
(GLfloat) renderer->a);
|
||||
|
||||
GL_SetBlendMode(data, renderer->blendMode);
|
||||
|
||||
GL_SetShader(data, SHADER_SOLID);
|
||||
}
|
||||
|
||||
static int
|
||||
GL_RenderClear(SDL_Renderer * renderer)
|
||||
{
|
||||
|
@ -684,15 +739,7 @@ GL_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points,
|
|||
GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
|
||||
int i;
|
||||
|
||||
GL_ActivateRenderer(renderer);
|
||||
|
||||
GL_SetBlendMode(data, renderer->blendMode);
|
||||
GL_SelectShader(data->shaders, SHADER_SOLID);
|
||||
|
||||
data->glColor4f((GLfloat) renderer->r * inv255f,
|
||||
(GLfloat) renderer->g * inv255f,
|
||||
(GLfloat) renderer->b * inv255f,
|
||||
(GLfloat) renderer->a * inv255f);
|
||||
GL_SetDrawingState(renderer);
|
||||
|
||||
data->glBegin(GL_POINTS);
|
||||
for (i = 0; i < count; ++i) {
|
||||
|
@ -710,15 +757,7 @@ GL_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points,
|
|||
GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
|
||||
int i;
|
||||
|
||||
GL_ActivateRenderer(renderer);
|
||||
|
||||
GL_SetBlendMode(data, renderer->blendMode);
|
||||
GL_SelectShader(data->shaders, SHADER_SOLID);
|
||||
|
||||
data->glColor4f((GLfloat) renderer->r * inv255f,
|
||||
(GLfloat) renderer->g * inv255f,
|
||||
(GLfloat) renderer->b * inv255f,
|
||||
(GLfloat) renderer->a * inv255f);
|
||||
GL_SetDrawingState(renderer);
|
||||
|
||||
if (count > 2 &&
|
||||
points[0].x == points[count-1].x && points[0].y == points[count-1].y) {
|
||||
|
@ -781,15 +820,7 @@ GL_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect * rects, int count)
|
|||
GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
|
||||
int i;
|
||||
|
||||
GL_ActivateRenderer(renderer);
|
||||
|
||||
GL_SetBlendMode(data, renderer->blendMode);
|
||||
GL_SelectShader(data->shaders, SHADER_SOLID);
|
||||
|
||||
data->glColor4f((GLfloat) renderer->r * inv255f,
|
||||
(GLfloat) renderer->g * inv255f,
|
||||
(GLfloat) renderer->b * inv255f,
|
||||
(GLfloat) renderer->a * inv255f);
|
||||
GL_SetDrawingState(renderer);
|
||||
|
||||
for (i = 0; i < count; ++i) {
|
||||
const SDL_Rect *rect = &rects[i];
|
||||
|
@ -811,6 +842,52 @@ GL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
|
|||
|
||||
GL_ActivateRenderer(renderer);
|
||||
|
||||
data->glEnable(texturedata->type);
|
||||
if (texturedata->yuv) {
|
||||
data->glActiveTextureARB(GL_TEXTURE2_ARB);
|
||||
data->glBindTexture(texturedata->type, texturedata->vtexture);
|
||||
if (texturedata->scaleMode != data->current.scaleMode) {
|
||||
data->glTexParameteri(texturedata->type, GL_TEXTURE_MIN_FILTER,
|
||||
texturedata->scaleMode);
|
||||
data->glTexParameteri(texturedata->type, GL_TEXTURE_MAG_FILTER,
|
||||
texturedata->scaleMode);
|
||||
}
|
||||
|
||||
data->glActiveTextureARB(GL_TEXTURE1_ARB);
|
||||
data->glBindTexture(texturedata->type, texturedata->utexture);
|
||||
if (texturedata->scaleMode != data->current.scaleMode) {
|
||||
data->glTexParameteri(texturedata->type, GL_TEXTURE_MIN_FILTER,
|
||||
texturedata->scaleMode);
|
||||
data->glTexParameteri(texturedata->type, GL_TEXTURE_MAG_FILTER,
|
||||
texturedata->scaleMode);
|
||||
}
|
||||
|
||||
data->glActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
}
|
||||
data->glBindTexture(texturedata->type, texturedata->texture);
|
||||
|
||||
if (texturedata->scaleMode != data->current.scaleMode) {
|
||||
data->glTexParameteri(texturedata->type, GL_TEXTURE_MIN_FILTER,
|
||||
texturedata->scaleMode);
|
||||
data->glTexParameteri(texturedata->type, GL_TEXTURE_MAG_FILTER,
|
||||
texturedata->scaleMode);
|
||||
data->current.scaleMode = texturedata->scaleMode;
|
||||
}
|
||||
|
||||
if (texture->modMode) {
|
||||
GL_SetColor(data, texture->r, texture->g, texture->b, texture->a);
|
||||
} else {
|
||||
GL_SetColor(data, 255, 255, 255, 255);
|
||||
}
|
||||
|
||||
GL_SetBlendMode(data, texture->blendMode);
|
||||
|
||||
if (texturedata->yuv) {
|
||||
GL_SetShader(data, SHADER_YV12);
|
||||
} else {
|
||||
GL_SetShader(data, SHADER_RGB);
|
||||
}
|
||||
|
||||
minx = dstrect->x;
|
||||
miny = dstrect->y;
|
||||
maxx = dstrect->x + dstrect->w;
|
||||
|
@ -825,32 +902,6 @@ GL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
|
|||
maxv = (GLfloat) (srcrect->y + srcrect->h) / texture->h;
|
||||
maxv *= texturedata->texh;
|
||||
|
||||
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);
|
||||
|
||||
if (texture->modMode) {
|
||||
data->glColor4f((GLfloat) texture->r * inv255f,
|
||||
(GLfloat) texture->g * inv255f,
|
||||
(GLfloat) texture->b * inv255f,
|
||||
(GLfloat) texture->a * inv255f);
|
||||
} else {
|
||||
data->glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
GL_SetBlendMode(data, texture->blendMode);
|
||||
if (texturedata->yuv) {
|
||||
GL_SelectShader(data->shaders, SHADER_YV12);
|
||||
} else {
|
||||
GL_SelectShader(data->shaders, SHADER_RGB);
|
||||
}
|
||||
|
||||
data->glBegin(GL_TRIANGLE_STRIP);
|
||||
data->glTexCoord2f(minu, minv);
|
||||
data->glVertex2f((GLfloat) minx, (GLfloat) miny);
|
||||
|
|
|
@ -60,7 +60,6 @@ struct GL_ShaderContext
|
|||
|
||||
SDL_bool GL_ARB_texture_rectangle_supported;
|
||||
|
||||
GL_Shader current_shader;
|
||||
GL_ShaderData shaders[NUM_SHADERS];
|
||||
};
|
||||
|
||||
|
@ -341,18 +340,7 @@ GL_CreateShaderContext()
|
|||
void
|
||||
GL_SelectShader(GL_ShaderContext *ctx, GL_Shader shader)
|
||||
{
|
||||
/* Nothing to do if there's no shader support */
|
||||
if (!ctx) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Nothing to do if there's no shader change */
|
||||
if (shader == ctx->current_shader) {
|
||||
return;
|
||||
}
|
||||
|
||||
ctx->glUseProgramObjectARB(ctx->shaders[shader].program);
|
||||
ctx->current_shader = shader;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -84,7 +84,12 @@ SDL_RenderDriver GLES_RenderDriver = {
|
|||
typedef struct
|
||||
{
|
||||
SDL_GLContext context;
|
||||
struct {
|
||||
Uint32 color;
|
||||
int blendMode;
|
||||
GLenum scaleMode;
|
||||
SDL_bool tex_coords;
|
||||
} current;
|
||||
|
||||
SDL_bool useDrawTexture;
|
||||
SDL_bool GL_OES_draw_texture_supported;
|
||||
|
@ -100,6 +105,7 @@ typedef struct
|
|||
GLenum formattype;
|
||||
void *pixels;
|
||||
int pitch;
|
||||
GLenum scaleMode;
|
||||
} GLES_TextureData;
|
||||
|
||||
static void
|
||||
|
@ -154,6 +160,33 @@ GLES_ActivateRenderer(SDL_Renderer * renderer)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* This is called if we need to invalidate all of the SDL OpenGL state */
|
||||
static void
|
||||
GLES_ResetState(SDL_Renderer *renderer)
|
||||
{
|
||||
GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
|
||||
|
||||
if (SDL_CurrentContext == data->context) {
|
||||
GLES_UpdateViewport(renderer);
|
||||
} else {
|
||||
GLES_ActivateRenderer(renderer);
|
||||
}
|
||||
|
||||
data->current.color = 0;
|
||||
data->current.blendMode = -1;
|
||||
data->current.scaleMode = 0;
|
||||
data->current.tex_coords = SDL_FALSE;
|
||||
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_CULL_FACE);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
}
|
||||
|
||||
SDL_Renderer *
|
||||
GLES_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||
{
|
||||
|
@ -234,14 +267,7 @@ GLES_CreateRenderer(SDL_Window * window, Uint32 flags)
|
|||
renderer->info.max_texture_height = value;
|
||||
|
||||
/* Set up parameters for rendering */
|
||||
data->blendMode = -1;
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_CULL_FACE);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
//glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
GLES_ResetState(renderer);
|
||||
|
||||
return renderer;
|
||||
}
|
||||
|
@ -319,15 +345,10 @@ GLES_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
|||
|
||||
data->format = format;
|
||||
data->formattype = type;
|
||||
data->scaleMode = GL_LINEAR;
|
||||
glBindTexture(data->type, data->texture);
|
||||
glTexParameteri(data->type, GL_TEXTURE_MIN_FILTER,
|
||||
GL_LINEAR);
|
||||
glTexParameteri(data->type, GL_TEXTURE_MAG_FILTER,
|
||||
GL_LINEAR);
|
||||
glTexParameteri(data->type, GL_TEXTURE_WRAP_S,
|
||||
GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(data->type, GL_TEXTURE_WRAP_T,
|
||||
GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(data->type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(data->type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
glTexImage2D(data->type, 0, internalFormat, texture_w,
|
||||
texture_h, 0, format, type, NULL);
|
||||
|
@ -453,25 +474,24 @@ GLES_UpdateViewport(SDL_Renderer * renderer)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
GLES_RenderClear(SDL_Renderer * renderer)
|
||||
static void
|
||||
GLES_SetColor(GLES_RenderData * data, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
|
||||
{
|
||||
GLES_ActivateRenderer(renderer);
|
||||
Uint32 color = ((a << 24) | (r << 16) | (g << 8) | b);
|
||||
|
||||
glClearColor((GLfloat) renderer->r * inv255f,
|
||||
(GLfloat) renderer->g * inv255f,
|
||||
(GLfloat) renderer->b * inv255f,
|
||||
(GLfloat) renderer->a * inv255f);
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
return 0;
|
||||
if (color != data->current.color) {
|
||||
glColor4f((GLfloat) r * inv255f,
|
||||
(GLfloat) g * inv255f,
|
||||
(GLfloat) b * inv255f,
|
||||
(GLfloat) a * inv255f);
|
||||
data->current.color = color;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
GLES_SetBlendMode(GLES_RenderData * data, int blendMode)
|
||||
{
|
||||
if (blendMode != data->blendMode) {
|
||||
if (blendMode != data->current.blendMode) {
|
||||
switch (blendMode) {
|
||||
case SDL_BLENDMODE_NONE:
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
||||
|
@ -493,10 +513,55 @@ GLES_SetBlendMode(GLES_RenderData * data, int blendMode)
|
|||
glBlendFunc(GL_ZERO, GL_SRC_COLOR);
|
||||
break;
|
||||
}
|
||||
data->blendMode = blendMode;
|
||||
data->current.blendMode = blendMode;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
GLES_SetTexCoords(GLES_RenderData * data, SDL_bool enabled)
|
||||
{
|
||||
if (enabled != data->current.tex_coords) {
|
||||
if (enabled) {
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
} else {
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
}
|
||||
data->current.tex_coords = enabled;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
GLES_SetDrawingState(SDL_Renderer * renderer)
|
||||
{
|
||||
GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
|
||||
|
||||
GLES_ActivateRenderer(renderer);
|
||||
|
||||
GLES_SetColor(data, (GLfloat) renderer->r,
|
||||
(GLfloat) renderer->g,
|
||||
(GLfloat) renderer->b,
|
||||
(GLfloat) renderer->a);
|
||||
|
||||
GLES_SetBlendMode(data, renderer->blendMode);
|
||||
|
||||
GLES_SetTexCoords(data, SDL_FALSE);
|
||||
}
|
||||
|
||||
static int
|
||||
GLES_RenderClear(SDL_Renderer * renderer)
|
||||
{
|
||||
GLES_ActivateRenderer(renderer);
|
||||
|
||||
glClearColor((GLfloat) renderer->r * inv255f,
|
||||
(GLfloat) renderer->g * inv255f,
|
||||
(GLfloat) renderer->b * inv255f,
|
||||
(GLfloat) renderer->a * inv255f);
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
GLES_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points,
|
||||
int count)
|
||||
|
@ -505,14 +570,7 @@ GLES_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points,
|
|||
int i;
|
||||
GLshort *vertices;
|
||||
|
||||
GLES_ActivateRenderer(renderer);
|
||||
|
||||
GLES_SetBlendMode(data, renderer->blendMode);
|
||||
|
||||
glColor4f((GLfloat) renderer->r * inv255f,
|
||||
(GLfloat) renderer->g * inv255f,
|
||||
(GLfloat) renderer->b * inv255f,
|
||||
(GLfloat) renderer->a * inv255f);
|
||||
GLES_SetDrawingState(renderer);
|
||||
|
||||
vertices = SDL_stack_alloc(GLshort, count*2);
|
||||
for (i = 0; i < count; ++i) {
|
||||
|
@ -534,14 +592,7 @@ GLES_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points,
|
|||
int i;
|
||||
GLshort *vertices;
|
||||
|
||||
GLES_ActivateRenderer(renderer);
|
||||
|
||||
GLES_SetBlendMode(data, renderer->blendMode);
|
||||
|
||||
glColor4f((GLfloat) renderer->r * inv255f,
|
||||
(GLfloat) renderer->g * inv255f,
|
||||
(GLfloat) renderer->b * inv255f,
|
||||
(GLfloat) renderer->a * inv255f);
|
||||
GLES_SetDrawingState(renderer);
|
||||
|
||||
vertices = SDL_stack_alloc(GLshort, count*2);
|
||||
for (i = 0; i < count; ++i) {
|
||||
|
@ -569,14 +620,7 @@ GLES_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect * rects,
|
|||
GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
|
||||
int i;
|
||||
|
||||
GLES_ActivateRenderer(renderer);
|
||||
|
||||
GLES_SetBlendMode(data, renderer->blendMode);
|
||||
|
||||
glColor4f((GLfloat) renderer->r * inv255f,
|
||||
(GLfloat) renderer->g * inv255f,
|
||||
(GLfloat) renderer->b * inv255f,
|
||||
(GLfloat) renderer->a * inv255f);
|
||||
GLES_SetDrawingState(renderer);
|
||||
|
||||
for (i = 0; i < count; ++i) {
|
||||
const SDL_Rect *rect = &rects[i];
|
||||
|
@ -614,21 +658,27 @@ GLES_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
|
|||
GLES_ActivateRenderer(renderer);
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
glBindTexture(texturedata->type, texturedata->texture);
|
||||
|
||||
if (texturedata->scaleMode != data->current.scaleMode) {
|
||||
glTexParameteri(texturedata->type, GL_TEXTURE_MIN_FILTER,
|
||||
texturedata->scaleMode);
|
||||
glTexParameteri(texturedata->type, GL_TEXTURE_MAG_FILTER,
|
||||
texturedata->scaleMode);
|
||||
data->current.scaleMode = texturedata->scaleMode;
|
||||
}
|
||||
|
||||
if (texture->modMode) {
|
||||
glColor4f((GLfloat) texture->r * inv255f,
|
||||
(GLfloat) texture->g * inv255f,
|
||||
(GLfloat) texture->b * inv255f,
|
||||
(GLfloat) texture->a * inv255f);
|
||||
GLES_SetColor(data, texture->r, texture->g, texture->b, texture->a);
|
||||
} else {
|
||||
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
GLES_SetColor(data, 255, 255, 255, 255);
|
||||
}
|
||||
|
||||
GLES_SetBlendMode(data, texture->blendMode);
|
||||
|
||||
GLES_SetTexCoords(data, SDL_TRUE);
|
||||
|
||||
if (data->GL_OES_draw_texture_supported && data->useDrawTexture) {
|
||||
/* this code is a little funny because the viewport is upside down vs SDL's coordinate system */
|
||||
GLint cropRect[4];
|
||||
|
@ -685,8 +735,6 @@ GLES_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
|
|||
glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -58,6 +58,7 @@ typedef struct GLES2_TextureData
|
|||
GLenum pixel_type;
|
||||
void *pixel_data;
|
||||
size_t pitch;
|
||||
GLenum scaleMode;
|
||||
} GLES2_TextureData;
|
||||
|
||||
typedef struct GLES2_ShaderCacheEntry
|
||||
|
@ -118,6 +119,12 @@ typedef enum
|
|||
typedef struct GLES2_DriverContext
|
||||
{
|
||||
SDL_GLContext *context;
|
||||
struct {
|
||||
int blendMode;
|
||||
GLenum scaleMode;
|
||||
SDL_bool tex_coords;
|
||||
} current;
|
||||
|
||||
int shader_format_count;
|
||||
GLenum *shader_formats;
|
||||
GLES2_ShaderCache shader_cache;
|
||||
|
@ -259,6 +266,7 @@ GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture)
|
|||
tdata->texture_type = GL_TEXTURE_2D;
|
||||
tdata->pixel_format = format;
|
||||
tdata->pixel_type = type;
|
||||
tdata->scaleMode = GL_LINEAR;
|
||||
|
||||
/* Allocate a blob for image data */
|
||||
if (texture->access == SDL_TEXTUREACCESS_STREAMING)
|
||||
|
@ -787,12 +795,12 @@ GLES2_RenderClear(SDL_Renderer * renderer)
|
|||
}
|
||||
|
||||
static void
|
||||
GLES2_SetBlendMode(int blendMode)
|
||||
GLES2_SetBlendMode(GLES2_DriverContext *rdata, int blendMode)
|
||||
{
|
||||
switch (blendMode)
|
||||
{
|
||||
case SDL_BLENDMODE_NONE:
|
||||
if (blendMode != rdata->current.blendMode) {
|
||||
switch (blendMode) {
|
||||
default:
|
||||
case SDL_BLENDMODE_NONE:
|
||||
glDisable(GL_BLEND);
|
||||
break;
|
||||
case SDL_BLENDMODE_BLEND:
|
||||
|
@ -808,22 +816,37 @@ GLES2_SetBlendMode(int blendMode)
|
|||
glBlendFunc(GL_ZERO, GL_SRC_COLOR);
|
||||
break;
|
||||
}
|
||||
rdata->current.blendMode = blendMode;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
GLES2_SetTexCoords(GLES2_DriverContext * rdata, SDL_bool enabled)
|
||||
{
|
||||
if (enabled != rdata->current.tex_coords) {
|
||||
if (enabled) {
|
||||
glEnableVertexAttribArray(GLES2_ATTRIBUTE_TEXCOORD);
|
||||
} else {
|
||||
glDisableVertexAttribArray(GLES2_ATTRIBUTE_TEXCOORD);
|
||||
}
|
||||
rdata->current.tex_coords = enabled;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
GLES2_RenderDrawPoints(SDL_Renderer *renderer, const SDL_Point *points, int count)
|
||||
GLES2_SetDrawingState(SDL_Renderer * renderer)
|
||||
{
|
||||
GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata;
|
||||
GLfloat *vertices;
|
||||
SDL_BlendMode blendMode;
|
||||
int alpha;
|
||||
int blendMode = renderer->blendMode;
|
||||
GLuint locColor;
|
||||
int idx;
|
||||
|
||||
glGetError();
|
||||
|
||||
GLES2_ActivateRenderer(renderer);
|
||||
|
||||
blendMode = renderer->blendMode;
|
||||
alpha = renderer->a;
|
||||
GLES2_SetBlendMode(rdata, blendMode);
|
||||
|
||||
GLES2_SetTexCoords(rdata, SDL_FALSE);
|
||||
|
||||
/* Activate an appropriate shader and set the projection matrix */
|
||||
if (GLES2_SelectProgram(renderer, GLES2_IMAGESOURCE_SOLID, blendMode) < 0)
|
||||
|
@ -831,15 +854,24 @@ GLES2_RenderDrawPoints(SDL_Renderer *renderer, const SDL_Point *points, int coun
|
|||
|
||||
/* Select the color to draw with */
|
||||
locColor = rdata->current_program->uniform_locations[GLES2_UNIFORM_COLOR];
|
||||
glGetError();
|
||||
glUniform4f(locColor,
|
||||
renderer->r * inv255f,
|
||||
renderer->g * inv255f,
|
||||
renderer->b * inv255f,
|
||||
alpha * inv255f);
|
||||
renderer->a * inv255f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Configure the correct blend mode */
|
||||
GLES2_SetBlendMode(blendMode);
|
||||
static int
|
||||
GLES2_RenderDrawPoints(SDL_Renderer *renderer, const SDL_Point *points, int count)
|
||||
{
|
||||
GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata;
|
||||
GLfloat *vertices;
|
||||
int idx;
|
||||
|
||||
if (GLES2_SetDrawingState(renderer) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Emit the specified vertices as points */
|
||||
vertices = SDL_stack_alloc(GLfloat, count * 2);
|
||||
|
@ -851,10 +883,9 @@ GLES2_RenderDrawPoints(SDL_Renderer *renderer, const SDL_Point *points, int coun
|
|||
vertices[idx * 2] = x;
|
||||
vertices[(idx * 2) + 1] = y;
|
||||
}
|
||||
glEnableVertexAttribArray(GLES2_ATTRIBUTE_POSITION);
|
||||
glGetError();
|
||||
glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices);
|
||||
glDrawArrays(GL_POINTS, 0, count);
|
||||
glDisableVertexAttribArray(GLES2_ATTRIBUTE_POSITION);
|
||||
SDL_stack_free(vertices);
|
||||
if (glGetError() != GL_NO_ERROR)
|
||||
{
|
||||
|
@ -869,31 +900,11 @@ GLES2_RenderDrawLines(SDL_Renderer *renderer, const SDL_Point *points, int count
|
|||
{
|
||||
GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata;
|
||||
GLfloat *vertices;
|
||||
SDL_BlendMode blendMode;
|
||||
int alpha;
|
||||
GLuint locColor;
|
||||
int idx;
|
||||
|
||||
GLES2_ActivateRenderer(renderer);
|
||||
|
||||
blendMode = renderer->blendMode;
|
||||
alpha = renderer->a;
|
||||
|
||||
/* Activate an appropriate shader and set the projection matrix */
|
||||
if (GLES2_SelectProgram(renderer, GLES2_IMAGESOURCE_SOLID, blendMode) < 0)
|
||||
if (GLES2_SetDrawingState(renderer) < 0) {
|
||||
return -1;
|
||||
|
||||
/* Select the color to draw with */
|
||||
locColor = rdata->current_program->uniform_locations[GLES2_UNIFORM_COLOR];
|
||||
glGetError();
|
||||
glUniform4f(locColor,
|
||||
renderer->r * inv255f,
|
||||
renderer->g * inv255f,
|
||||
renderer->b * inv255f,
|
||||
alpha * inv255f);
|
||||
|
||||
/* Configure the correct blend mode */
|
||||
GLES2_SetBlendMode(blendMode);
|
||||
}
|
||||
|
||||
/* Emit a line strip including the specified vertices */
|
||||
vertices = SDL_stack_alloc(GLfloat, count * 2);
|
||||
|
@ -905,10 +916,9 @@ GLES2_RenderDrawLines(SDL_Renderer *renderer, const SDL_Point *points, int count
|
|||
vertices[idx * 2] = x;
|
||||
vertices[(idx * 2) + 1] = y;
|
||||
}
|
||||
glEnableVertexAttribArray(GLES2_ATTRIBUTE_POSITION);
|
||||
glGetError();
|
||||
glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices);
|
||||
glDrawArrays(GL_LINE_STRIP, 0, count);
|
||||
glDisableVertexAttribArray(GLES2_ATTRIBUTE_POSITION);
|
||||
SDL_stack_free(vertices);
|
||||
if (glGetError() != GL_NO_ERROR)
|
||||
{
|
||||
|
@ -923,34 +933,14 @@ GLES2_RenderFillRects(SDL_Renderer *renderer, const SDL_Rect *rects, int count)
|
|||
{
|
||||
GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata;
|
||||
GLfloat vertices[8];
|
||||
SDL_BlendMode blendMode;
|
||||
int alpha;
|
||||
GLuint locColor;
|
||||
int idx;
|
||||
|
||||
GLES2_ActivateRenderer(renderer);
|
||||
|
||||
blendMode = renderer->blendMode;
|
||||
alpha = renderer->a;
|
||||
|
||||
/* Activate an appropriate shader and set the projection matrix */
|
||||
if (GLES2_SelectProgram(renderer, GLES2_IMAGESOURCE_SOLID, blendMode) < 0)
|
||||
if (GLES2_SetDrawingState(renderer) < 0) {
|
||||
return -1;
|
||||
|
||||
/* Select the color to draw with */
|
||||
locColor = rdata->current_program->uniform_locations[GLES2_UNIFORM_COLOR];
|
||||
glGetError();
|
||||
glUniform4f(locColor,
|
||||
renderer->r * inv255f,
|
||||
renderer->g * inv255f,
|
||||
renderer->b * inv255f,
|
||||
alpha * inv255f);
|
||||
|
||||
/* Configure the correct blend mode */
|
||||
GLES2_SetBlendMode(blendMode);
|
||||
}
|
||||
|
||||
/* Emit a line loop for each rectangle */
|
||||
glEnableVertexAttribArray(GLES2_ATTRIBUTE_POSITION);
|
||||
glGetError();
|
||||
for (idx = 0; idx < count; ++idx) {
|
||||
const SDL_Rect *rect = &rects[idx];
|
||||
|
||||
|
@ -970,7 +960,6 @@ GLES2_RenderFillRects(SDL_Renderer *renderer, const SDL_Rect *rects, int count)
|
|||
glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
glDisableVertexAttribArray(GLES2_ATTRIBUTE_POSITION);
|
||||
if (glGetError() != GL_NO_ERROR)
|
||||
{
|
||||
SDL_SetError("Failed to render lines");
|
||||
|
@ -987,7 +976,6 @@ GLES2_RenderCopy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *s
|
|||
GLES2_TextureData *tdata = (GLES2_TextureData *)texture->driverdata;
|
||||
GLES2_ImageSource sourceType;
|
||||
SDL_BlendMode blendMode;
|
||||
int alpha;
|
||||
GLfloat vertices[8];
|
||||
GLfloat texCoords[8];
|
||||
GLuint locTexture;
|
||||
|
@ -997,7 +985,6 @@ GLES2_RenderCopy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *s
|
|||
|
||||
/* Activate an appropriate shader and set the projection matrix */
|
||||
blendMode = texture->blendMode;
|
||||
alpha = texture->a;
|
||||
sourceType = GLES2_IMAGESOURCE_TEXTURE;
|
||||
if (GLES2_SelectProgram(renderer, sourceType, blendMode) < 0)
|
||||
return -1;
|
||||
|
@ -1009,8 +996,13 @@ GLES2_RenderCopy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *s
|
|||
glBindTexture(tdata->texture_type, tdata->texture);
|
||||
glUniform1i(locTexture, 0);
|
||||
|
||||
/* Configure texture blending */
|
||||
GLES2_SetBlendMode(blendMode);
|
||||
if (tdata->scaleMode != rdata->current.scaleMode) {
|
||||
glTexParameteri(tdata->texture_type, GL_TEXTURE_MIN_FILTER,
|
||||
tdata->scaleMode);
|
||||
glTexParameteri(tdata->texture_type, GL_TEXTURE_MAG_FILTER,
|
||||
tdata->scaleMode);
|
||||
rdata->current.scaleMode = tdata->scaleMode;
|
||||
}
|
||||
|
||||
/* Configure color modulation */
|
||||
locModulation = rdata->current_program->uniform_locations[GLES2_UNIFORM_MODULATION];
|
||||
|
@ -1018,11 +1010,14 @@ GLES2_RenderCopy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *s
|
|||
texture->r * inv255f,
|
||||
texture->g * inv255f,
|
||||
texture->b * inv255f,
|
||||
alpha * inv255f);
|
||||
texture->a * inv255f);
|
||||
|
||||
/* Configure texture blending */
|
||||
GLES2_SetBlendMode(rdata, blendMode);
|
||||
|
||||
GLES2_SetTexCoords(rdata, SDL_TRUE);
|
||||
|
||||
/* Emit the textured quad */
|
||||
glEnableVertexAttribArray(GLES2_ATTRIBUTE_TEXCOORD);
|
||||
glEnableVertexAttribArray(GLES2_ATTRIBUTE_POSITION);
|
||||
vertices[0] = (GLfloat)dstrect->x;
|
||||
vertices[1] = (GLfloat)dstrect->y;
|
||||
vertices[2] = (GLfloat)(dstrect->x + dstrect->w);
|
||||
|
@ -1042,8 +1037,6 @@ GLES2_RenderCopy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *s
|
|||
texCoords[7] = (srcrect->y + srcrect->h) / (GLfloat)texture->h;
|
||||
glVertexAttribPointer(GLES2_ATTRIBUTE_TEXCOORD, 2, GL_FLOAT, GL_FALSE, 0, texCoords);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
glDisableVertexAttribArray(GLES2_ATTRIBUTE_POSITION);
|
||||
glDisableVertexAttribArray(GLES2_ATTRIBUTE_TEXCOORD);
|
||||
if (glGetError() != GL_NO_ERROR)
|
||||
{
|
||||
SDL_SetError("Failed to render texture");
|
||||
|
@ -1067,6 +1060,25 @@ GLES2_RenderPresent(SDL_Renderer *renderer)
|
|||
|
||||
#define GL_NVIDIA_PLATFORM_BINARY_NV 0x890B
|
||||
|
||||
static void
|
||||
GLES2_ResetState(SDL_Renderer *renderer)
|
||||
{
|
||||
GLES2_DriverContext *rdata = (GLES2_DriverContext *) renderer->driverdata;
|
||||
|
||||
if (SDL_CurrentContext == rdata->context) {
|
||||
GLES2_UpdateViewport(renderer);
|
||||
} else {
|
||||
GLES2_ActivateRenderer(renderer);
|
||||
}
|
||||
|
||||
rdata->current.blendMode = -1;
|
||||
rdata->current.scaleMode = 0;
|
||||
rdata->current.tex_coords = SDL_FALSE;
|
||||
|
||||
glEnableVertexAttribArray(GLES2_ATTRIBUTE_POSITION);
|
||||
glDisableVertexAttribArray(GLES2_ATTRIBUTE_TEXCOORD);
|
||||
}
|
||||
|
||||
static SDL_Renderer *
|
||||
GLES2_CreateRenderer(SDL_Window *window, Uint32 flags)
|
||||
{
|
||||
|
@ -1166,6 +1178,9 @@ GLES2_CreateRenderer(SDL_Window *window, Uint32 flags)
|
|||
renderer->RenderPresent = &GLES2_RenderPresent;
|
||||
renderer->DestroyTexture = &GLES2_DestroyTexture;
|
||||
renderer->DestroyRenderer = &GLES2_DestroyRenderer;
|
||||
|
||||
GLES2_ResetState(renderer);
|
||||
|
||||
return renderer;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue