Merge pull request #354 from kichikuou/edge

SealEngine: Implement outline rendering options
This commit is contained in:
Nunuhara Cabbage
2026-06-27 08:12:00 -07:00
committed by GitHub
4 changed files with 94 additions and 22 deletions
+4 -6
View File
@@ -92,12 +92,6 @@ enum RE_draw_options {
RE_DRAW_OPTION_MAX
};
enum RE_draw_edge_mode {
RE_DRAW_EDGE_NONE = 0,
RE_DRAW_EDGE_CHARACTERS_ONLY = 1,
RE_DRAW_EDGE_ALL = 2,
};
struct RE_options {
int anti_aliasing;
int wait_vsync;
@@ -129,6 +123,7 @@ struct RE_back_cg {
struct RE_plugin {
struct draw_plugin plugin;
enum RE_plugin_version version;
int sprite;
int nr_instances;
struct RE_instance **instances;
@@ -183,6 +178,8 @@ struct RE_plugin {
// SealEngine
int mag_speed;
float light_params[RE_NR_LIGHT_PARAMS];
float edge_length;
vec3 edge_color;
};
struct RE_instance {
@@ -201,6 +198,7 @@ struct RE_instance {
vec3 scale;
float alpha;
bool draw;
bool draw_edge;
bool draw_shadow;
bool make_shadow;
float shadow_volume_bone_radius;
+7 -2
View File
@@ -41,6 +41,7 @@ static struct RE_instance *create_instance(struct RE_plugin *plugin)
{
struct RE_instance *instance = xcalloc_aligned(1, struct RE_instance);
instance->plugin = plugin;
instance->draw_edge = plugin->version == RE_TAPIR_PLUGIN;
for (int i = 0; i < RE_NR_INSTANCE_TARGETS; i++)
instance->target[i] = -1;
glm_vec3_one(instance->scale);
@@ -236,6 +237,7 @@ struct RE_plugin *RE_plugin_new(enum RE_plugin_version version)
return NULL;
struct RE_plugin *plugin = xcalloc_aligned(1, struct RE_plugin);
plugin->version = version;
plugin->plugin.name = "ReignEngine";
plugin->plugin.update = RE_render;
plugin->plugin.to_json = RE_to_json;
@@ -247,9 +249,12 @@ struct RE_plugin *RE_plugin_new(enum RE_plugin_version version)
for (int i = 0; i < RE_NR_BACK_CGS; i++)
RE_back_cg_init(&plugin->back_cg[i]);
plugin->mag_speed = 1;
if (version == RE_TAPIR_PLUGIN)
plugin->draw_options[RE_DRAW_OPTION_EDGE] = 1;
plugin->edge_length = 0.02f;
plugin->fog_type = RE_FOG_NONE;
plugin->fog_near = 1.0;
plugin->fog_far = 10.0;
plugin->fog_near = 1.0f;
plugin->fog_far = 10.0f;
glm_vec3_one(plugin->fog_color);
lit_reset(plugin->light_params);
return plugin;
+14 -5
View File
@@ -1072,8 +1072,7 @@ static void render_shadow_map(struct RE_plugin *plugin, mat4 light_space_transfo
static void render_outlines(struct RE_plugin *plugin, mat4 view_transform)
{
enum RE_draw_edge_mode mode = plugin->draw_options[RE_DRAW_OPTION_EDGE];
if (mode == RE_DRAW_EDGE_NONE)
if (plugin->draw_options[RE_DRAW_OPTION_EDGE] == 0)
return;
struct outline_renderer *or = &plugin->renderer->outline;
if (!or->program)
@@ -1082,12 +1081,20 @@ static void render_outlines(struct RE_plugin *plugin, mat4 view_transform)
glUniformMatrix4fv(or->view_transform, 1, GL_FALSE, view_transform[0]);
glUniformMatrix4fv(or->proj_transform, 1, GL_FALSE, plugin->proj_transform[0]);
// SealEngine ignores the per-mesh edge parameters from .opr and uses
// a single plugin-wide edge length and color.
bool seal_edge = re_plugin_version >= RE_SEAL_PLUGIN;
if (seal_edge) {
glUniform3fv(or->outline_color, 1, plugin->edge_color);
glUniform1f(or->outline_thickness, plugin->edge_length);
}
glCullFace(GL_FRONT);
for (int i = 0; i < plugin->nr_instances; i++) {
struct RE_instance *inst = plugin->instances[i];
if (!inst || !inst->draw)
continue;
if (mode == RE_DRAW_EDGE_CHARACTERS_ONLY && inst->type != RE_ITYPE_SKINNED)
if (!inst->draw_edge)
continue;
struct model *model = inst->model;
if (inst->model && model->nr_bones > 0) {
@@ -1102,8 +1109,10 @@ static void render_outlines(struct RE_plugin *plugin, mat4 view_transform)
struct mesh *mesh = &model->meshes[j];
if (mesh->flags & MESH_NO_EDGE)
continue;
glUniform3fv(or->outline_color, 1, mesh->outline_color);
glUniform1f(or->outline_thickness, mesh->outline_thickness);
if (!seal_edge) {
glUniform3fv(or->outline_color, 1, mesh->outline_color);
glUniform1f(or->outline_thickness, mesh->outline_thickness);
}
glBindVertexArray(mesh->vao);
glDrawArrays(GL_TRIANGLES, 0, mesh->nr_vertices);
}
+69 -9
View File
@@ -1825,8 +1825,35 @@ static int TapirEngine_CreatePlugin(void)
return ReignEngine_create_plugin(RE_TAPIR_PLUGIN);
}
HLL_WARN_UNIMPLEMENTED(false, bool, TapirEngine, SetInstanceDrawParam, int plugin_number, int instance_number, int draw_param, int value);
//bool TapirEngine_GetInstanceDrawParam(int PluginNumber, int InstanceNumber, int DrawParam, int *Value);
static bool TapirEngine_SetInstanceDrawParam(int plugin_number, int instance_number, int draw_param, int value)
{
struct RE_plugin *p = get_plugin(plugin_number);
struct RE_instance *ri = get_instance(plugin_number, instance_number);
if (!p || !ri)
return false;
int edge_index = p->version >= RE_SEAL_PLUGIN ? 2 : 0;
if (draw_param == edge_index) {
ri->draw_edge = value != 0;
return true;
}
WARNING("unimplemented InstanceDrawParam: %d", draw_param);
return false;
}
static bool TapirEngine_GetInstanceDrawParam(int plugin_number, int instance_number, int draw_param, int *value)
{
struct RE_plugin *p = get_plugin(plugin_number);
struct RE_instance *ri = get_instance(plugin_number, instance_number);
if (!p || !ri)
return false;
int edge_index = p->version >= RE_SEAL_PLUGIN ? 2 : 0;
if (draw_param == edge_index) {
*value = ri->draw_edge;
return true;
}
WARNING("unimplemented InstanceDrawParam: %d", draw_param);
return false;
}
static float TapirEngine_CalcInstance2DDetectionHeight(int plugin, int instance, float x, float z)
{
@@ -2313,7 +2340,7 @@ HLL_LIBRARY(ReignEngine, REIGN_EXPORTS,
#define TAPIR_EXPORTS \
HLL_EXPORT(CreatePlugin, TapirEngine_CreatePlugin), \
HLL_EXPORT(SetInstanceDrawParam, TapirEngine_SetInstanceDrawParam), \
HLL_TODO_EXPORT(GetInstanceDrawParam, TapirEngine_GetInstanceDrawParam), \
HLL_EXPORT(GetInstanceDrawParam, TapirEngine_GetInstanceDrawParam), \
HLL_EXPORT(CalcInstance2DDetectionHeight, TapirEngine_CalcInstance2DDetectionHeight), \
HLL_EXPORT(CalcInstance2DDetection, TapirEngine_CalcInstance2DDetection), \
HLL_EXPORT(FindInstancePath, TapirEngine_FindInstancePath), \
@@ -2510,12 +2537,45 @@ HLL_WARN_UNIMPLEMENTED(false, bool, SealEngine, SetShadowRate, int PluginNumber,
//float SealEngine_GetShadowRate(int PluginNumber);
//bool SealEngine_SetSoftFogEdgeLength(int PluginNumber, float SoftFogEdgeLength);
//float SealEngine_GetSoftFogEdgeLength(int PluginNumber);
HLL_WARN_UNIMPLEMENTED(false, bool, SealEngine, SetEdgeLength, int PluginNumber, float EdgeLength);
//float SealEngine_GetEdgeLength(int PluginNumber);
static bool SealEngine_SetEdgeLength(int PluginNumber, float EdgeLength)
{
struct RE_plugin *p = get_plugin(PluginNumber);
if (!p)
return false;
p->edge_length = EdgeLength;
return true;
}
static float SealEngine_GetEdgeLength(int PluginNumber)
{
struct RE_plugin *p = get_plugin(PluginNumber);
return p ? p->edge_length : 0.0;
}
//bool SealEngine_SetEdgeReductionRate(int PluginNumber, float EdgeReductionRate);
//float SealEngine_GetEdgeReductionRate(int PluginNumber);
HLL_WARN_UNIMPLEMENTED(false, bool, SealEngine, SetEdgeColor, int PluginNumber, float ColorR, float ColorG, float ColorB);
//bool SealEngine_GetEdgeColor(int PluginNumber, float *ColorR, float *ColorG, float *ColorB);
static bool SealEngine_SetEdgeColor(int PluginNumber, float ColorR, float ColorG, float ColorB)
{
struct RE_plugin *p = get_plugin(PluginNumber);
if (!p)
return false;
p->edge_color[0] = ColorR;
p->edge_color[1] = ColorG;
p->edge_color[2] = ColorB;
return true;
}
static bool SealEngine_GetEdgeColor(int PluginNumber, float *ColorR, float *ColorG, float *ColorB)
{
struct RE_plugin *p = get_plugin(PluginNumber);
if (!p)
return false;
*ColorR = p->edge_color[0];
*ColorG = p->edge_color[1];
*ColorB = p->edge_color[2];
return true;
}
//bool SealEngine_Calc2DDetectionHeight(int PluginNumber, float X, float Z, float *Height);
//bool SealEngine_Calc2DDetection(int PluginNumber, float X0, float Y0, float Z0, float X1, float Y1, float Z1, float Radius, float *X2, float *Y2, float *Z2);
//bool SealEngine_Calc2DDetectionIntersectEyeVector(int PluginNumber, int ViewX, int ViewY, float *X, float *Y, float *Z);
@@ -2643,11 +2703,11 @@ HLL_QUIET_UNIMPLEMENTED(false, bool, SealEngine, IsThreadLoadingMode, int Plugin
HLL_TODO_EXPORT(SetSoftFogEdgeLength, SealEngine_SetSoftFogEdgeLength), \
HLL_TODO_EXPORT(GetSoftFogEdgeLength, SealEngine_GetSoftFogEdgeLength), \
HLL_EXPORT(SetEdgeLength, SealEngine_SetEdgeLength), \
HLL_TODO_EXPORT(GetEdgeLength, SealEngine_GetEdgeLength), \
HLL_EXPORT(GetEdgeLength, SealEngine_GetEdgeLength), \
HLL_TODO_EXPORT(SetEdgeReductionRate, SealEngine_SetEdgeReductionRate), \
HLL_TODO_EXPORT(GetEdgeReductionRate, SealEngine_GetEdgeReductionRate), \
HLL_EXPORT(SetEdgeColor, SealEngine_SetEdgeColor), \
HLL_TODO_EXPORT(GetEdgeColor, SealEngine_GetEdgeColor), \
HLL_EXPORT(GetEdgeColor, SealEngine_GetEdgeColor), \
HLL_TODO_EXPORT(Calc2DDetectionHeight, SealEngine_Calc2DDetectionHeight), \
HLL_TODO_EXPORT(Calc2DDetection, SealEngine_Calc2DDetection), \
HLL_TODO_EXPORT(Calc2DDetectionIntersectEyeVector, SealEngine_Calc2DDetectionIntersectEyeVector), \