From 988e0cf72a6207dcb189026b7bdbb2723af1b601 Mon Sep 17 00:00:00 2001 From: Adam Date: Thu, 28 Nov 2024 01:04:45 +0000 Subject: [PATCH] library: sort out vertex2d UV API confusion --- src/library/doc.texi | 22 ++++++++++++++++------ src/library/gl.c | 12 +++++++----- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/library/doc.texi b/src/library/doc.texi index d09e671..21f550a 100644 --- a/src/library/doc.texi +++ b/src/library/doc.texi @@ -1939,6 +1939,18 @@ associated image in the batch's texture atlas, in pixel coordinates. Given an index of a vertex in a batch, returns the width and height of its associated image in the batch's texture atlas, in pixel coordinates. +The game engine has a strangely complex system for these values, which +is described in the next paragraph. This is the type of thing which the +Bolt API would normally make simple using abstraction, but this can't +easily be abstracted, so the values are left exactly as-is. Plugins will +need to account for everything in the following paragraph if they intend +to work with UV coordinates. + +If the U value is less than -60000, then the texture info for this +vertex should be ignored and RGBA values of 1.0 should be used. +Otherwise, if a UV value is negative, it should be negated (i.e. made +positive) and then clamped to the edges of the sub-image. If a UV value +is positive, it should wrap within the sub-image. @node batch2d-vertexuv @subsection vertexuv @@ -1948,12 +1960,10 @@ Given an index of a vertex in a batch, returns the vertex's associated 0.0 - 1.0. Unlike with 3D render events, these UVs are relative to the entire -texture atlas, not to the sub-image. However they may fall outside the -bounds of the sub-image, in which case they're usually expected to wrap -around within it. - -The values will be floating-point numbers in the range 0.0 - 1.0. They -are relative to image in the texture atlas. +texture atlas, not to the sub-image. There are a few other things to be +aware of when working with Render2D UVs. @ref{batch2d-vertexatlaswh,, +vertexatlaswh}. Plugins will need to negotiate all of this correctly if +they intend to work with UVs. @node batch2d-vertexcolour @subsection vertexcolour diff --git a/src/library/gl.c b/src/library/gl.c index 31f29d2..6e912bd 100644 --- a/src/library/gl.c +++ b/src/library/gl.c @@ -1689,12 +1689,15 @@ void _bolt_gl_onViewport(GLint x, GLint y, GLsizei width, GLsizei height) { static void _bolt_gl_plugin_drawelements_vertex2d_xy(size_t index, void* userdata, int32_t* out) { struct GLPluginDrawElementsVertex2DUserData* data = userdata; if (_bolt_get_attr_binding_int(data->c, data->position, data->indices[index], 2, out)) { - out[1] = (int32_t)data->screen_height - (out[1] + 1); + // this line would seem like it introduces an off-by-one error, but the same error actually exists in the game engine + // causing the UI to be drawn one pixel higher than the top of the screen, so we're just accounting for that here. + out[1] = (int32_t)data->screen_height - out[1]; } else { float pos[2]; _bolt_get_attr_binding(data->c, data->position, data->indices[index], 2, pos); out[0] = (int32_t)roundf(pos[0]); - out[1] = (int32_t)data->screen_height - ((int32_t)roundf(pos[1]) + 1); + // as above + out[1] = (int32_t)data->screen_height - (int32_t)roundf(pos[1]); } } @@ -1710,9 +1713,8 @@ static void _bolt_gl_plugin_drawelements_vertex2d_atlas_wh(size_t index, void* u struct GLPluginDrawElementsVertex2DUserData* data = userdata; float wh[2]; _bolt_get_attr_binding(data->c, data->atlas_size, data->indices[index], 2, wh); - // these are negative for some reason - out[0] = -(int32_t)roundf(wh[0] * data->atlas->width); - out[1] = -(int32_t)roundf(wh[1] * data->atlas->height); + out[0] = (int32_t)roundf(wh[0] * data->atlas->width); + out[1] = (int32_t)roundf(wh[1] * data->atlas->height); } static void _bolt_gl_plugin_drawelements_vertex2d_uv(size_t index, void* userdata, double* out) {