library: texturedata getter

This commit is contained in:
Adam
2024-03-07 03:49:21 +00:00
parent 7e652519e6
commit ad25587682
5 changed files with 63 additions and 2 deletions

View File

@@ -1237,6 +1237,7 @@ void _bolt_gl_onDrawElements(uint32_t mode, unsigned int count, uint32_t type, c
batch.texture_functions.id = _bolt_gl_plugin_texture_id;
batch.texture_functions.size = _bolt_gl_plugin_texture_size;
batch.texture_functions.compare = _bolt_gl_plugin_texture_compare;
batch.texture_functions.data = _bolt_gl_plugin_texture_data;
_bolt_plugin_handle_2d(&batch);
}
@@ -1279,6 +1280,7 @@ void _bolt_gl_onDrawElements(uint32_t mode, unsigned int count, uint32_t type, c
render.texture_functions.id = _bolt_gl_plugin_texture_id;
render.texture_functions.size = _bolt_gl_plugin_texture_size;
render.texture_functions.compare = _bolt_gl_plugin_texture_compare;
render.texture_functions.data = _bolt_gl_plugin_texture_data;
_bolt_plugin_handle_3d(&render);
}
@@ -1496,6 +1498,12 @@ uint8_t _bolt_gl_plugin_texture_compare(void* userdata, size_t x, size_t y, size
return !memcmp(tex->data + start_offset, data, len);
}
uint8_t* _bolt_gl_plugin_texture_data(void* userdata, size_t x, size_t y) {
const struct GLPluginTextureUserData* data = userdata;
const struct GLTexture2D* tex = data->tex;
return tex->data + (tex->width * y * 4) + (x * 4);
}
void _bolt_gl_plugin_surface_init(struct SurfaceFunctions* functions, unsigned int width, unsigned int height) {
struct PluginSurfaceUserdata* userdata = malloc(sizeof(struct PluginSurfaceUserdata));
struct GLContext* c = _bolt_context();

View File

@@ -316,6 +316,7 @@ struct GLPluginTextureUserData {
size_t _bolt_gl_plugin_texture_id(void* userdata);
void _bolt_gl_plugin_texture_size(void* userdata, size_t* out);
uint8_t _bolt_gl_plugin_texture_compare(void* userdata, size_t x, size_t y, size_t len, const unsigned char* data);
uint8_t* _bolt_gl_plugin_texture_data(void* userdata, size_t x, size_t y);
void _bolt_gl_plugin_surface_init(struct SurfaceFunctions* out, unsigned int width, unsigned int height);
void _bolt_gl_plugin_surface_destroy(void* userdata);

View File

@@ -122,6 +122,7 @@ void _bolt_plugin_init(void (*_surface_init)(struct SurfaceFunctions*, unsigned
API_ADD_SUB(textureid, batch2d)
API_ADD_SUB(texturesize, batch2d)
API_ADD_SUB(texturecompare, batch2d)
API_ADD_SUB(texturedata, batch2d)
API_ADD_SUB_ALIAS(vertexcolour, vertexcolor, batch2d)
lua_settable(state, -3);
lua_settable(state, LUA_REGISTRYINDEX);
@@ -140,6 +141,7 @@ void _bolt_plugin_init(void (*_surface_init)(struct SurfaceFunctions*, unsigned
API_ADD_SUB(textureid, render3d)
API_ADD_SUB(texturesize, render3d)
API_ADD_SUB(texturecompare, render3d)
API_ADD_SUB(texturedata, render3d)
API_ADD_SUB_ALIAS(vertexcolour, vertexcolor, render3d)
lua_settable(state, -3);
lua_settable(state, LUA_REGISTRYINDEX);
@@ -438,6 +440,17 @@ static int api_batch2d_texturecompare(lua_State* state) {
return 1;
}
static int api_batch2d_texturedata(lua_State* state) {
_bolt_check_argc(state, 4, "batch2d_texturedata");
struct RenderBatch2D* render = lua_touserdata(state, 1);
const size_t x = lua_tointeger(state, 2);
const size_t y = lua_tointeger(state, 3);
const size_t len = lua_tointeger(state, 4);
const uint8_t* ret = render->texture_functions.data(render->texture_functions.userdata, x, y);
lua_pushlstring(state, (const char*)ret, len);
return 1;
}
static int api_minimap_angle(lua_State* state) {
_bolt_check_argc(state, 1, "minimap_angle");
struct RenderMinimapEvent* render = lua_touserdata(state, 1);
@@ -604,3 +617,14 @@ static int api_render3d_texturecompare(lua_State* state) {
lua_pushboolean(state, match);
return 1;
}
static int api_render3d_texturedata(lua_State* state) {
_bolt_check_argc(state, 4, "render3d_texturedata");
struct Render3D* render = lua_touserdata(state, 1);
const size_t x = lua_tointeger(state, 2);
const size_t y = lua_tointeger(state, 3);
const size_t len = lua_tointeger(state, 4);
const uint8_t* ret = render->texture_functions.data(render->texture_functions.userdata, x, y);
lua_pushlstring(state, (const char*)ret, len);
return 1;
}

View File

@@ -74,6 +74,10 @@ struct TextureFunctions {
/// Note that changing the in-game "texture compression" setting will change the contents of
/// the texture for some images and therefore change the result of this comparison.
uint8_t (*compare)(void* userdata, size_t x, size_t y, size_t len, const unsigned char* data);
/// Fetches a pointer to the texture's pixel data at coordinates x and y. Doesn't do any checks
/// on whether x and y are in-bounds. Data is always RGBA and pixel rows are always contiguous.
uint8_t* (*data)(void* userdata, size_t x, size_t y);
};
/// Struct containing "vtable" callback information for surfaces.

View File

@@ -213,7 +213,7 @@ static int api_batch2d_texturesize(lua_State*);
/// [-4, +1, -]
/// Compares a section of the texture atlas for this batch to some RGBA data. For example:
///
/// `batch:comparetexture(64, 128, {0xFF, 0x0, 0x0, 0xFF, 0xFF, 0x0, 0x0, 0xFF})`
/// `batch:texturecompare(64, 128, {0xFF, 0x0, 0x0, 0xFF, 0xFF, 0x0, 0x0, 0xFF})`
///
/// This would check if the pixels at 64,128 and 65,128 are red. The bytes must match exactly
/// for the function to return true, otherwise it will return false.
@@ -223,6 +223,18 @@ static int api_batch2d_texturesize(lua_State*);
/// but can only be done one row at a time.
static int api_batch2d_texturecompare(lua_State*);
/// [-4, +1, -]
/// Gets the RGBA data starting at a given coordinate of the texture atlas, for example:
///
/// `batch:texturedata(64, 128, 8)`
///
/// This would return RGBA data for eight bytes, i.e. the two pixels at (64,128) and (65,128),
/// encoded as a Lua string.
///
/// Encoding Lua strings is computationally expensive, and indexing the data one byte at a time is
/// even more so. Unless you really need to do that, use `texturecompare()` instead.
static int api_batch2d_texturedata(lua_State*);
/// [-1, +1, -]
/// Returns the angle at which the minimap background image is being rendered, in radians.
///
@@ -318,7 +330,7 @@ static int api_render3d_texturesize(lua_State*);
/// [-4, +1, -]
/// Compares a section of the texture atlas for this render to some RGBA data. For example:
///
/// `render:comparetexture(64, 128, {0xFF, 0x0, 0x0, 0xFF, 0xFF, 0x0, 0x0, 0xFF})`
/// `render:texturecompare(64, 128, {0xFF, 0x0, 0x0, 0xFF, 0xFF, 0x0, 0x0, 0xFF})`
///
/// This would check if the pixels at 64,128 and 65,128 are red. The bytes must match exactly
/// for the function to return true, otherwise it will return false.
@@ -327,3 +339,15 @@ static int api_render3d_texturesize(lua_State*);
/// block of pixels at once by this method is relatively fast, but can only be done one row at a
/// time.
static int api_render3d_texturecompare(lua_State*);
/// [-4, +1, -]
/// Gets the RGBA data starting at a given coordinate of the texture atlas, for example:
///
/// `render:texturedata(64, 128, 8)`
///
/// This would return RGBA data for eight bytes, i.e. the two pixels at (64,128) and (65,128),
/// encoded as a Lua string.
///
/// Encoding Lua strings is computationally expensive, and indexing the data one byte at a time is
/// even more so. Unless you really need to do that, use `texturecompare()` instead.
static int api_render3d_texturedata(lua_State*);