Fix the other rendering backends
Also finished ripping-out the sub-pixel support
This commit is contained in:
parent
eeed719c16
commit
1b2d4fdb4d
5 changed files with 55 additions and 235 deletions
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue