Fix the other rendering backends

Also finished ripping-out the sub-pixel support
This commit is contained in:
Clownacy 2020-02-01 22:57:07 +00:00
parent eeed719c16
commit 1b2d4fdb4d
5 changed files with 55 additions and 235 deletions

View file

@ -18,7 +18,6 @@ unsigned char* Backend_LockSurface(Backend_Surface *surface, unsigned int *pitch
void Backend_UnlockSurface(Backend_Surface *surface, unsigned int width, unsigned int height);
void Backend_Blit(Backend_Surface *source_surface, const RECT *rect, Backend_Surface *destination_surface, long x, long y, BOOL colour_key);
void Backend_ColourFill(Backend_Surface *surface, const RECT *rect, unsigned char red, unsigned char green, unsigned char blue);
BOOL Backend_SupportsSubpixelGlyphs(void);
Backend_Glyph* Backend_LoadGlyph(const unsigned char *pixels, unsigned int width, unsigned int height, int pitch);
void Backend_UnloadGlyph(Backend_Glyph *glyph);
void Backend_PrepareToDrawGlyphs(Backend_Surface *destination_surface, const unsigned char *colour_channels);

View file

@ -75,13 +75,10 @@ static SDL_GLContext context;
static GLuint program_texture;
static GLuint program_texture_colour_key;
static GLuint program_colour_fill;
static GLuint program_glyph_normal;
static GLuint program_glyph_subpixel_part1;
static GLuint program_glyph_subpixel_part2;
static GLuint program_glyph;
static GLint program_colour_fill_uniform_colour;
static GLint program_glyph_normal_uniform_colour;
static GLint program_glyph_subpixel_part2_uniform_colour;
static GLint program_glyph_uniform_colour;
#ifndef USE_OPENGLES2
static GLuint vertex_array_id;
@ -161,7 +158,7 @@ void main() \
} \
";
static const GLchar *fragment_shader_glyph_normal = " \
static const GLchar *fragment_shader_glyph = " \
#version 100\n \
precision mediump float; \
uniform sampler2D tex; \
@ -172,29 +169,6 @@ void main() \
gl_FragColor = colour * vec4(1.0, 1.0, 1.0, texture2D(tex, texture_coordinates).r); \
} \
";
static const GLchar *fragment_shader_glyph_subpixel_part1 = " \
#version 100\n \
precision mediump float; \
uniform sampler2D tex; \
varying vec2 texture_coordinates; \
void main() \
{ \
gl_FragColor = texture2D(tex, texture_coordinates); \
} \
";
static const GLchar *fragment_shader_glyph_subpixel_part2 = " \
#version 100\n \
precision mediump float; \
uniform sampler2D tex; \
uniform vec4 colour; \
varying vec2 texture_coordinates; \
void main() \
{ \
gl_FragColor = colour * texture2D(tex, texture_coordinates); \
} \
";
#else
static const GLchar *vertex_shader_plain = " \
#version 150 core\n \
@ -254,7 +228,7 @@ void main() \
} \
";
static const GLchar *fragment_shader_glyph_normal = " \
static const GLchar *fragment_shader_glyph = " \
#version 150 core\n \
uniform sampler2D tex; \
uniform vec4 colour; \
@ -265,29 +239,6 @@ void main() \
fragment = colour * vec4(1.0, 1.0, 1.0, texture(tex, texture_coordinates).r); \
} \
";
static const GLchar *fragment_shader_glyph_subpixel_part1 = " \
#version 150 core\n \
uniform sampler2D tex; \
in vec2 texture_coordinates; \
out vec4 fragment; \
void main() \
{ \
fragment = texture(tex, texture_coordinates); \
} \
";
static const GLchar *fragment_shader_glyph_subpixel_part2 = " \
#version 150 core\n \
uniform sampler2D tex; \
uniform vec4 colour; \
in vec2 texture_coordinates; \
out vec4 fragment; \
void main() \
{ \
fragment = colour * texture(tex, texture_coordinates); \
} \
";
#endif
/*
static void GLAPIENTRY MessageCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void* userParam)
@ -427,8 +378,8 @@ static void GlyphBatch_Draw(spritebatch_sprite_t* sprites, int count, int textur
last_green = glyph_colour_channels[1];
last_blue = glyph_colour_channels[2];
glUseProgram(program_glyph_normal);
glUniform4f(program_glyph_normal_uniform_colour, glyph_colour_channels[0] / 255.0f, glyph_colour_channels[1] / 255.0f, glyph_colour_channels[2] / 255.0f, 1.0f);
glUseProgram(program_glyph);
glUniform4f(program_glyph_uniform_colour, glyph_colour_channels[0] / 255.0f, glyph_colour_channels[1] / 255.0f, glyph_colour_channels[2] / 255.0f, 1.0f);
// Point our framebuffer to the destination texture
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, glyph_destination_surface->texture_id, 0);
@ -613,16 +564,13 @@ Backend_Surface* Backend_Init(const char *title, int width, int height, BOOL ful
program_texture = CompileShader(vertex_shader_texture, fragment_shader_texture);
program_texture_colour_key = CompileShader(vertex_shader_texture, fragment_shader_texture_colour_key);
program_colour_fill = CompileShader(vertex_shader_plain, fragment_shader_colour_fill);
program_glyph_normal = CompileShader(vertex_shader_texture, fragment_shader_glyph_normal);
program_glyph_subpixel_part1 = CompileShader(vertex_shader_texture, fragment_shader_glyph_subpixel_part1);
program_glyph_subpixel_part2 = CompileShader(vertex_shader_texture, fragment_shader_glyph_subpixel_part2);
program_glyph = CompileShader(vertex_shader_texture, fragment_shader_glyph);
if (program_texture != 0 && program_texture_colour_key != 0 && program_colour_fill != 0 && program_glyph_normal != 0 && program_glyph_subpixel_part1 != 0 && program_glyph_subpixel_part2 != 0)
if (program_texture != 0 && program_texture_colour_key != 0 && program_colour_fill != 0 && program_glyph != 0)
{
// Get shader uniforms
program_colour_fill_uniform_colour = glGetUniformLocation(program_colour_fill, "colour");
program_glyph_normal_uniform_colour = glGetUniformLocation(program_glyph_normal, "colour");
program_glyph_subpixel_part2_uniform_colour = glGetUniformLocation(program_glyph_subpixel_part2, "colour");
program_glyph_uniform_colour = glGetUniformLocation(program_glyph, "colour");
// Set up framebuffer (used for surface-to-surface blitting)
glGenFramebuffers(1, &framebuffer_id);
@ -662,14 +610,8 @@ Backend_Surface* Backend_Init(const char *title, int width, int height, BOOL ful
return &framebuffer;
}
if (program_glyph_subpixel_part2 != 0)
glDeleteProgram(program_glyph_subpixel_part2);
if (program_glyph_subpixel_part1 != 0)
glDeleteProgram(program_glyph_subpixel_part1);
if (program_glyph_normal != 0)
glDeleteProgram(program_glyph_normal);
if (program_glyph != 0)
glDeleteProgram(program_glyph);
if (program_colour_fill != 0)
glDeleteProgram(program_colour_fill);
@ -727,9 +669,7 @@ void Backend_Deinit(void)
glDeleteTextures(1, &framebuffer.texture_id);
glDeleteFramebuffers(1, &framebuffer_id);
glDeleteProgram(program_glyph_subpixel_part2);
glDeleteProgram(program_glyph_subpixel_part1);
glDeleteProgram(program_glyph_normal);
glDeleteProgram(program_glyph);
glDeleteProgram(program_colour_fill);
glDeleteProgram(program_texture_colour_key);
glDeleteProgram(program_texture);
@ -1018,11 +958,6 @@ void Backend_ColourFill(Backend_Surface *surface, const RECT *rect, unsigned cha
vertex_buffer_slot->vertices[1][2].vertex_coordinate.y = vertex_bottom;
}
BOOL Backend_SupportsSubpixelGlyphs(void)
{
return TRUE;
}
Backend_Glyph* Backend_LoadGlyph(const unsigned char *pixels, unsigned int width, unsigned int height, int pitch)
{
Backend_Glyph *glyph = (Backend_Glyph*)malloc(sizeof(Backend_Glyph));

View file

@ -173,12 +173,7 @@ void Backend_ColourFill(Backend_Surface *surface, const RECT *rect, unsigned cha
SDL_FillRect(surface->sdlsurface, &destination_rect, SDL_MapRGB(surface->sdlsurface->format, red, green, blue));
}
BOOL Backend_SupportsSubpixelGlyphs(void)
{
return FALSE; // SDL_Surfaces don't have per-component alpha
}
Backend_Glyph* Backend_LoadGlyph(const unsigned char *pixels, unsigned int width, unsigned int height, int pitch, FontPixelMode pixel_mode)
Backend_Glyph* Backend_LoadGlyph(const unsigned char *pixels, unsigned int width, unsigned int height, int pitch)
{
Backend_Glyph *glyph = (Backend_Glyph*)malloc(sizeof(Backend_Glyph));
@ -193,45 +188,18 @@ Backend_Glyph* Backend_LoadGlyph(const unsigned char *pixels, unsigned int width
return NULL;
}
switch (pixel_mode)
for (unsigned int y = 0; y < height; ++y)
{
case FONT_PIXEL_MODE_LCD:
// Unsupported
break;
const unsigned char *source_pointer = pixels + y * pitch;
unsigned char *destination_pointer = (unsigned char*)glyph->sdlsurface->pixels + y * glyph->sdlsurface->pitch;
case FONT_PIXEL_MODE_GRAY:
for (unsigned int y = 0; y < height; ++y)
{
const unsigned char *source_pointer = pixels + y * pitch;
unsigned char *destination_pointer = (unsigned char*)glyph->sdlsurface->pixels + y * glyph->sdlsurface->pitch;
for (unsigned int x = 0; x < width; ++x)
{
*destination_pointer++ = 0xFF;
*destination_pointer++ = 0xFF;
*destination_pointer++ = 0xFF;
*destination_pointer++ = *source_pointer++;
}
}
break;
case FONT_PIXEL_MODE_MONO:
for (unsigned int y = 0; y < height; ++y)
{
const unsigned char *source_pointer = pixels + y * pitch;
unsigned char *destination_pointer = (unsigned char*)glyph->sdlsurface->pixels + y * glyph->sdlsurface->pitch;
for (unsigned int x = 0; x < width; ++x)
{
*destination_pointer++ = 0xFF;
*destination_pointer++ = 0xFF;
*destination_pointer++ = 0xFF;
*destination_pointer++ = *source_pointer++ ? 0xFF : 0;
}
}
break;
for (unsigned int x = 0; x < width; ++x)
{
*destination_pointer++ = 0xFF;
*destination_pointer++ = 0xFF;
*destination_pointer++ = 0xFF;
*destination_pointer++ = *source_pointer++;
}
}
return glyph;
@ -272,6 +240,11 @@ void Backend_DrawGlyph(Backend_Glyph *glyph, long x, long y)
SDL_BlitSurface(glyph->sdlsurface, NULL, glyph_destination_sdlsurface, &rect);
}
void Backend_FlushGlyphs(void)
{
}
void Backend_HandleRenderTargetLoss(void)
{
// No problem for us

View file

@ -357,11 +357,6 @@ void Backend_ColourFill(Backend_Surface *surface, const RECT *rect, unsigned cha
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
}
BOOL Backend_SupportsSubpixelGlyphs(void)
{
return FALSE; // SDL_Textures don't have per-component alpha
}
Backend_Glyph* Backend_LoadGlyph(const unsigned char *pixels, unsigned int width, unsigned int height, int pitch)
{
Backend_Glyph *glyph = (Backend_Glyph*)malloc(sizeof(Backend_Glyph));

View file

@ -26,7 +26,6 @@ typedef struct Backend_Glyph
void *pixels;
unsigned int width;
unsigned int height;
FontPixelMode pixel_mode;
} Backend_Glyph;
static SDL_Window *window;
@ -298,69 +297,33 @@ void Backend_ColourFill(Backend_Surface *surface, const RECT *rect, unsigned cha
}
}
BOOL Backend_SupportsSubpixelGlyphs(void)
{
return TRUE; // It's a software renderer, baby
}
Backend_Glyph* Backend_LoadGlyph(const unsigned char *pixels, unsigned int width, unsigned int height, int pitch, FontPixelMode pixel_mode)
Backend_Glyph* Backend_LoadGlyph(const unsigned char *pixels, unsigned int width, unsigned int height, int pitch)
{
Backend_Glyph *glyph = (Backend_Glyph*)malloc(sizeof(Backend_Glyph));
if (glyph == NULL)
return NULL;
switch (pixel_mode)
glyph->pixels = malloc(width * height * sizeof(float));
if (glyph->pixels == NULL)
{
case FONT_PIXEL_MODE_LCD:
case FONT_PIXEL_MODE_GRAY:
{
glyph->pixels = malloc(width * height * sizeof(float));
if (glyph->pixels == NULL)
{
free(glyph);
return NULL;
}
float *destination_pointer = (float*)glyph->pixels;
for (unsigned int y = 0; y < height; ++y)
{
const unsigned char *source_pointer = pixels + y * pitch;
for (unsigned int x = 0; x < width; ++x)
*destination_pointer++ = *source_pointer++ / 255.0f;
}
break;
}
case FONT_PIXEL_MODE_MONO:
{
glyph->pixels = malloc(width * height);
if (glyph->pixels == NULL)
{
free(glyph);
return NULL;
}
for (unsigned int y = 0; y < height; ++y)
{
const unsigned char *source_pointer = pixels + y * pitch;
unsigned char *destination_pointer = (unsigned char*)glyph->pixels + y * width;
memcpy(destination_pointer, source_pointer, width);
}
break;
}
free(glyph);
return NULL;
}
glyph->width = (pixel_mode == FONT_PIXEL_MODE_LCD ? width / 3 : width);
float *destination_pointer = (float*)glyph->pixels;
for (unsigned int y = 0; y < height; ++y)
{
const unsigned char *source_pointer = pixels + y * pitch;
for (unsigned int x = 0; x < width; ++x)
*destination_pointer++ = *source_pointer++ / 255.0f;
}
glyph->width = width;
glyph->height = height;
glyph->pixel_mode = pixel_mode;
return glyph;
}
@ -389,65 +352,20 @@ void Backend_DrawGlyph(Backend_Glyph *glyph, long x, long y)
if (glyph == NULL)
return;
switch (glyph->pixel_mode)
for (unsigned int iy = MAX(-y, 0); y + iy < MIN(y + glyph->height, glyph_destination_surface->height); ++iy)
{
case FONT_PIXEL_MODE_LCD:
for (unsigned int iy = MAX(-y, 0); y + iy < MIN(y + glyph->height, glyph_destination_surface->height); ++iy)
for (unsigned int ix = MAX(-x, 0); x + ix < MIN(x + glyph->width, glyph_destination_surface->width); ++ix)
{
const float alpha = ((float*)glyph->pixels)[iy * glyph->width + ix];
if (alpha)
{
for (unsigned int ix = MAX(-x, 0); x + ix < MIN(x + glyph->width, glyph_destination_surface->width); ++ix)
{
const float *font_pixel = (float*)glyph->pixels + (iy * glyph->width + ix) * 3;
unsigned char *bitmap_pixel = glyph_destination_surface->pixels + (y + iy) * glyph_destination_surface->pitch + (x + ix) * 3;
if (font_pixel[0] || font_pixel[1] || font_pixel[2])
{
unsigned char *bitmap_pixel = glyph_destination_surface->pixels + (y + iy) * glyph_destination_surface->pitch + (x + ix) * 3;
for (unsigned int j = 0; j < 3; ++j)
{
const float alpha = font_pixel[j];
bitmap_pixel[j] = (unsigned char)((glyph_colour_channels[j] * alpha) + (bitmap_pixel[j] * (1.0f - alpha))); // Alpha blending
}
}
}
for (unsigned int j = 0; j < 3; ++j)
bitmap_pixel[j] = (unsigned char)((glyph_colour_channels[j] * alpha) + (bitmap_pixel[j] * (1.0f - alpha))); // Alpha blending
}
break;
case FONT_PIXEL_MODE_GRAY:
for (unsigned int iy = MAX(-y, 0); y + iy < MIN(y + glyph->height, glyph_destination_surface->height); ++iy)
{
for (unsigned int ix = MAX(-x, 0); x + ix < MIN(x + glyph->width, glyph_destination_surface->width); ++ix)
{
const float alpha = ((float*)glyph->pixels)[iy * glyph->width + ix];
if (alpha)
{
unsigned char *bitmap_pixel = glyph_destination_surface->pixels + (y + iy) * glyph_destination_surface->pitch + (x + ix) * 3;
for (unsigned int j = 0; j < 3; ++j)
bitmap_pixel[j] = (unsigned char)((glyph_colour_channels[j] * alpha) + (bitmap_pixel[j] * (1.0f - alpha))); // Alpha blending
}
}
}
break;
case FONT_PIXEL_MODE_MONO:
for (unsigned int iy = MAX(-y, 0); y + iy < MIN(y + glyph->height, glyph_destination_surface->height); ++iy)
{
for (unsigned int ix = MAX(-x, 0); x + ix < MIN(x + glyph->width, glyph_destination_surface->width); ++ix)
{
if (((unsigned char*)glyph->pixels)[iy * glyph->width + ix])
{
unsigned char *bitmap_pixel = glyph_destination_surface->pixels + (y + iy) * glyph_destination_surface->pitch + (x + ix) * 3;
for (unsigned int j = 0; j < 3; ++j)
bitmap_pixel[j] = glyph_colour_channels[j];
}
}
}
break;
}
}
}