get_texture_average_color
Some checks are pending
Build coop / build-linux (push) Waiting to run
Build coop / build-steamos (push) Waiting to run
Build coop / build-windows-opengl (push) Waiting to run
Build coop / build-windows-directx (push) Waiting to run
Build coop / build-macos-arm (push) Waiting to run
Build coop / build-macos-intel (push) Waiting to run

pass in a texture, it returns the average color of the texture
This commit is contained in:
Isaac0-dev 2025-06-05 22:33:24 +10:00
parent 378b619fd6
commit 98ff007818
11 changed files with 145 additions and 22 deletions

View file

@ -11098,6 +11098,14 @@ function geo_get_current_held_object()
-- ...
end
--- @param tex Pointer_integer
--- @param out Color
--- @return boolean
--- Calculates the average color of a given texture. Returns true if success
function get_texture_average_color(tex, out)
-- ...
end
--- @param name string
--- @return ModelExtendedId
--- Gets the extended model ID for the `name` of a `GeoLayout`

View file

@ -48,6 +48,7 @@ Collision* dynos_collision_get(const char* collisionName);
// -- textures -- //
void dynos_add_texture(const char *filePath, const char* textureName);
bool dynos_texture_get(const char* textureName, struct TextureInfo* outTextureInfo);
bool dynos_texture_get_from_data(const Texture *tex, struct TextureInfo* outTextureInfo);
void dynos_texture_override_set(const char* textureName, struct TextureInfo* overrideTextureInfo);
void dynos_texture_override_reset(const char* textureName);

View file

@ -862,6 +862,7 @@ const Texture* DynOS_Builtin_Tex_GetFromName(const char* aDataName);
const char* DynOS_Builtin_Tex_GetFromData(const Texture* aData);
const char* DynOS_Builtin_Tex_GetNameFromFileName(const char* aDataName);
const struct BuiltinTexInfo* DynOS_Builtin_Tex_GetInfoFromName(const char* aDataName);
const struct BuiltinTexInfo* DynOS_Builtin_Tex_GetInfoFromData(const Texture* aData);
const void* DynOS_Builtin_Func_GetFromName(const char* aDataName);
const void* DynOS_Builtin_Func_GetFromIndex(s32 aIndex);
const char * DynOS_Builtin_Func_GetNameFromIndex(s64 aIndex);
@ -918,6 +919,7 @@ void DynOS_Tex_Activate(DataNode<TexData>* aNode, bool aCustomTexture);
void DynOS_Tex_Deactivate(DataNode<TexData>* aNode);
void DynOS_Tex_AddCustom(const SysPath &aFilename, const char *aTexName);
bool DynOS_Tex_Get(const char* aTexName, struct TextureInfo* aOutTexInfo);
bool DynOS_Tex_GetFromData(const Texture *aTex, struct TextureInfo* aOutTexInfo);
void DynOS_Tex_Override_Set(const char* textureName, struct TextureInfo* aOverrideTexInfo);
void DynOS_Tex_Override_Reset(const char* textureName);
void DynOS_Tex_ModShutdown();

View file

@ -148,6 +148,10 @@ bool dynos_texture_get(const char* textureName, struct TextureInfo* outTextureIn
return DynOS_Tex_Get(textureName, outTextureInfo);
}
bool dynos_texture_get_from_data(const Texture *tex, struct TextureInfo* outTextureInfo) {
return DynOS_Tex_GetFromData(tex, outTextureInfo);
}
void dynos_texture_override_set(const char* textureName, struct TextureInfo* overrideTextureInfo) {
DynOS_Tex_Override_Set(textureName, overrideTextureInfo);
}

View file

