ref: bcf5513495528f7943e96ab48bd5c0cfe9d556f7
parent: 1d9446d4258c012f280d3e2d54ce49175f7432cb
author: Clownacy <Clownacy@users.noreply.github.com>
date: Mon Sep 7 21:17:07 EDT 2020
Updated Wii U renderer Turns out it doesn't even batch the font stuff. I'll need to add that later.
--- a/src/Backends/Rendering/WiiU.cpp
+++ b/src/Backends/Rendering/WiiU.cpp
@@ -44,12 +44,11 @@
unsigned char *lock_buffer; // TODO - Dumb
} RenderBackend_Surface;
-typedef struct RenderBackend_Glyph
+typedef struct RenderBackend_GlyphAtlas
{
+ size_t size;
GX2Texture texture;
- unsigned int width;
- unsigned int height;
-} RenderBackend_Glyph;
+} RenderBackend_GlyphAtlas;
typedef struct Viewport
{
@@ -728,75 +727,74 @@
}
}
-RenderBackend_Glyph* RenderBackend_LoadGlyph(const unsigned char *pixels, unsigned int width, unsigned int height, int pitch)
+RenderBackend_GlyphAtlas* RenderBackend_CreateGlyphAtlas(size_t size)
{
- RenderBackend_Glyph *glyph = (RenderBackend_Glyph*)malloc(sizeof(RenderBackend_Glyph));
+ RenderBackend_GlyphAtlas *atlas = (RenderBackend_GlyphAtlas*)malloc(sizeof(RenderBackend_GlyphAtlas));
- if (glyph != NULL)
+ if (atlas != NULL)
{
- glyph->width = width;
- glyph->height = height;
-
+ atlas->size = size;
// Initialise texture
- memset(&glyph->texture, 0, sizeof(glyph->texture));
- glyph->texture.surface.width = width;
- glyph->texture.surface.height = height;
- glyph->texture.surface.format = GX2_SURFACE_FORMAT_UNORM_R8;
- glyph->texture.surface.depth = 1;
- glyph->texture.surface.dim = GX2_SURFACE_DIM_TEXTURE_2D;
- glyph->texture.surface.tileMode = GX2_TILE_MODE_LINEAR_ALIGNED;
- glyph->texture.surface.mipLevels = 1;
- glyph->texture.viewNumMips = 1;
- glyph->texture.viewNumSlices = 1;
- glyph->texture.compMap = 0x00000000;
- GX2CalcSurfaceSizeAndAlignment(&glyph->texture.surface);
- GX2InitTextureRegs(&glyph->texture);
+ memset(&atlas->texture, 0, sizeof(atlas->texture));
+ atlas->texture.surface.width = size;
+ atlas->texture.surface.height = size;
+ atlas->texture.surface.format = GX2_SURFACE_FORMAT_UNORM_R8;
+ atlas->texture.surface.depth = 1;
+ atlas->texture.surface.dim = GX2_SURFACE_DIM_TEXTURE_2D;
+ atlas->texture.surface.tileMode = GX2_TILE_MODE_LINEAR_ALIGNED;
+ atlas->texture.surface.mipLevels = 1;
+ atlas->texture.viewNumMips = 1;
+ atlas->texture.viewNumSlices = 1;
+ atlas->texture.compMap = 0x00000000;
+ GX2CalcSurfaceSizeAndAlignment(&atlas->texture.surface);
+ GX2InitTextureRegs(&atlas->texture);
- if (GX2RCreateSurface(&glyph->texture.surface, (GX2RResourceFlags)(GX2R_RESOURCE_BIND_TEXTURE |
+ if (GX2RCreateSurface(&atlas->texture.surface, (GX2RResourceFlags)(GX2R_RESOURCE_BIND_TEXTURE |
GX2R_RESOURCE_USAGE_CPU_WRITE | GX2R_RESOURCE_USAGE_CPU_READ |
GX2R_RESOURCE_USAGE_GPU_WRITE | GX2R_RESOURCE_USAGE_GPU_READ)))
{
- // Convert from RGB24 to RGBA32, and upload it to the GPU texture
- unsigned char *framebuffer = (unsigned char*)GX2RLockSurfaceEx(&glyph->texture.surface, 0, (GX2RResourceFlags)0);
-
- const unsigned char *in_pointer = pixels;
- unsigned char *out_pointer = framebuffer;
-
- for (size_t y = 0; y < height; ++y)
- {
- memcpy(out_pointer, in_pointer, width);
-
- in_pointer += pitch;
- out_pointer += glyph->texture.surface.pitch;
- }
-
- GX2RUnlockSurfaceEx(&glyph->texture.surface, 0, (GX2RResourceFlags)0);
-
- return glyph;
+ return atlas;
}
else
{
- Backend_PrintError("GX2RCreateSurface failed in RenderBackend_LoadGlyph");
+ Backend_PrintError("GX2RCreateSurface failed in RenderBackend_CreateGlyphAtlas");
}
- free(glyph);
+ free(atlas);
}
-
return NULL;
}
-void RenderBackend_UnloadGlyph(RenderBackend_Glyph *glyph)
+void RenderBackend_DestroyGlyphAtlas(RenderBackend_GlyphAtlas *atlas)
{
- if (glyph != NULL)
+ GX2RDestroySurfaceEx(&atlas->texture.surface, (GX2RResourceFlags)0);
+ free(atlas);
+}
+
+void RenderBackend_UploadGlyph(RenderBackend_GlyphAtlas *atlas, size_t x, size_t y, const unsigned char *pixels, size_t width, size_t height)
+{
+ // Convert from RGB24 to RGBA32, and upload it to the GPU texture
+ unsigned char *buffer = (unsigned char*)GX2RLockSurfaceEx(&atlas->texture.surface, 0, (GX2RResourceFlags)0);
+
+ const unsigned char *in_pointer = pixels;
+ unsigned char *out_pointer = &buffer[y * atlas->texture.surface.pitch + x];
+
+ for (size_t iy = 0; iy < height; ++iy)
{
- GX2RDestroySurfaceEx(&glyph->texture.surface, (GX2RResourceFlags)0);
- free(glyph);
+ memcpy(out_pointer, in_pointer, width);
+
+ in_pointer += width;
+ out_pointer += atlas->texture.surface.pitch;
}
+
+ GX2RUnlockSurfaceEx(&atlas->texture.surface, 0, (GX2RResourceFlags)0);
}
-void RenderBackend_PrepareToDrawGlyphs(RenderBackend_Surface *destination_surface, const unsigned char *colour_channels)
+void RenderBackend_PrepareToDrawGlyphs(RenderBackend_GlyphAtlas *atlas, RenderBackend_Surface *destination_surface, const unsigned char *colour_channels)
{
+ (void)atlas;
+
FlushVertexBuffer();
last_render_mode = MODE_BLANK;
last_source_surface = NULL;
@@ -815,11 +813,8 @@
GX2SetColorControl(GX2_LOGIC_OP_COPY, 0xFF, FALSE, TRUE);
}
-void RenderBackend_DrawGlyph(RenderBackend_Glyph *glyph, long x, long y)
+void RenderBackend_DrawGlyph(RenderBackend_GlyphAtlas *atlas, long x, long y, size_t glyph_x, size_t glyph_y, size_t glyph_width, size_t glyph_height)
{
- if (glyph == NULL)
- return;
-
// Make sure the buffers aren't currently being used before we modify them
GX2DrawDone();
@@ -826,19 +821,19 @@
VertexBufferSlot *vertex_buffer_slot = (VertexBufferSlot*)GX2RLockBufferEx(&vertex_buffer, (GX2RResourceFlags)0);
// Set vertex position buffer
- const float destination_left = x;
- const float destination_top = y;
- const float destination_right = x + glyph->width;
- const float destination_bottom = y + glyph->height;
+ const float vertex_left = x;
+ const float vertex_top = y;
+ const float vertex_right = x + glyph_width;
+ const float vertex_bottom = y + glyph_height;
- vertex_buffer_slot->vertices[0].position.x = destination_left;
- vertex_buffer_slot->vertices[0].position.y = destination_top;
- vertex_buffer_slot->vertices[1].position.x = destination_right;
- vertex_buffer_slot->vertices[1].position.y = destination_top;
- vertex_buffer_slot->vertices[2].position.x = destination_right;
- vertex_buffer_slot->vertices[2].position.y = destination_bottom;
- vertex_buffer_slot->vertices[3].position.x = destination_left;
- vertex_buffer_slot->vertices[3].position.y = destination_bottom;
+ vertex_buffer_slot->vertices[0].position.x = vertex_left;
+ vertex_buffer_slot->vertices[0].position.y = vertex_top;
+ vertex_buffer_slot->vertices[1].position.x = vertex_right;
+ vertex_buffer_slot->vertices[1].position.y = vertex_top;
+ vertex_buffer_slot->vertices[2].position.x = vertex_right;
+ vertex_buffer_slot->vertices[2].position.y = vertex_bottom;
+ vertex_buffer_slot->vertices[3].position.x = vertex_left;
+ vertex_buffer_slot->vertices[3].position.y = vertex_bottom;
for (unsigned int i = 0; i < 4; ++i)
{
@@ -851,16 +846,31 @@
vertex_buffer_slot->vertices[i].position.y += 1.0f;
}
- // Set texture coordinate buffer
- vertex_buffer_slot->vertices[0].texture.x = 0.0f;
- vertex_buffer_slot->vertices[0].texture.y = 0.0f;
- vertex_buffer_slot->vertices[1].texture.x = 1.0f;
- vertex_buffer_slot->vertices[1].texture.y = 0.0f;
- vertex_buffer_slot->vertices[2].texture.x = 1.0f;
- vertex_buffer_slot->vertices[2].texture.y = 1.0f;
- vertex_buffer_slot->vertices[3].texture.x = 0.0f;
- vertex_buffer_slot->vertices[3].texture.y = 1.0f;
+ const float texture_left = glyph_x / (float)atlas->size;
+ const float texture_top = glyph_y / (float)atlas->size;
+ const float texture_right = (glyph_x + glyph_width) / (float)atlas->size;
+ const float texture_bottom = (glyph_y + glyph_height) / (float)atlas->size;
+ // Set texture coordinate buffer
+#if 0
+ vertex_buffer_slot->vertices[0].texture.x = 0;
+ vertex_buffer_slot->vertices[0].texture.y = 0;
+ vertex_buffer_slot->vertices[1].texture.x = 1;
+ vertex_buffer_slot->vertices[1].texture.y = 0;
+ vertex_buffer_slot->vertices[2].texture.x = 1;
+ vertex_buffer_slot->vertices[2].texture.y = 1;
+ vertex_buffer_slot->vertices[3].texture.x = 0;
+ vertex_buffer_slot->vertices[3].texture.y = 1;
+#else
+ vertex_buffer_slot->vertices[0].texture.x = texture_left;
+ vertex_buffer_slot->vertices[0].texture.y = texture_top;
+ vertex_buffer_slot->vertices[1].texture.x = texture_right;
+ vertex_buffer_slot->vertices[1].texture.y = texture_top;
+ vertex_buffer_slot->vertices[2].texture.x = texture_right;
+ vertex_buffer_slot->vertices[2].texture.y = texture_bottom;
+ vertex_buffer_slot->vertices[3].texture.x = texture_left;
+ vertex_buffer_slot->vertices[3].texture.y = texture_bottom;
+#endif
GX2RUnlockBufferEx(&vertex_buffer, (GX2RResourceFlags)0);
// Draw to the selected texture, instead of the screen
@@ -875,7 +885,7 @@
// Bind misc. data
GX2SetPixelSampler(&sampler, glyph_shader.pixelShader->samplerVars[0].location);
- GX2SetPixelTexture(&glyph->texture, glyph_shader.pixelShader->samplerVars[0].location);
+ GX2SetPixelTexture(&atlas->texture, glyph_shader.pixelShader->samplerVars[0].location);
GX2RSetAttributeBuffer(&vertex_buffer, 0, sizeof(Vertex), offsetof(Vertex, position));
GX2RSetAttributeBuffer(&vertex_buffer, 1, sizeof(Vertex), offsetof(Vertex, texture));