@ -1153,7 +1153,7 @@ static const struct BuiltinTexInfo sDynosBuiltinTexs[] = {
define_builtin_tex(texture_selectionbox_back_icon, "textures/segment2/custom_selectionbox_back_icon.rgba16.png", 16, 16, 16),
define_builtin_tex(texture_selectionbox_forward_icon, "textures/segment2/custom_selectionbox_forward_icon.rgba16.png", 16, 16, 16),
define_builtin_tex(texture_coopdx_logo, "textures/segment2/custom_coopdx_logo.rgba32.png", 2048, 1024, 32),
// Goddard
define_builtin_tex(gd_texture_hand_open, "textures/intro_raw/hand_open.rgba16.png", 32, 32, 16),
define_builtin_tex(gd_texture_hand_closed, "textures/intro_raw/hand_closed.rgba16.png", 32, 32, 16),
@ -1179,7 +1179,7 @@ static const struct BuiltinTexInfo sDynosBuiltinTexs[] = {
define_builtin_tex(gd_texture_sparkle_3, "textures/intro_raw/sparkle_3.rgba16.png", 32, 32, 16),
define_builtin_tex(gd_texture_sparkle_4, "textures/intro_raw/sparkle_4.rgba16.png", 32, 32, 16),
define_builtin_tex(gd_texture_sparkle_5, "textures/intro_raw/sparkle_5.rgba16.png", 32, 32, 16),
// Version Exclusives
#if defined(VERSION_JP)
define_builtin_tex(texture_font_char_jp_0, "textures/segment2/segment2.07100.ia1.png", 8, 8, 16),
@ -1448,7 +1448,7 @@ static const struct BuiltinTexInfo sDynosBuiltinTexs[] = {
define_builtin_tex(texture_font_char_eu_unknown, "textures/segment2/font_graphics.06510.ia1.png", 16, 8, 16),
define_builtin_tex(texture_font_char_eu_Cedilla, "textures/segment2/font_graphics.06520.ia1.png", 16, 8, 16),
define_builtin_tex(texture_font_char_eu_eszeet, "textures/segment2/font_graphics.06530.ia1.png", 16, 8, 16),
define_builtin_tex(cake_end_texture_eu_35, "levels/ending/eu_023000.rgba16.png", 64, 32, 16),
define_builtin_tex(cake_end_texture_eu_36, "levels/ending/eu_024000.rgba16.png", 64, 32, 16),
define_builtin_tex(cake_end_texture_eu_37, "levels/ending/eu_025000.rgba16.png", 64, 32, 16),
@ -1614,7 +1614,7 @@ static const struct BuiltinTexInfo sDynosBuiltinTexs[] = {
define_builtin_tex(water_skybox_texture_0003D, "textures/skybox_tiles/water.61.rgba16.png", 32, 32, 16),
define_builtin_tex(water_skybox_texture_0003E, "textures/skybox_tiles/water.62.rgba16.png", 32, 32, 16),
define_builtin_tex(water_skybox_texture_0003F, "textures/skybox_tiles/water.63.rgba16.png", 32, 32, 16),
define_builtin_tex(bitfs_skybox_texture_00000, "textures/skybox_tiles/bitfs.0.rgba16.png", 32, 32, 16),
define_builtin_tex(bitfs_skybox_texture_00001, "textures/skybox_tiles/bitfs.1.rgba16.png", 32, 32, 16),
define_builtin_tex(bitfs_skybox_texture_00002, "textures/skybox_tiles/bitfs.2.rgba16.png", 32, 32, 16),
@ -2461,3 +2461,15 @@ const struct BuiltinTexInfo* DynOS_Builtin_Tex_GetInfoFromName(const char* aData
return NULL;
}
const struct BuiltinTexInfo* DynOS_Builtin_Tex_GetInfoFromData(const Texture* aData) {
size_t count = sizeof(sDynosBuiltinTexs) / (sizeof(struct BuiltinTexInfo));
for (size_t i = 0; i < count; i++) {
const struct BuiltinTexInfo* info = &sDynosBuiltinTexs[i];
if (info->pointer == aData) {
return info;
}
}
return NULL;
}

View file

@ -447,24 +447,24 @@ void DynOS_Tex_AddCustom(const SysPath &aFilename, const char *aTexName) {
}
}
bool DynOS_Tex_Get(const char* aTexName, struct TextureInfo* aOutTexInfo) {
#define CONVERT_TEXINFO() { \
/* translate bit size */ \
switch (_Data->mRawSize) { \
case G_IM_SIZ_8b: aOutTexInfo->bitSize = 8; break; \
case G_IM_SIZ_16b: aOutTexInfo->bitSize = 16; break; \
case G_IM_SIZ_32b: aOutTexInfo->bitSize = 32; break; \
default: return false; \
} \
aOutTexInfo->width = _Data->mRawWidth; \
aOutTexInfo->height = _Data->mRawHeight; \
aOutTexInfo->texture = _Data->mRawData.begin(); \
aOutTexInfo->name = aTexName; \
}
#define CONVERT_TEXINFO(texName) { \
/* translate bit size */ \
switch (_Data->mRawSize) { \
case G_IM_SIZ_8b: aOutTexInfo->bitSize = 8; break; \
case G_IM_SIZ_16b: aOutTexInfo->bitSize = 16; break; \
case G_IM_SIZ_32b: aOutTexInfo->bitSize = 32; break; \
default: return false; \
} \
aOutTexInfo->width = _Data->mRawWidth; \
aOutTexInfo->height = _Data->mRawHeight; \
aOutTexInfo->texture = _Data->mRawData.begin(); \
aOutTexInfo->name = texName; \
}
auto& _DynosCustomTexs = DynosCustomTexs();
bool DynOS_Tex_Get(const char* aTexName, struct TextureInfo* aOutTexInfo) {
// check custom textures
auto& _DynosCustomTexs = DynosCustomTexs();
for (s32 i = 0; i < _DynosCustomTexs.Count(); ++i) {
if (!strcmp(_DynosCustomTexs[i].first, aTexName)) {
auto& _Data = _DynosCustomTexs[i].second->mData;
@ -483,7 +483,7 @@ bool DynOS_Tex_Get(const char* aTexName, struct TextureInfo* aOutTexInfo) {
free(_RawData);
}
CONVERT_TEXINFO();
CONVERT_TEXINFO(aTexName);
return true;
}
}
@ -494,7 +494,7 @@ bool DynOS_Tex_Get(const char* aTexName, struct TextureInfo* aOutTexInfo) {
for (DataNode<TexData>* _Node : DynosValidTextures()) { // check valid textures
if (_Node->mName == aTexName) {
auto& _Data = _Node->mData;
CONVERT_TEXINFO();
CONVERT_TEXINFO(aTexName);
return true;
}
}
@ -508,6 +508,28 @@ bool DynOS_Tex_Get(const char* aTexName, struct TextureInfo* aOutTexInfo) {
return true;
}
bool DynOS_Tex_GetFromData(const Texture *aTex, struct TextureInfo* aOutTexInfo) {
DataNode<TexData> *node = DynOS_Tex_RetrieveNode((void *) aTex);
if (node) {
auto& _Data = node->mData;
CONVERT_TEXINFO(node->mName.begin());
return true;
}
// check builtin textures
const struct BuiltinTexInfo* info = DynOS_Builtin_Tex_GetInfoFromData(aTex);
if (info) {
aOutTexInfo->bitSize = info->bitSize;
aOutTexInfo->width = info->width;
aOutTexInfo->height = info->height;
aOutTexInfo->texture = (u8*)info->pointer;
aOutTexInfo->name = info->identifier;
return true;
}
return false;
}
static DataNode<TexData> *DynOS_Lua_Tex_RetrieveNode(const char* aName) {
auto& _DynosCustomTexs = DynosCustomTexs();
for (s32 i = 0; i < _DynosCustomTexs.Count(); ++i) {

View file

@ -5105,6 +5105,30 @@ Gets the current GraphNodeHeldObject
<br />
## [get_texture_average_color](#get_texture_average_color)
### Description
Calculates the average color of a given texture. Returns true if success
### Lua Example
`local booleanValue = get_texture_average_color(tex, out)`
### Parameters
| Field | Type |
| ----- | ---- |
| tex | `Pointer` <`integer`> |
| out | [Color](structs.md#Color) |
### Returns
- `boolean`
### C Prototype
`bool get_texture_average_color(const u8 *tex, OUT Color out);`
[:arrow_up_small:](#)
<br />
---
# functions from smlua_model_utils.h

View file

@ -1990,6 +1990,7 @@
- [geo_get_current_perspective](functions-6.md#geo_get_current_perspective)
- [geo_get_current_camera](functions-6.md#geo_get_current_camera)
- [geo_get_current_held_object](functions-6.md#geo_get_current_held_object)
- [get_texture_average_color](functions-6.md#get_texture_average_color)
<br />

View file

@ -33075,6 +33075,29 @@ int smlua_func_geo_get_current_held_object(UNUSED lua_State* L) {
return 1;
}
int smlua_func_get_texture_average_color(lua_State* L) {
if (L == NULL) { return 0; }
int top = lua_gettop(L);
if (top != 2) {
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "get_texture_average_color", 2, top);
return 0;
}
u8 * tex = (u8 *)smlua_to_cpointer(L, 1, LVT_U8_P);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "get_texture_average_color"); return 0; }
Color out;
smlua_get_color(out, 2);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "get_texture_average_color"); return 0; }
lua_pushboolean(L, get_texture_average_color(tex, out));
smlua_push_color(out, 2);
return 1;
}
/////////////////////////
// smlua_model_utils.h //
/////////////////////////
@ -36957,6 +36980,7 @@ void smlua_bind_functions_autogen(void) {
smlua_bind_function(L, "geo_get_current_perspective", smlua_func_geo_get_current_perspective);
smlua_bind_function(L, "geo_get_current_camera", smlua_func_geo_get_current_camera);
smlua_bind_function(L, "geo_get_current_held_object", smlua_func_geo_get_current_held_object);
smlua_bind_function(L, "get_texture_average_color", smlua_func_get_texture_average_color);
// smlua_model_utils.h
smlua_bind_function(L, "smlua_model_util_get_id", smlua_func_smlua_model_util_get_id);

View file

@ -584,4 +584,26 @@ struct GraphNodeCamera* geo_get_current_camera(void) {
struct GraphNodeHeldObject* geo_get_current_held_object(void) {
return gCurGraphNodeHeldObject;
}
}
bool get_texture_average_color(const u8 *tex, OUT Color out) {
struct TextureInfo texInfo;
if (!tex) { return false; }
if (!dynos_texture_get_from_data(tex, &texInfo)) { return false; }
u32 w = texInfo.width;
u32 h = texInfo.height;
u32 texSize = w * h;
const u8 *data = texInfo.texture;
u32 r = 0;
u32 g = 0;
u32 b = 0;
for (u32 i = 0; i < texSize; i++) {
r += data[4 * i + 0];
g += data[4 * i + 1];
b += data[4 * i + 2];
}
out[0] = r / texSize;
out[1] = g / texSize;
out[2] = b / texSize;
return true;
}

View file

@ -231,4 +231,7 @@ struct GraphNodeCamera* geo_get_current_camera(void);
/* |description|Gets the current GraphNodeHeldObject|descriptionEnd|*/
struct GraphNodeHeldObject* geo_get_current_held_object(void);
/* |description|Calculates the average color of a given texture. Returns true if success|descriptionEnd|*/
bool get_texture_average_color(const u8 *tex, OUT Color out);
#endif