This commit is contained in:
EmeraldLockdown 2026-03-31 21:20:37 -05:00
parent 7604ef9297
commit ed3cdeae10
37 changed files with 2742 additions and 1368 deletions

View file

@ -52,6 +52,7 @@ in_files = [
"src/game/player_palette.h",
"src/pc/network/lag_compensation.h",
"src/pc/djui/djui_panel_menu.h",
"src/pc/gfx/gfx_cc.h",
"src/engine/lighting_engine.h",
"include/PR/gbi.h",
"include/PR/gbi_extension.h",

View file

@ -31,6 +31,8 @@ in_files = [
"src/pc/lua/utils/smlua_audio_utils.h",
"src/game/paintings.h",
"src/pc/djui/djui_types.h",
"src/pc/gfx/gfx_cc.h",
"src/pc/gfx/gfx_opengl.h",
"src/game/first_person_cam.h",
"src/game/player_palette.h",
"src/engine/graph_node.h",

View file

@ -3056,6 +3056,116 @@ BACKGROUND_CUSTOM = 10 --- @type SkyBackgroundParams
--- | `BACKGROUND_PURPLE_SKY`
--- | `BACKGROUND_CUSTOM`
CC_0 = 0 --- @type ColorCombinerSource
CC_TEXEL0 = 1 --- @type ColorCombinerSource
CC_TEXEL1 = 2 --- @type ColorCombinerSource
CC_PRIM = 3 --- @type ColorCombinerSource
CC_SHADE = 4 --- @type ColorCombinerSource
CC_ENV = 5 --- @type ColorCombinerSource
CC_TEXEL0A = 6 --- @type ColorCombinerSource
CC_LOD = 7 --- @type ColorCombinerSource
CC_1 = 8 --- @type ColorCombinerSource
CC_TEXEL1A = 9 --- @type ColorCombinerSource
CC_COMBINED = 10 --- @type ColorCombinerSource
CC_COMBINEDA = 11 --- @type ColorCombinerSource
CC_PRIMA = 12 --- @type ColorCombinerSource
CC_SHADEA = 13 --- @type ColorCombinerSource
CC_ENVA = 14 --- @type ColorCombinerSource
CC_NOISE = 15 --- @type ColorCombinerSource
CC_ENUM_MAX = 16 --- @type ColorCombinerSource
--- @alias ColorCombinerSource
--- | `CC_0`
--- | `CC_TEXEL0`
--- | `CC_TEXEL1`
--- | `CC_PRIM`
--- | `CC_SHADE`
--- | `CC_ENV`
--- | `CC_TEXEL0A`
--- | `CC_LOD`
--- | `CC_1`
--- | `CC_TEXEL1A`
--- | `CC_COMBINED`
--- | `CC_COMBINEDA`
--- | `CC_PRIMA`
--- | `CC_SHADEA`
--- | `CC_ENVA`
--- | `CC_NOISE`
--- | `CC_ENUM_MAX`
SHADER_0 = 0 --- @type ShaderInput
SHADER_INPUT_1 = 1 --- @type ShaderInput
SHADER_INPUT_2 = 2 --- @type ShaderInput
SHADER_INPUT_3 = 3 --- @type ShaderInput
SHADER_INPUT_4 = 4 --- @type ShaderInput
SHADER_INPUT_5 = 5 --- @type ShaderInput
SHADER_INPUT_6 = 6 --- @type ShaderInput
SHADER_INPUT_7 = 7 --- @type ShaderInput
SHADER_INPUT_8 = 8 --- @type ShaderInput
SHADER_TEXEL0 = 9 --- @type ShaderInput
SHADER_TEXEL0A = 10 --- @type ShaderInput
SHADER_TEXEL1 = 11 --- @type ShaderInput
SHADER_TEXEL1A = 12 --- @type ShaderInput
SHADER_1 = 13 --- @type ShaderInput
SHADER_COMBINED = 14 --- @type ShaderInput
SHADER_COMBINEDA = 15 --- @type ShaderInput
SHADER_NOISE = 16 --- @type ShaderInput
--- @alias ShaderInput
--- | `SHADER_0`
--- | `SHADER_INPUT_1`
--- | `SHADER_INPUT_2`
--- | `SHADER_INPUT_3`
--- | `SHADER_INPUT_4`
--- | `SHADER_INPUT_5`
--- | `SHADER_INPUT_6`
--- | `SHADER_INPUT_7`
--- | `SHADER_INPUT_8`
--- | `SHADER_TEXEL0`
--- | `SHADER_TEXEL0A`
--- | `SHADER_TEXEL1`
--- | `SHADER_TEXEL1A`
--- | `SHADER_1`
--- | `SHADER_COMBINED`
--- | `SHADER_COMBINEDA`
--- | `SHADER_NOISE`
--- @type integer
SHADER_OPT_ALPHA = (1 << 24)
--- @type integer
SHADER_OPT_FOG = (1 << 25)
--- @type integer
SHADER_OPT_TEXTURE_EDGE = (1 << 26)
--- @type integer
SHADER_OPT_NOISE = (1 << 27)
USE_ALPHA = 1 << 0 --- @type CombineModeFlags
USE_FOG = 1 << 1 --- @type CombineModeFlags
TEXTURE_EDGE = 1 << 2 --- @type CombineModeFlags
USE_DITHER = 1 << 3 --- @type CombineModeFlags
USE_2CYCLE = 1 << 4 --- @type CombineModeFlags
LIGHT_MAP = 1 << 5 --- @type CombineModeFlags
--- @alias CombineModeFlags
--- | `USE_ALPHA`
--- | `USE_FOG`
--- | `TEXTURE_EDGE`
--- | `USE_DITHER`
--- | `USE_2CYCLE`
--- | `LIGHT_MAP`
--- @type integer
SHADER_CMD_LENGTH = 16
--- @type integer
CC_MAX_SHADERS = 64
--- @type integer
CC_MAX_INPUTS = 8
--- @type integer
GRAPH_RENDER_ACTIVE = (1 << 0)
@ -8213,7 +8323,10 @@ HOOK_ON_FIND_FLOOR = 62 --- @type LuaHookedEventType
HOOK_ON_FIND_WATER_LEVEL = 63 --- @type LuaHookedEventType
HOOK_ON_FIND_POISON_GAS_LEVEL = 64 --- @type LuaHookedEventType
HOOK_ON_FIND_SURFACE_ON_RAY = 65 --- @type LuaHookedEventType
HOOK_MAX = 66 --- @type LuaHookedEventType
HOOK_ON_REFRESH_SHADERS = 66 --- @type LuaHookedEventType
HOOK_ON_VERTEX_SHADER_CREATE = 67 --- @type LuaHookedEventType
HOOK_ON_FRAGMENT_SHADER_CREATE = 68 --- @type LuaHookedEventType
HOOK_MAX = 69 --- @type LuaHookedEventType
--- @alias LuaHookedEventType
--- | `HOOK_UPDATE`
@ -8282,6 +8395,9 @@ HOOK_MAX = 66 --- @type LuaHookedEventType
--- | `HOOK_ON_FIND_WATER_LEVEL`
--- | `HOOK_ON_FIND_POISON_GAS_LEVEL`
--- | `HOOK_ON_FIND_SURFACE_ON_RAY`
--- | `HOOK_ON_REFRESH_SHADERS`
--- | `HOOK_ON_VERTEX_SHADER_CREATE`
--- | `HOOK_ON_FRAGMENT_SHADER_CREATE`
--- | `HOOK_MAX`
--- @type integer

View file

@ -10966,6 +10966,87 @@ function gfx_delete_all()
-- ...
end
--- Reloads all shaders
function gfx_reload_shaders()
-- ...
end
--- @param cc ColorCombiner
--- @return CCFeatures
--- Gets features from a color combiner.
function gfx_color_combiner_get_features(cc)
-- ...
end
--- @param shaderIndex integer
--- @return integer
--- Gets a program id from the shader index.
function gfx_get_program_id_from_shader_index(shaderIndex)
-- ...
end
--- @param program integer
--- Uses a specific program. Required for setting uniforms.
function gfx_use_program(program)
-- ...
end
--- @param program integer
--- @param name string
--- @return integer
--- Gets the location of a shader uniform in a program for modification.
function gfx_shader_get_uniform_location(program, name)
-- ...
end
--- @param loc integer
--- @param value integer
--- Sets the value of a shader uniform of type int.
function gfx_shader_set_int(loc, value)
-- ...
end
--- @param loc integer
--- @param value number
--- Sets the value of a shader uniform of type float.
function gfx_shader_set_float(loc, value)
-- ...
end
--- @param loc integer
--- @param x number
--- @param y number
--- Sets the value of a shader uniform of type vec2.
function gfx_shader_set_vec2(loc, x, y)
-- ...
end
--- @param loc integer
--- @param x number
--- @param y number
--- @param z number
--- Sets the value of a shader uniform of type vec3.
function gfx_shader_set_vec3(loc, x, y, z)
-- ...
end
--- @param loc integer
--- @param w number
--- @param x number
--- @param y number
--- @param z number
--- Sets the value of a shader uniform of type vec4.
function gfx_shader_set_vec4(loc, w, x, y, z)
-- ...
end
--- @param loc integer
--- @param mat Mat4
--- Sets the value of a shader uniform of type mat4.
function gfx_shader_set_mat4(loc, mat)
-- ...
end
--- @param name string
--- @return Pointer_Vtx
--- @return integer count

View file

@ -201,6 +201,15 @@
--- @field public dialogs BehaviorDialogs
--- @field public trajectories BehaviorTrajectories
--- @class CCFeatures
--- @field public used_textures boolean[]
--- @field public num_inputs integer
--- @field public do_single boolean[]
--- @field public do_multiply boolean[]
--- @field public do_mix boolean[]
--- @field public color_alpha_same boolean[]
--- @field public do_noise boolean
--- @class Camera
--- @field public mode integer
--- @field public defMode integer
@ -502,6 +511,24 @@
--- @field public soundOkeyDokey integer
--- @field public sounds integer[]
--- @class ColorCombiner
--- @field public cm CombineMode
--- @field public prg ShaderProgram
--- @field public shader_input_mapping integer[]
--- @field public shader_input_mapping_as_u64 integer[]
--- @field public shader_commands integer[]
--- @field public shader_commands_as_u64 integer[]
--- @field public hash integer
--- @class CombineMode
--- @field public rgb1 integer
--- @field public alpha1 integer
--- @field public rgb2 integer
--- @field public alpha2 integer
--- @field public all_values integer[]
--- @field public flags integer
--- @field public hash integer
--- @class Controller
--- @field public port integer
--- @field public stickX number
@ -2167,6 +2194,19 @@
--- @field public maxPlayers integer
--- @field public pauseAnywhere integer
--- @class ShaderProgram
--- @field public hash integer
--- @field public opengl_program_id integer
--- @field public num_inputs integer
--- @field public used_textures boolean[]
--- @field public num_floats integer
--- @field public attrib_locations integer[]
--- @field public uniform_locations integer[]
--- @field public attrib_sizes integer[]
--- @field public num_attribs integer
--- @field public used_noise boolean
--- @field public used_lightmap boolean
--- @class SpawnInfo
--- @field public startPos Vec3s
--- @field public startAngle Vec3s

View file

@ -29,6 +29,10 @@
- [gbi_extension.h](#gbi_extensionh)
- [geo_commands.h](#geo_commandsh)
- [enum SkyBackgroundParams](#enum-SkyBackgroundParams)
- [gfx_cc.h](#gfx_cch)
- [enum ColorCombinerSource](#enum-ColorCombinerSource)
- [enum ShaderInput](#enum-ShaderInput)
- [enum CombineModeFlags](#enum-CombineModeFlags)
- [graph_node.h](#graph_nodeh)
- [interaction.c](#interactionc)
- [interaction.h](#interactionh)
@ -1339,6 +1343,71 @@
<br />
## [gfx_cc.h](#gfx_cc.h)
### [enum ColorCombinerSource](#ColorCombinerSource)
| Identifier | Value |
| :--------- | :---- |
| CC_0 | 0 |
| CC_TEXEL0 | 1 |
| CC_TEXEL1 | 2 |
| CC_PRIM | 3 |
| CC_SHADE | 4 |
| CC_ENV | 5 |
| CC_TEXEL0A | 6 |
| CC_LOD | 7 |
| CC_1 | 8 |
| CC_TEXEL1A | 9 |
| CC_COMBINED | 10 |
| CC_COMBINEDA | 11 |
| CC_PRIMA | 12 |
| CC_SHADEA | 13 |
| CC_ENVA | 14 |
| CC_NOISE | 15 |
| CC_ENUM_MAX | 16 |
### [enum ShaderInput](#ShaderInput)
| Identifier | Value |
| :--------- | :---- |
| SHADER_0 | 0 |
| SHADER_INPUT_1 | 1 |
| SHADER_INPUT_2 | 2 |
| SHADER_INPUT_3 | 3 |
| SHADER_INPUT_4 | 4 |
| SHADER_INPUT_5 | 5 |
| SHADER_INPUT_6 | 6 |
| SHADER_INPUT_7 | 7 |
| SHADER_INPUT_8 | 8 |
| SHADER_TEXEL0 | 9 |
| SHADER_TEXEL0A | 10 |
| SHADER_TEXEL1 | 11 |
| SHADER_TEXEL1A | 12 |
| SHADER_1 | 13 |
| SHADER_COMBINED | 14 |
| SHADER_COMBINEDA | 15 |
| SHADER_NOISE | 16 |
- SHADER_OPT_ALPHA
- SHADER_OPT_FOG
- SHADER_OPT_TEXTURE_EDGE
- SHADER_OPT_NOISE
### [enum CombineModeFlags](#CombineModeFlags)
| Identifier | Value |
| :--------- | :---- |
| USE_ALPHA | 1 << 0 |
| USE_FOG | 1 << 1 |
| TEXTURE_EDGE | 1 << 2 |
| USE_DITHER | 1 << 3 |
| USE_2CYCLE | 1 << 4 |
| LIGHT_MAP | 1 << 5 |
- SHADER_CMD_LENGTH
- CC_MAX_SHADERS
- CC_MAX_INPUTS
[:arrow_up_small:](#)
<br />
## [graph_node.h](#graph_node.h)
- GRAPH_RENDER_ACTIVE
- GRAPH_RENDER_CHILDREN_FIRST
@ -3543,7 +3612,10 @@
| HOOK_ON_FIND_WATER_LEVEL | 63 |
| HOOK_ON_FIND_POISON_GAS_LEVEL | 64 |
| HOOK_ON_FIND_SURFACE_ON_RAY | 65 |
| HOOK_MAX | 66 |
| HOOK_ON_REFRESH_SHADERS | 66 |
| HOOK_ON_VERTEX_SHADER_CREATE | 67 |
| HOOK_ON_FRAGMENT_SHADER_CREATE | 68 |
| HOOK_MAX | 69 |
- MAX_HOOKED_BEHAVIORS
[:arrow_up_small:](#)

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1926,51 +1926,62 @@
<br />
- smlua_gfx_utils.h
- [set_override_fov](functions-6.md#set_override_fov)
- [set_override_near](functions-6.md#set_override_near)
- [set_override_far](functions-6.md#set_override_far)
- [get_lighting_dir](functions-6.md#get_lighting_dir)
- [set_lighting_dir](functions-6.md#set_lighting_dir)
- [get_lighting_color](functions-6.md#get_lighting_color)
- [get_lighting_color_ambient](functions-6.md#get_lighting_color_ambient)
- [set_lighting_color](functions-6.md#set_lighting_color)
- [set_lighting_color_ambient](functions-6.md#set_lighting_color_ambient)
- [get_vertex_color](functions-6.md#get_vertex_color)
- [set_vertex_color](functions-6.md#set_vertex_color)
- [get_fog_color](functions-6.md#get_fog_color)
- [set_fog_color](functions-6.md#set_fog_color)
- [get_fog_intensity](functions-6.md#get_fog_intensity)
- [set_fog_intensity](functions-6.md#set_fog_intensity)
- [get_skybox](functions-6.md#get_skybox)
- [set_override_skybox](functions-6.md#set_override_skybox)
- [get_skybox_color](functions-6.md#get_skybox_color)
- [set_skybox_color](functions-6.md#set_skybox_color)
- [gfx_parse](functions-6.md#gfx_parse)
- [gfx_get_op](functions-6.md#gfx_get_op)
- [gfx_get_display_list](functions-6.md#gfx_get_display_list)
- [gfx_get_vertex_buffer](functions-6.md#gfx_get_vertex_buffer)
- [gfx_get_vertex_count](functions-6.md#gfx_get_vertex_count)
- [gfx_get_texture](functions-6.md#gfx_get_texture)
- [gfx_get_from_name](functions-6.md#gfx_get_from_name)
- [gfx_get_name](functions-6.md#gfx_get_name)
- [gfx_get_length](functions-6.md#gfx_get_length)
- [gfx_get_command](functions-6.md#gfx_get_command)
- [gfx_get_next_command](functions-6.md#gfx_get_next_command)
- [gfx_copy](functions-6.md#gfx_copy)
- [gfx_create](functions-6.md#gfx_create)
- [gfx_resize](functions-6.md#gfx_resize)
- [gfx_delete](functions-6.md#gfx_delete)
- [gfx_delete_all](functions-6.md#gfx_delete_all)
- [vtx_get_from_name](functions-6.md#vtx_get_from_name)
- [vtx_get_name](functions-6.md#vtx_get_name)
- [vtx_get_count](functions-6.md#vtx_get_count)
- [vtx_get_vertex](functions-6.md#vtx_get_vertex)
- [vtx_get_next_vertex](functions-6.md#vtx_get_next_vertex)
- [vtx_copy](functions-6.md#vtx_copy)
- [vtx_create](functions-6.md#vtx_create)
- [vtx_resize](functions-6.md#vtx_resize)
- [vtx_delete](functions-6.md#vtx_delete)
- [vtx_delete_all](functions-6.md#vtx_delete_all)
- [set_override_fov](functions-7.md#set_override_fov)
- [set_override_near](functions-7.md#set_override_near)
- [set_override_far](functions-7.md#set_override_far)
- [get_lighting_dir](functions-7.md#get_lighting_dir)
- [set_lighting_dir](functions-7.md#set_lighting_dir)
- [get_lighting_color](functions-7.md#get_lighting_color)
- [get_lighting_color_ambient](functions-7.md#get_lighting_color_ambient)
- [set_lighting_color](functions-7.md#set_lighting_color)
- [set_lighting_color_ambient](functions-7.md#set_lighting_color_ambient)
- [get_vertex_color](functions-7.md#get_vertex_color)
- [set_vertex_color](functions-7.md#set_vertex_color)
- [get_fog_color](functions-7.md#get_fog_color)
- [set_fog_color](functions-7.md#set_fog_color)
- [get_fog_intensity](functions-7.md#get_fog_intensity)
- [set_fog_intensity](functions-7.md#set_fog_intensity)
- [get_skybox](functions-7.md#get_skybox)
- [set_override_skybox](functions-7.md#set_override_skybox)
- [get_skybox_color](functions-7.md#get_skybox_color)
- [set_skybox_color](functions-7.md#set_skybox_color)
- [gfx_parse](functions-7.md#gfx_parse)
- [gfx_get_op](functions-7.md#gfx_get_op)
- [gfx_get_display_list](functions-7.md#gfx_get_display_list)
- [gfx_get_vertex_buffer](functions-7.md#gfx_get_vertex_buffer)
- [gfx_get_vertex_count](functions-7.md#gfx_get_vertex_count)
- [gfx_get_texture](functions-7.md#gfx_get_texture)
- [gfx_get_from_name](functions-7.md#gfx_get_from_name)
- [gfx_get_name](functions-7.md#gfx_get_name)
- [gfx_get_length](functions-7.md#gfx_get_length)
- [gfx_get_command](functions-7.md#gfx_get_command)
- [gfx_get_next_command](functions-7.md#gfx_get_next_command)
- [gfx_copy](functions-7.md#gfx_copy)
- [gfx_create](functions-7.md#gfx_create)
- [gfx_resize](functions-7.md#gfx_resize)
- [gfx_delete](functions-7.md#gfx_delete)
- [gfx_delete_all](functions-7.md#gfx_delete_all)
- [gfx_reload_shaders](functions-7.md#gfx_reload_shaders)
- [gfx_color_combiner_get_features](functions-7.md#gfx_color_combiner_get_features)
- [gfx_get_program_id_from_shader_index](functions-7.md#gfx_get_program_id_from_shader_index)
- [gfx_use_program](functions-7.md#gfx_use_program)
- [gfx_shader_get_uniform_location](functions-7.md#gfx_shader_get_uniform_location)
- [gfx_shader_set_int](functions-7.md#gfx_shader_set_int)
- [gfx_shader_set_float](functions-7.md#gfx_shader_set_float)
- [gfx_shader_set_vec2](functions-7.md#gfx_shader_set_vec2)
- [gfx_shader_set_vec3](functions-7.md#gfx_shader_set_vec3)
- [gfx_shader_set_vec4](functions-7.md#gfx_shader_set_vec4)
- [gfx_shader_set_mat4](functions-7.md#gfx_shader_set_mat4)
- [vtx_get_from_name](functions-7.md#vtx_get_from_name)
- [vtx_get_name](functions-7.md#vtx_get_name)
- [vtx_get_count](functions-7.md#vtx_get_count)
- [vtx_get_vertex](functions-7.md#vtx_get_vertex)
- [vtx_get_next_vertex](functions-7.md#vtx_get_next_vertex)
- [vtx_copy](functions-7.md#vtx_copy)
- [vtx_create](functions-7.md#vtx_create)
- [vtx_resize](functions-7.md#vtx_resize)
- [vtx_delete](functions-7.md#vtx_delete)
- [vtx_delete_all](functions-7.md#vtx_delete_all)
<br />

View file

@ -143,7 +143,7 @@ The lua functions sent to `hook_event()` will be automatically called by SM64 wh
| HOOK_ON_GEO_PROCESS | Called when a GeoLayout is processed **Note:** You must set the `hookProcess` field of the graph node to a non-zero value | [GraphNode](../structs.md#GraphNode) graphNode, `integer` matStackIndex |
| HOOK_BEFORE_GEO_PROCESS | Called before a GeoLayout is processed **Note:** You must set the `hookProcess` field of the graph node to a non-zero value | [GraphNode](../structs.md#GraphNode) graphNode, `integer` matStackIndex |
| HOOK_ON_GEO_PROCESS_CHILDREN | Called when the children of a GeoLayout node is processed **Note:** You must set the `hookProcess` field of the parent graph node to a non-zero value | [GraphNode](../structs.md#GraphNode) graphNode, `integer` matStackIndex |
| HOOK_MARIO_OVERRIDE_GEOMETRY_INPUTS | Called before running Mario's geometry input logic, return `false` to not run it. | [MarioState](../structs.md) m |
| HOOK_MARIO_OVERRIDE_GEOMETRY_INPUTS | Called before running Mario's geometry input logic, return `false` to not run it. | [MarioState](../structs.md) m |
| HOOK_ON_INTERACTIONS | Called when the Mario interactions are processed | [MarioState](../structs.md#MarioState) mario |
| HOOK_ALLOW_FORCE_WATER_ACTION | Called when executing a non-water action while under the water's surface, or vice versa. Return `false` to prevent the player from being forced out of the action at the water's surface | [MarioState](../structs.md#MarioState) mario, `boolean` isInWaterAction |
| HOOK_BEFORE_WARP | Called before the local player warps. Return a table with `destLevel`, `destArea`, `destWarpNode`, to override the warp | `integer` destLevel, `integer` destArea, `integer` destWarpNode, `integer` arg |
@ -157,6 +157,9 @@ The lua functions sent to `hook_event()` will be automatically called by SM64 wh
| HOOK_ON_FIND_WATER_LEVEL | Called after water level detection completes. Return a number to override the water level | `number` x, `number` z, `number` waterLevel |
| HOOK_ON_FIND_POISON_GAS_LEVEL | Called after poison gas level detection completes. Return a number to override the gas level | `number` x, `number` z, `number` gasLevel |
| HOOK_ON_FIND_SURFACE_ON_RAY | Called after ray-surface intersection completes. Return `surface` to override the hit surface, or `surface, hitPos` to override both | `Vec3f` orig, `Vec3f` dir, [Surface](../structs.md#Surface) hitSurface, `Vec3f` hitPos |
| HOOK_ON_REFRESH_SHADERS | Called when a shader is refreshed | |
| HOOK_ON_VERTEX_SHADER_CREATE | Called when a vertex shader is created. Return a string to override the shader | [ColorCombiner](../structs.md#ColorCombiner) cc, `integer` shaderIndex |
| HOOK_ON_FRAGMENT_SHADER_CREATE | Called when a fragment shader is created. Return a string to override the shader | [ColorCombiner](../structs.md#ColorCombiner) cc, `integer` shaderIndex |
### Parameters

View file

@ -7,10 +7,13 @@
- [BehaviorDialogs](#BehaviorDialogs)
- [BehaviorTrajectories](#BehaviorTrajectories)
- [BehaviorValues](#BehaviorValues)
- [CCFeatures](#CCFeatures)
- [Camera](#Camera)
- [ChainSegment](#ChainSegment)
- [Character](#Character)
- [Color](#Color)
- [ColorCombiner](#ColorCombiner)
- [CombineMode](#CombineMode)
- [Controller](#Controller)
- [CustomLevelInfo](#CustomLevelInfo)
- [DateTime](#DateTime)
@ -77,6 +80,7 @@
- [RayIntersectionInfo](#RayIntersectionInfo)
- [RomhackCameraSettings](#RomhackCameraSettings)
- [ServerSettings](#ServerSettings)
- [ShaderProgram](#ShaderProgram)
- [SpawnInfo](#SpawnInfo)
- [SpawnParticlesInfo](#SpawnParticlesInfo)
- [StarPositions](#StarPositions)
@ -345,6 +349,22 @@
<br />
## [CCFeatures](#CCFeatures)
| Field | Type | Access |
| ----- | ---- | ------ |
| used_textures | `Array` <`boolean`> | |
| num_inputs | `integer` | |
| do_single | `Array` <`boolean`> | |
| do_multiply | `Array` <`boolean`> | |
| do_mix | `Array` <`boolean`> | |
| color_alpha_same | `Array` <`boolean`> | |
| do_noise | `boolean` | |
[:arrow_up_small:](#)
<br />
## [Camera](#Camera)
| Field | Type | Access |
@ -679,6 +699,38 @@
<br />
## [ColorCombiner](#ColorCombiner)
| Field | Type | Access |
| ----- | ---- | ------ |
| cm | [CombineMode](structs.md#CombineMode) | read-only |
| prg | [ShaderProgram](structs.md#ShaderProgram) | |
| shader_input_mapping | `Array` <`integer`> | |
| shader_input_mapping_as_u64 | `Array` <`integer`> | |
| shader_commands | `Array` <`integer`> | |
| shader_commands_as_u64 | `Array` <`integer`> | |
| hash | `integer` | |
[:arrow_up_small:](#)
<br />
## [CombineMode](#CombineMode)
| Field | Type | Access |
| ----- | ---- | ------ |
| rgb1 | `integer` | |
| alpha1 | `integer` | |
| rgb2 | `integer` | |
| alpha2 | `integer` | |
| all_values | `Array` <`integer`> | |
| flags | `integer` | |
| hash | `integer` | |
[:arrow_up_small:](#)
<br />
## [Controller](#Controller)
| Field | Type | Access |
@ -2839,6 +2891,26 @@
<br />
## [ShaderProgram](#ShaderProgram)
| Field | Type | Access |
| ----- | ---- | ------ |
| hash | `integer` | |
| opengl_program_id | `integer` | |
| num_inputs | `integer` | |
| used_textures | `Array` <`boolean`> | |
| num_floats | `integer` | |
| attrib_locations | `Array` <`integer`> | |
| uniform_locations | `Array` <`integer`> | |
| attrib_sizes | `Array` <`integer`> | |
| num_attribs | `integer` | |
| used_noise | `boolean` | |
| used_lightmap | `boolean` | |
[:arrow_up_small:](#)
<br />
## [SpawnInfo](#SpawnInfo)
| Field | Type | Access |

View file

@ -184,7 +184,7 @@ LookAt lookAt;
static struct GraphNodePerspective *sPerspectiveNode = NULL;
static Gfx* sPerspectivePos = NULL;
static Mtx* sPerspectiveMtx = NULL;
static Mtx* sPerspectiveMtx = NULL;
static f32 sPerspectiveAspect = 0;
static Vp* sViewport = NULL;
@ -200,6 +200,8 @@ static struct GraphNodeBackground* sBackgroundNode = NULL;
static struct GraphNodeRoot* sBackgroundNodeRoot = NULL;
static struct GraphNodeCamera* sCameraNode = NULL;
Mtx gInverseCameraMatrix = { 0 };
static struct GrowingArray* sShadowInterp = NULL;
struct ShadowInterp* gShadowInterpCurrent = NULL;
@ -350,6 +352,7 @@ void patch_mtx_interpolated(f32 delta) {
delta_interpolate_vec3f(focusInterp, sCameraNode->prevFocus, sCameraNode->focus, delta);
mtxf_lookat(camInterp.m, posInterp, focusInterp, sCameraNode->roll);
mtxf_to_mtx(&camInterp, camInterp.m);
mtxf_inverse(gInverseCameraMatrix.m, camInterp.m);
}
for (u32 i = 0; i < sMtxTbl->count; i++) {

View file

@ -20,6 +20,9 @@ extern struct GraphNodePerspective *gCurGraphNodeCamFrustum;
extern struct GraphNodeCamera *gCurGraphNodeCamera;
extern struct GraphNodeObject *gCurGraphNodeObject;
extern struct GraphNodeHeldObject *gCurGraphNodeHeldObject;
extern Mtx gInverseCameraMatrix;
extern u16 gAreaUpdateCounter;
extern struct Object* gCurGraphNodeProcessingObject;

View file

@ -209,10 +209,10 @@ Vtx *make_skybox_rect(s32 tileRow, s32 tileCol, s8 colorIndex, s32 row, s32 col)
f32 g = gSkyboxColor[1] / 255.0f;
f32 b = gSkyboxColor[2] / 255.0f;
u8 *colors = sSkyboxColors[colorIndex];
make_vertex(verts, 0, x, y, -1, 0, 0, colors[0] * r, colors[1] * g, colors[2] * b, 255);
make_vertex(verts, 1, x, y - SKYBOX_TILE_HEIGHT, -1, 0, 31 << 5, colors[0] * r, colors[1] * g, colors[2] * b, 255);
make_vertex(verts, 2, x + SKYBOX_TILE_WIDTH, y - SKYBOX_TILE_HEIGHT, -1, 31 << 5, 31 << 5, colors[0] * r, colors[1] * g, colors[2] * b, 255);
make_vertex(verts, 3, x + SKYBOX_TILE_WIDTH, y, -1, 31 << 5, 0, colors[0] * r, colors[1] * g, colors[2] * b, 255);
make_vertex(verts, 0, x, y, -2, 0, 0, colors[0] * r, colors[1] * g, colors[2] * b, 255);
make_vertex(verts, 1, x, y - SKYBOX_TILE_HEIGHT, -2, 0, 31 << 5, colors[0] * r, colors[1] * g, colors[2] * b, 255);
make_vertex(verts, 2, x + SKYBOX_TILE_WIDTH, y - SKYBOX_TILE_HEIGHT, -2, 31 << 5, 31 << 5, colors[0] * r, colors[1] * g, colors[2] * b, 255);
make_vertex(verts, 3, x + SKYBOX_TILE_WIDTH, y, -2, 31 << 5, 0, colors[0] * r, colors[1] * g, colors[2] * b, 255);
}
return verts;
}

View file

@ -1,10 +1,11 @@
#ifndef GFX_CC_H
#define GFX_CC_H
#include <PR/ultratypes.h>
#include <stdint.h>
#include <stdbool.h>
enum {
enum ColorCombinerSource {
CC_0,
CC_TEXEL0,
CC_TEXEL1,
@ -24,7 +25,7 @@ enum {
CC_ENUM_MAX,
};
enum {
enum ShaderInput {
SHADER_0,
SHADER_INPUT_1,
SHADER_INPUT_2,
@ -59,47 +60,57 @@ struct CCFeatures {
bool do_noise;
};
enum CombineModeFlags {
USE_ALPHA = 1 << 0,
USE_FOG = 1 << 1,
TEXTURE_EDGE = 1 << 2,
USE_DITHER = 1 << 3,
USE_2CYCLE = 1 << 4,
LIGHT_MAP = 1 << 5
};
#pragma pack(1)
struct CombineMode {
union {
struct {
uint32_t rgb1;
uint32_t alpha1;
uint32_t rgb2;
uint32_t alpha2;
u32 rgb1;
u32 alpha1;
u32 rgb2;
u32 alpha2;
};
uint8_t all_values[16];
u8 all_values[16];
};
union {
struct {
uint8_t use_alpha : 1;
uint8_t use_fog : 1;
uint8_t texture_edge : 1;
uint8_t use_dither : 1;
uint8_t use_2cycle : 1;
uint8_t light_map : 1;
u8 use_alpha : 1;
u8 use_fog : 1;
u8 texture_edge : 1;
u8 use_dither : 1;
u8 use_2cycle : 1;
u8 light_map : 1;
};
uint32_t flags;
u32 flags;
};
uint64_t hash;
s64 hash;
};
#pragma pack()
#define SHADER_CMD_LENGTH 16
#define CC_MAX_SHADERS 64
#define CC_MAX_INPUTS 8
struct ColorCombiner {
struct CombineMode cm;
struct ShaderProgram *prg;
union {
uint8_t shader_input_mapping[16];
uint64_t shader_input_mapping_as_u64[8];
u8 shader_input_mapping[16];
u64 shader_input_mapping_as_u64[8];
};
union {
uint8_t shader_commands[16];
uint64_t shader_commands_as_u64[8];
u8 shader_commands[16];
u64 shader_commands_as_u64[8];
};
uint64_t hash;
u64 hash;
};
#ifdef __cplusplus

View file

@ -77,12 +77,12 @@ struct ShaderProgramD3D11 {
static struct {
HMODULE d3d11_module;
PFN_D3D11_CREATE_DEVICE D3D11CreateDevice;
HMODULE d3dcompiler_module;
pD3DCompile D3DCompile;
D3D_FEATURE_LEVEL feature_level;
ComPtr<ID3D11Device> device;
ComPtr<IDXGISwapChain1> swap_chain;
ComPtr<ID3D11DeviceContext> context;
@ -324,6 +324,9 @@ static void gfx_d3d11_load_shader(struct ShaderProgram *new_prg) {
d3d.shader_program = (struct ShaderProgramD3D11 *)new_prg;
}
static void gfx_d3d11_remove_shaders(void) {
}
static struct ShaderProgram *gfx_d3d11_create_and_load_new_shader(struct ColorCombiner* cc) {
CCFeatures cc_features = { 0 };
gfx_cc_get_features(cc, &cc_features);
@ -425,6 +428,11 @@ static struct ShaderProgram *gfx_d3d11_lookup_shader(struct ColorCombiner* cc) {
return nullptr;
}
static struct ShaderProgram *gfx_d3d11_lookup_shader_using_index(u8 shaderIndex) {
if (shaderIndex >= d3d.shader_program_pool_size) return nullptr;
return (struct ShaderProgram *)&d3d.shader_program_pool[i];
}
static void gfx_d3d11_shader_get_info(struct ShaderProgram *prg, uint8_t *num_inputs, bool used_textures[2]) {
struct ShaderProgramD3D11 *p = (struct ShaderProgramD3D11 *)prg;
@ -719,8 +727,10 @@ struct GfxRenderingAPI gfx_direct3d11_api = {
gfx_d3d11_z_is_from_0_to_1,
gfx_d3d11_unload_shader,
gfx_d3d11_load_shader,
gfx_d3d11_remove_shaders,
gfx_d3d11_create_and_load_new_shader,
gfx_d3d11_lookup_shader,
gfx_d3d11_lookup_shader_using_index,
gfx_d3d11_shader_get_info,
gfx_d3d11_new_texture,
gfx_d3d11_select_texture,

View file

@ -129,6 +129,9 @@ static void gfx_dummy_renderer_unload_shader(UNUSED struct ShaderProgram *old_pr
static void gfx_dummy_renderer_load_shader(UNUSED struct ShaderProgram *new_prg) {
}
static void gfx_dummy_renderer_remove_shaders(void) {
}
static struct ShaderProgram *gfx_dummy_renderer_create_and_load_new_shader(UNUSED struct ColorCombiner* cc) {
return NULL;
}
@ -137,6 +140,10 @@ static struct ShaderProgram *gfx_dummy_renderer_lookup_shader(UNUSED struct Colo
return NULL;
}
static struct ShaderProgram *gfx_dummy_renderer_lookup_shader_using_index(u8 shaderIndex) {
return NULL;
}
static void gfx_dummy_renderer_shader_get_info(UNUSED struct ShaderProgram *prg, uint8_t *num_inputs, bool used_textures[2]) {
*num_inputs = 0;
used_textures[0] = false;
@ -223,8 +230,10 @@ struct GfxRenderingAPI gfx_dummy_renderer_api = {
gfx_dummy_renderer_z_is_from_0_to_1,
gfx_dummy_renderer_unload_shader,
gfx_dummy_renderer_load_shader,
gfx_dummy_renderer_remove_shaders,
gfx_dummy_renderer_create_and_load_new_shader,
gfx_dummy_renderer_lookup_shader,
gfx_dummy_renderer_lookup_shader_using_index,
gfx_dummy_renderer_shader_get_info,
gfx_dummy_renderer_new_texture,
gfx_dummy_renderer_select_texture,

View file

@ -40,23 +40,12 @@
#include "gfx_cc.h"
#include "gfx_rendering_api.h"
#include "gfx_pc.h"
#include "gfx_opengl.h"
#include "pc/lua/smlua.h"
#include "game/rendering_graph_node.h"
#define TEX_CACHE_STEP 512
struct ShaderProgram {
uint64_t hash;
GLuint opengl_program_id;
uint8_t num_inputs;
bool used_textures[2];
uint8_t num_floats;
GLint attrib_locations[7];
GLint uniform_locations[7];
uint8_t attrib_sizes[7];
uint8_t num_attribs;
bool used_noise;
bool used_lightmap;
};
struct GLTexture {
GLuint gltex;
GLfloat size[2];
@ -66,6 +55,7 @@ struct GLTexture {
static struct ShaderProgram shader_program_pool[CC_MAX_SHADERS];
static uint8_t shader_program_pool_size = 0;
static uint8_t shader_program_pool_index = 0;
static GLuint opengl_vbo;
static GLuint opengl_vao;
@ -95,13 +85,16 @@ static void gfx_opengl_vertex_array_set_attribs(struct ShaderProgram *prg) {
}
static inline void gfx_opengl_set_shader_uniforms(struct ShaderProgram *prg) {
if (prg->used_noise) { glUniform1f(prg->uniform_locations[4], (float)frame_count); }
if (prg->used_lightmap) { glUniform3f(prg->uniform_locations[5], gVertexColor[0] / 255.0f, gVertexColor[1] / 255.0f, gVertexColor[2] / 255.0f); }
glUniform1f(prg->uniform_locations[4], (float)frame_count);
glUniform3f(prg->uniform_locations[5], gVertexColor[0] / 255.0f, gVertexColor[1] / 255.0f, gVertexColor[2] / 255.0f);
glUniform1i(prg->uniform_locations[6], configFiltering);
glUniformMatrix4fv(prg->uniform_locations[7], 1, GL_FALSE, (const GLfloat *)rsp.modelview_matrix_stack[rsp.modelview_matrix_stack_size - 1]);
glUniformMatrix4fv(prg->uniform_locations[8], 1, GL_FALSE, (const GLfloat *)rsp.P_matrix);
glUniformMatrix4fv(prg->uniform_locations[9], 1, GL_FALSE, (const GLfloat *)gInverseCameraMatrix.m);
}
static inline void gfx_opengl_set_texture_uniforms(struct ShaderProgram *prg, const int tile) {
if (prg->used_textures[tile] && opengl_tex[tile]) {
if (opengl_tex[tile]) {
glUniform2f(prg->uniform_locations[tile*2 + 0], opengl_tex[tile]->size[0], opengl_tex[tile]->size[1]);
glUniform1i(prg->uniform_locations[tile*2 + 1], opengl_tex[tile]->filter);
}
@ -127,6 +120,16 @@ static void gfx_opengl_load_shader(struct ShaderProgram *new_prg) {
gfx_opengl_set_texture_uniforms(new_prg, 1);
}
static void gfx_opengl_remove_shaders(void) {
for (int i = 0; i < CC_MAX_SHADERS; i++) {
gfx_opengl_unload_shader(&shader_program_pool[i]);
memset(&shader_program_pool[i], 0, sizeof(shader_program_pool[i]));
}
shader_program_pool_index = 0;
shader_program_pool_size = 0;
}
static void append_str(char *buf, size_t *len, const char *str) {
while (*str != '\0') buf[(*len)++] = *str++;
}
@ -136,7 +139,7 @@ static void append_line(char *buf, size_t *len, const char *str) {
buf[(*len)++] = '\n';
}
static const char *shader_item_to_str(uint32_t item, bool with_alpha, bool only_alpha, bool inputs_have_alpha, bool hint_single_element) {
static const char *shader_item_to_str(uint32_t item, bool with_alpha, bool only_alpha, bool hint_single_element) {
if (!only_alpha) {
switch (item) {
case SHADER_0:
@ -144,21 +147,21 @@ static const char *shader_item_to_str(uint32_t item, bool with_alpha, bool only_
case SHADER_1:
return with_alpha ? "vec4(1.0, 1.0, 1.0, 1.0)" : "vec3(1.0, 1.0, 1.0)";
case SHADER_INPUT_1:
return with_alpha || !inputs_have_alpha ? "vInput1" : "vInput1.rgb";
return with_alpha ? "vInput1" : "vInput1.rgb";
case SHADER_INPUT_2:
return with_alpha || !inputs_have_alpha ? "vInput2" : "vInput2.rgb";
return with_alpha ? "vInput2" : "vInput2.rgb";
case SHADER_INPUT_3:
return with_alpha || !inputs_have_alpha ? "vInput3" : "vInput3.rgb";
return with_alpha ? "vInput3" : "vInput3.rgb";
case SHADER_INPUT_4:
return with_alpha || !inputs_have_alpha ? "vInput4" : "vInput4.rgb";
return with_alpha ? "vInput4" : "vInput4.rgb";
case SHADER_INPUT_5:
return with_alpha || !inputs_have_alpha ? "vInput5" : "vInput5.rgb";
return with_alpha ? "vInput5" : "vInput5.rgb";
case SHADER_INPUT_6:
return with_alpha || !inputs_have_alpha ? "vInput6" : "vInput6.rgb";
return with_alpha ? "vInput6" : "vInput6.rgb";
case SHADER_INPUT_7:
return with_alpha || !inputs_have_alpha ? "vInput7" : "vInput7.rgb";
return with_alpha ? "vInput7" : "vInput7.rgb";
case SHADER_INPUT_8:
return with_alpha || !inputs_have_alpha ? "vInput8" : "vInput8.rgb";
return with_alpha ? "vInput8" : "vInput8.rgb";
case SHADER_TEXEL0:
return with_alpha ? "texVal0" : "texVal0.rgb";
case SHADER_TEXEL0A:
@ -218,30 +221,30 @@ static const char *shader_item_to_str(uint32_t item, bool with_alpha, bool only_
return "unknown";
}
static void append_formula(char *buf, size_t *len, uint8_t* cmd, bool do_single, bool do_multiply, bool do_mix, bool with_alpha, bool only_alpha, bool opt_alpha) {
static void append_formula(char *buf, size_t *len, uint8_t* cmd, bool do_single, bool do_multiply, bool do_mix, bool with_alpha, bool only_alpha) {
if (do_single) {
append_str(buf, len, shader_item_to_str(cmd[only_alpha * 4 + 3], with_alpha, only_alpha, opt_alpha, false));
append_str(buf, len, shader_item_to_str(cmd[only_alpha * 4 + 3], with_alpha, only_alpha, false));
} else if (do_multiply) {
append_str(buf, len, shader_item_to_str(cmd[only_alpha * 4 + 0], with_alpha, only_alpha, opt_alpha, false));
append_str(buf, len, shader_item_to_str(cmd[only_alpha * 4 + 0], with_alpha, only_alpha, false));
append_str(buf, len, " * ");
append_str(buf, len, shader_item_to_str(cmd[only_alpha * 4 + 2], with_alpha, only_alpha, opt_alpha, true));
append_str(buf, len, shader_item_to_str(cmd[only_alpha * 4 + 2], with_alpha, only_alpha, true));
} else if (do_mix) {
append_str(buf, len, "mix(");
append_str(buf, len, shader_item_to_str(cmd[only_alpha * 4 + 1], with_alpha, only_alpha, opt_alpha, false));
append_str(buf, len, shader_item_to_str(cmd[only_alpha * 4 + 1], with_alpha, only_alpha, false));
append_str(buf, len, ", ");
append_str(buf, len, shader_item_to_str(cmd[only_alpha * 4 + 0], with_alpha, only_alpha, opt_alpha, false));
append_str(buf, len, shader_item_to_str(cmd[only_alpha * 4 + 0], with_alpha, only_alpha, false));
append_str(buf, len, ", ");
append_str(buf, len, shader_item_to_str(cmd[only_alpha * 4 + 2], with_alpha, only_alpha, opt_alpha, true));
append_str(buf, len, shader_item_to_str(cmd[only_alpha * 4 + 2], with_alpha, only_alpha, true));
append_str(buf, len, ")");
} else {
append_str(buf, len, "(");
append_str(buf, len, shader_item_to_str(cmd[only_alpha * 4 + 0], with_alpha, only_alpha, opt_alpha, false));
append_str(buf, len, shader_item_to_str(cmd[only_alpha * 4 + 0], with_alpha, only_alpha, false));
append_str(buf, len, " - ");
append_str(buf, len, shader_item_to_str(cmd[only_alpha * 4 + 1], with_alpha, only_alpha, opt_alpha, false));
append_str(buf, len, shader_item_to_str(cmd[only_alpha * 4 + 1], with_alpha, only_alpha, false));
append_str(buf, len, ") * ");
append_str(buf, len, shader_item_to_str(cmd[only_alpha * 4 + 2], with_alpha, only_alpha, opt_alpha, true));
append_str(buf, len, shader_item_to_str(cmd[only_alpha * 4 + 2], with_alpha, only_alpha, true));
append_str(buf, len, " + ");
append_str(buf, len, shader_item_to_str(cmd[only_alpha * 4 + 3], with_alpha, only_alpha, opt_alpha, false));
append_str(buf, len, shader_item_to_str(cmd[only_alpha * 4 + 3], with_alpha, only_alpha, false));
}
}
@ -265,48 +268,45 @@ static struct ShaderProgram *gfx_opengl_create_and_load_new_shader(struct ColorC
char fs_buf[2048];
size_t vs_len = 0;
size_t fs_len = 0;
size_t num_floats = 4;
size_t num_floats = 0;
// Vertex shader
#ifdef USE_GLES
append_line(vs_buf, &vs_len, "#version 100");
append_line(vs_buf, &vs_len, "#version 300 es");
#else
append_line(vs_buf, &vs_len, "#version 120");
append_line(vs_buf, &vs_len, "#version 150");
#endif
append_line(vs_buf, &vs_len, "attribute vec4 aVtxPos;");
if (ccf.used_textures[0] || ccf.used_textures[1]) {
append_line(vs_buf, &vs_len, "attribute vec2 aTexCoord;");
append_line(vs_buf, &vs_len, "varying vec2 vTexCoord;");
num_floats += 2;
}
if (opt_fog) {
append_line(vs_buf, &vs_len, "attribute vec4 aFog;");
append_line(vs_buf, &vs_len, "varying vec4 vFog;");
append_line(vs_buf, &vs_len, "in vec4 aVtxPos;");
num_floats += 4;
append_line(vs_buf, &vs_len, "in vec2 aTexCoord;");
append_line(vs_buf, &vs_len, "out vec2 vTexCoord;");
num_floats += 2;
append_line(vs_buf, &vs_len, "in vec4 aFog;");
append_line(vs_buf, &vs_len, "out vec4 vFog;");
num_floats += 4;
append_line(vs_buf, &vs_len, "in vec2 aLightMap;");
append_line(vs_buf, &vs_len, "out vec2 vLightMap;");
num_floats += 2;
for (int i = 0; i < CC_MAX_INPUTS; i++) {
vs_len += sprintf(vs_buf + vs_len, "in vec4 aInput%d;\n", i + 1);
vs_len += sprintf(vs_buf + vs_len, "out vec4 vInput%d;\n", i + 1);
num_floats += 4;
}
if (opt_light_map) {
append_line(vs_buf, &vs_len, "attribute vec2 aLightMap;");
append_line(vs_buf, &vs_len, "varying vec2 vLightMap;");
num_floats += 2;
}
for (int i = 0; i < ccf.num_inputs; i++) {
vs_len += sprintf(vs_buf + vs_len, "attribute vec%d aInput%d;\n", opt_alpha ? 4 : 3, i + 1);
vs_len += sprintf(vs_buf + vs_len, "varying vec%d vInput%d;\n", opt_alpha ? 4 : 3, i + 1);
num_floats += opt_alpha ? 4 : 3;
}
append_line(vs_buf, &vs_len, "in vec3 aNormal;");
append_line(vs_buf, &vs_len, "out vec3 vNormal;");
num_floats += 3;
append_line(vs_buf, &vs_len, "in vec3 aBarycentric;");
append_line(vs_buf, &vs_len, "out vec3 vBarycentric;");
num_floats += 3;
append_line(vs_buf, &vs_len, "void main() {");
if (ccf.used_textures[0] || ccf.used_textures[1]) {
append_line(vs_buf, &vs_len, "vTexCoord = aTexCoord;");
}
if (opt_fog) {
append_line(vs_buf, &vs_len, "vFog = aFog;");
}
if (opt_light_map) {
append_line(vs_buf, &vs_len, "vLightMap = aLightMap;");
}
for (int i = 0; i < ccf.num_inputs; i++) {
append_line(vs_buf, &vs_len, "vTexCoord = aTexCoord;");
append_line(vs_buf, &vs_len, "vFog = aFog;");
append_line(vs_buf, &vs_len, "vLightMap = aLightMap;");
for (int i = 0; i < CC_MAX_INPUTS; i++) {
vs_len += sprintf(vs_buf + vs_len, "vInput%d = aInput%d;\n", i + 1, i + 1);
}
append_line(vs_buf, &vs_len, "vNormal = aNormal;");
append_line(vs_buf, &vs_len, "vBarycentric = aBarycentric;");
append_line(vs_buf, &vs_len, "gl_Position = aVtxPos;");
append_line(vs_buf, &vs_len, "}");
@ -315,20 +315,16 @@ static struct ShaderProgram *gfx_opengl_create_and_load_new_shader(struct ColorC
append_line(fs_buf, &fs_len, "#version 100");
append_line(fs_buf, &fs_len, "precision mediump float;");
#else
append_line(fs_buf, &fs_len, "#version 120");
append_line(fs_buf, &fs_len, "#version 150");
#endif
if (ccf.used_textures[0] || ccf.used_textures[1]) {
append_line(fs_buf, &fs_len, "varying vec2 vTexCoord;");
}
if (opt_fog) {
append_line(fs_buf, &fs_len, "varying vec4 vFog;");
}
if (opt_light_map) {
append_line(fs_buf, &fs_len, "varying vec2 vLightMap;");
}
for (int i = 0; i < ccf.num_inputs; i++) {
fs_len += sprintf(fs_buf + fs_len, "varying vec%d vInput%d;\n", opt_alpha ? 4 : 3, i + 1);
append_line(fs_buf, &fs_len, "out vec4 fragColor;");
append_line(fs_buf, &fs_len, "in vec2 vTexCoord;");
append_line(fs_buf, &fs_len, "in vec4 vFog;");
append_line(fs_buf, &fs_len, "in vec2 vLightMap;");
for (int i = 0; i < CC_MAX_INPUTS; i++) {
fs_len += sprintf(fs_buf + fs_len, "in vec4 vInput%d;\n", i + 1);
}
if (ccf.used_textures[0]) {
append_line(fs_buf, &fs_len, "uniform sampler2D uTex0;");
@ -345,7 +341,7 @@ static struct ShaderProgram *gfx_opengl_create_and_load_new_shader(struct ColorC
// Original author: ArthurCarvalho
// Modified GLSL implementation by twinaphex, mupen64plus-libretro project.
if (ccf.used_textures[0] || ccf.used_textures[1]) {
append_line(fs_buf, &fs_len, "#define TEX_OFFSET(off) texture2D(tex, texCoord - (off)/texSize)");
append_line(fs_buf, &fs_len, "#define TEX_OFFSET(off) texture(tex, texCoord - (off)/texSize)");
append_line(fs_buf, &fs_len, "vec4 filter3point(in sampler2D tex, in vec2 texCoord, in vec2 texSize) {");
append_line(fs_buf, &fs_len, " vec2 offset = fract(texCoord*texSize - vec2(0.5));");
append_line(fs_buf, &fs_len, " offset -= step(1.0, offset.x + offset.y);");
@ -354,11 +350,11 @@ static struct ShaderProgram *gfx_opengl_create_and_load_new_shader(struct ColorC
append_line(fs_buf, &fs_len, " vec4 c2 = TEX_OFFSET(vec2(offset.x, offset.y - sign(offset.y)));");
append_line(fs_buf, &fs_len, " return c0 + abs(offset.x)*(c1-c0) + abs(offset.y)*(c2-c0);");
append_line(fs_buf, &fs_len, "}");
append_line(fs_buf, &fs_len, "vec4 sampleTex(in sampler2D tex, in vec2 uv, in vec2 texSize, in bool dofilter, in int filter) {");
append_line(fs_buf, &fs_len, " if (dofilter && filter == 2)");
append_line(fs_buf, &fs_len, "vec4 sampleTex(in sampler2D tex, in vec2 uv, in vec2 texSize, in bool dofilter, in int filterType) {");
append_line(fs_buf, &fs_len, " if (dofilter && filterType == 2)");
append_line(fs_buf, &fs_len, " return filter3point(tex, uv, texSize);");
append_line(fs_buf, &fs_len, " else");
append_line(fs_buf, &fs_len, " return texture2D(tex, uv);");
append_line(fs_buf, &fs_len, " return texture(tex, uv);");
append_line(fs_buf, &fs_len, "}");
}
@ -401,12 +397,12 @@ static struct ShaderProgram *gfx_opengl_create_and_load_new_shader(struct ColorC
u8* cmd = &cc->shader_commands[i * 8];
if (!ccf.color_alpha_same[i] && opt_alpha) {
append_str(fs_buf, &fs_len, "vec4(");
append_formula(fs_buf, &fs_len, cmd, ccf.do_single[i*2+0], ccf.do_multiply[i*2+0], ccf.do_mix[i*2+0], false, false, true);
append_formula(fs_buf, &fs_len, cmd, ccf.do_single[i*2+0], ccf.do_multiply[i*2+0], ccf.do_mix[i*2+0], false, false);
append_str(fs_buf, &fs_len, ", ");
append_formula(fs_buf, &fs_len, cmd, ccf.do_single[i*2+1], ccf.do_multiply[i*2+1], ccf.do_mix[i*2+1], true, true, true);
append_formula(fs_buf, &fs_len, cmd, ccf.do_single[i*2+1], ccf.do_multiply[i*2+1], ccf.do_mix[i*2+1], true, true);
append_str(fs_buf, &fs_len, ")");
} else {
append_formula(fs_buf, &fs_len, cmd, ccf.do_single[i*2+0], ccf.do_multiply[i*2+0], ccf.do_mix[i*2+0], opt_alpha, false, opt_alpha);
append_formula(fs_buf, &fs_len, cmd, ccf.do_single[i*2+0], ccf.do_multiply[i*2+0], ccf.do_mix[i*2+0], opt_alpha, false);
}
append_line(fs_buf, &fs_len, ";");
@ -434,9 +430,9 @@ static struct ShaderProgram *gfx_opengl_create_and_load_new_shader(struct ColorC
}
if (opt_alpha) {
append_line(fs_buf, &fs_len, "gl_FragColor = texel;");
append_line(fs_buf, &fs_len, "fragColor = texel;");
} else {
append_line(fs_buf, &fs_len, "gl_FragColor = vec4(texel, 1.0);");
append_line(fs_buf, &fs_len, "fragColor = vec4(texel, 1.0);");
}
append_line(fs_buf, &fs_len, "}");
@ -449,8 +445,19 @@ static struct ShaderProgram *gfx_opengl_create_and_load_new_shader(struct ColorC
puts(fs_buf);
puts("End");*/
const GLchar *sources[2] = { vs_buf, fs_buf };
const GLint lengths[2] = { vs_len, fs_len };
const char* vertexShader = vs_buf;
bool usingCustomVertexShader = false;
const char* fragmentShader = fs_buf;
bool usingCustomFragmentShader = false;
smlua_call_event_hooks(HOOK_ON_VERTEX_SHADER_CREATE, cc, shader_program_pool_index, &vertexShader);
smlua_call_event_hooks(HOOK_ON_FRAGMENT_SHADER_CREATE, cc, shader_program_pool_index, &fragmentShader);
if (strcmp(vertexShader, vs_buf) != 0) usingCustomVertexShader = true;
if (strcmp(fragmentShader, fs_buf) != 0) usingCustomFragmentShader = true;
const GLchar *sources[2] = { vertexShader, fragmentShader };
GLint lengths[2] = { strlen(vertexShader), strlen(fragmentShader) };
GLint success;
GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER);
@ -461,10 +468,26 @@ static struct ShaderProgram *gfx_opengl_create_and_load_new_shader(struct ColorC
GLint max_length = 0;
glGetShaderiv(vertex_shader, GL_INFO_LOG_LENGTH, &max_length);
char error_log[1024];
fprintf(stderr, "Vertex shader compilation failed\n");
glGetShaderInfoLog(vertex_shader, max_length, &max_length, &error_log[0]);
fprintf(stderr, "%s\n", &error_log[0]);
sys_fatal("vertex shader compilation failed (see terminal)");
if (!usingCustomVertexShader) {
fprintf(stderr, "Vertex shader compilation failed\n");
fprintf(stderr, "%s\n", &error_log[0]);
sys_fatal("vertex shader compilation failed (see terminal)");
} else {
LOG_LUA_LINE("Vertex Shader: %s", error_log);
}
usingCustomVertexShader = false;
sources[0] = vs_buf;
lengths[0] = vs_len;
glShaderSource(vertex_shader, 1, &sources[0], &lengths[0]);
glCompileShader(vertex_shader);
glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &success);
if (!success) {
fprintf(stderr, "Vertex shader compilation failed\n");
glGetShaderInfoLog(vertex_shader, max_length, &max_length, &error_log[0]);
fprintf(stderr, "%s\n", &error_log[0]);
sys_fatal("vertex shader compilation failed (see terminal)");
}
}
GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
@ -475,10 +498,26 @@ static struct ShaderProgram *gfx_opengl_create_and_load_new_shader(struct ColorC
GLint max_length = 0;
glGetShaderiv(fragment_shader, GL_INFO_LOG_LENGTH, &max_length);
char error_log[1024];
fprintf(stderr, "Fragment shader compilation failed\n");
glGetShaderInfoLog(fragment_shader, max_length, &max_length, &error_log[0]);
fprintf(stderr, "%s\n", &error_log[0]);
sys_fatal("fragment shader compilation failed (see terminal)");
if (!usingCustomFragmentShader) {
fprintf(stderr, "Fragment shader compilation failed\n");
fprintf(stderr, "%s\n", &error_log[0]);
sys_fatal("fragment shader compilation failed (see terminal)");
} else {
LOG_LUA_LINE("Fragment Shader: %s", &error_log[0]);
}
usingCustomFragmentShader = false;
sources[1] = fs_buf;
lengths[1] = fs_len;
glShaderSource(fragment_shader, 1, &sources[1], &lengths[1]);
glCompileShader(fragment_shader);
glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &success);
if (!success) {
fprintf(stderr, "Fragment shader compilation failed\n");
glGetShaderInfoLog(fragment_shader, max_length, &max_length, &error_log[0]);
fprintf(stderr, "%s\n", &error_log[0]);
sys_fatal("fragment shader compilation failed (see terminal)");
}
}
GLuint shader_program = glCreateProgram();
@ -496,31 +535,33 @@ static struct ShaderProgram *gfx_opengl_create_and_load_new_shader(struct ColorC
prg->attrib_sizes[cnt] = 4;
++cnt;
if (ccf.used_textures[0] || ccf.used_textures[1]) {
prg->attrib_locations[cnt] = glGetAttribLocation(shader_program, "aTexCoord");
prg->attrib_sizes[cnt] = 2;
++cnt;
}
prg->attrib_locations[cnt] = glGetAttribLocation(shader_program, "aTexCoord");
prg->attrib_sizes[cnt] = 2;
++cnt;
if (opt_fog) {
prg->attrib_locations[cnt] = glGetAttribLocation(shader_program, "aFog");
prg->attrib_locations[cnt] = glGetAttribLocation(shader_program, "aFog");
prg->attrib_sizes[cnt] = 4;
++cnt;
prg->attrib_locations[cnt] = glGetAttribLocation(shader_program, "aLightMap");
prg->attrib_sizes[cnt] = 2;
++cnt;
for (int i = 0; i < CC_MAX_INPUTS; i++) {
char name[16];
sprintf(name, "aInput%d", i + 1);
prg->attrib_locations[cnt] = glGetAttribLocation(shader_program, name);
prg->attrib_sizes[cnt] = 4;
++cnt;
}
if (opt_light_map) {
prg->attrib_locations[cnt] = glGetAttribLocation(shader_program, "aLightMap");
prg->attrib_sizes[cnt] = 2;
++cnt;
}
prg->attrib_locations[cnt] = glGetAttribLocation(shader_program, "aNormal");
prg->attrib_sizes[cnt] = 3;
++cnt;
for (int i = 0; i < ccf.num_inputs; i++) {
char name[16];
sprintf(name, "aInput%d", i + 1);
prg->attrib_locations[cnt] = glGetAttribLocation(shader_program, name);
prg->attrib_sizes[cnt] = opt_alpha ? 4 : 3;
++cnt;
}
prg->attrib_locations[cnt] = glGetAttribLocation(shader_program, "aBarycentric");
prg->attrib_sizes[cnt] = 3;
++cnt;
prg->hash = cc->hash;
prg->opengl_program_id = shader_program;
@ -532,34 +573,32 @@ static struct ShaderProgram *gfx_opengl_create_and_load_new_shader(struct ColorC
gfx_opengl_load_shader(prg);
if (ccf.used_textures[0]) {
GLint sampler_location = glGetUniformLocation(shader_program, "uTex0");
prg->uniform_locations[0] = glGetUniformLocation(shader_program, "uTex0Size");
prg->uniform_locations[1] = glGetUniformLocation(shader_program, "uTex0Filter");
glUniform1i(sampler_location, 0);
}
if (ccf.used_textures[1]) {
GLint sampler_location = glGetUniformLocation(shader_program, "uTex1");
prg->uniform_locations[2] = glGetUniformLocation(shader_program, "uTex1Size");
prg->uniform_locations[3] = glGetUniformLocation(shader_program, "uTex1Filter");
glUniform1i(sampler_location, 1);
}
GLint sampler_location = glGetUniformLocation(shader_program, "uTex0");
prg->uniform_locations[0] = glGetUniformLocation(shader_program, "uTex0Size");
prg->uniform_locations[1] = glGetUniformLocation(shader_program, "uTex0Filter");
glUniform1i(sampler_location, 0);
sampler_location = glGetUniformLocation(shader_program, "uTex1");
prg->uniform_locations[2] = glGetUniformLocation(shader_program, "uTex1Size");
prg->uniform_locations[3] = glGetUniformLocation(shader_program, "uTex1Filter");
glUniform1i(sampler_location, 1);
prg->uniform_locations[4] = glGetUniformLocation(shader_program, "uFrameCount");
if ((opt_alpha && opt_dither) || ccf.do_noise) {
prg->uniform_locations[4] = glGetUniformLocation(shader_program, "uFrameCount");
prg->used_noise = true;
} else {
prg->used_noise = false;
}
if (opt_light_map) {
prg->uniform_locations[5] = glGetUniformLocation(shader_program, "uLightmapColor");
prg->used_lightmap = true;
} else {
prg->used_lightmap = false;
}
prg->uniform_locations[5] = glGetUniformLocation(shader_program, "uLightmapColor");
prg->used_lightmap = opt_light_map;
// hah
prg->uniform_locations[6] = glGetUniformLocation(shader_program, "uFilter");
prg->uniform_locations[7] = glGetUniformLocation(shader_program, "uModelViewMatrix");
prg->uniform_locations[8] = glGetUniformLocation(shader_program, "uProjectionMatrix");
prg->uniform_locations[9] = glGetUniformLocation(shader_program, "uInverseViewMatrix");
return prg;
}
@ -573,6 +612,11 @@ static struct ShaderProgram *gfx_opengl_lookup_shader(struct ColorCombiner* cc)
return NULL;
}
static struct ShaderProgram* gfx_opengl_lookup_shader_using_index(uint8_t shaderIndex) {
if (shaderIndex >= shader_program_pool_size) return NULL;
return &shader_program_pool[shaderIndex];
}
static void gfx_opengl_shader_get_info(struct ShaderProgram *prg, uint8_t *num_inputs, bool used_textures[2]) {
*num_inputs = prg->num_inputs;
used_textures[0] = prg->used_textures[0];
@ -744,8 +788,10 @@ struct GfxRenderingAPI gfx_opengl_api = {
gfx_opengl_z_is_from_0_to_1,
gfx_opengl_unload_shader,
gfx_opengl_load_shader,
gfx_opengl_remove_shaders,
gfx_opengl_create_and_load_new_shader,
gfx_opengl_lookup_shader,
gfx_opengl_lookup_shader_using_index,
gfx_opengl_shader_get_info,
gfx_opengl_new_texture,
gfx_opengl_select_texture,

View file

@ -3,6 +3,24 @@
#include "gfx_rendering_api.h"
#define MAX_SHADER_TEXTURES 2
#define MAX_SHADER_ATTRIBUTES 24
#define MAX_SHADER_UNIFORMS 24
struct ShaderProgram {
u64 hash;
u32 opengl_program_id;
u8 num_inputs;
bool used_textures[MAX_SHADER_TEXTURES];
u8 num_floats;
u32 attrib_locations[MAX_SHADER_ATTRIBUTES];
u32 uniform_locations[MAX_SHADER_UNIFORMS];
u8 attrib_sizes[MAX_SHADER_ATTRIBUTES];
u8 num_attribs;
bool used_noise;
bool used_lightmap;
};
extern struct GfxRenderingAPI gfx_opengl_api;
#endif

View file

@ -246,6 +246,9 @@ static void gfx_opengl_load_shader(struct ShaderProgram *new_prg) {
cur_shader->enabled = false;
}
static void gfx_opengl_remove_shaders(void) {
}
static struct ShaderProgram *gfx_opengl_create_and_load_new_shader(struct ColorCombiner* cc) {
struct ShaderProgram *prg = &shader_program_pool[shader_program_pool_size++];
@ -292,6 +295,11 @@ static struct ShaderProgram *gfx_opengl_lookup_shader(struct ColorCombiner* cc)
return NULL;
}
static struct ShaderProgram *gfx_opengl_lookup_shader_using_index(u8 shaderIndex) {
if (shaderIndex >= shader_program_pool_size) return NULL;
return &shader_program_pool[shaderIndex];
}
static void gfx_opengl_shader_get_info(struct ShaderProgram *prg, uint8_t *num_inputs, bool used_textures[2]) {
*num_inputs = prg->num_inputs;
used_textures[0] = prg->texture_used[0];
@ -568,8 +576,10 @@ struct GfxRenderingAPI gfx_opengl_api = {
gfx_opengl_z_is_from_0_to_1,
gfx_opengl_unload_shader,
gfx_opengl_load_shader,
gfx_opengl_remove_shaders,
gfx_opengl_create_and_load_new_shader,
gfx_opengl_lookup_shader,
gfx_opengl_lookup_shader_using_index,
gfx_opengl_shader_get_info,
gfx_opengl_new_texture,
gfx_opengl_select_texture,

View file

@ -53,29 +53,7 @@ static struct ColorCombiner color_combiner_pool[CC_MAX_SHADERS] = { 0 };
static uint8_t color_combiner_pool_size = 0;
static uint8_t color_combiner_pool_index = 0;
static struct RSP {
ALIGNED16 Mat4 MP_matrix;
ALIGNED16 Mat4 P_matrix;
ALIGNED16 Mat4 modelview_matrix_stack[MAX_MATRIX_STACK_SIZE];
uint32_t modelview_matrix_stack_size;
uint32_t geometry_mode;
int16_t fog_mul, fog_offset;
int16_t fresnel_scale, fresnel_offset;
struct {
// U0.16
uint16_t s, t;
} texture_scaling_factor;
bool lights_changed;
uint8_t current_num_lights; // includes ambient light
Vec3f current_lights_coeffs[MAX_LIGHTS];
Vec3f current_lookat_coeffs[2]; // lookat_x, lookat_y
Light_t current_lights[MAX_LIGHTS + 1];
struct GfxVertex loaded_vertices[MAX_VERTICES + 4];
} rsp;
struct RSP rsp = { 0 };
static struct RDP {
const uint8_t *palette;
@ -108,7 +86,7 @@ struct GfxDimensions gfx_current_dimensions = { 0 };
static bool dropped_frame = false;
static float buf_vbo[MAX_BUFFERED * (26 * 3)] = { 0.0f }; // 3 vertices in a triangle and 26 floats per vtx
static float buf_vbo[MAX_BUFFERED * ((18 + (CC_MAX_INPUTS * 4)) * 3)] = { 0.0f }; // 3 vertices in a triangle and 18 floats per verticies plus the 4 floats per input for verticies
static size_t buf_vbo_len = 0;
static size_t buf_vbo_num_tris = 0;
@ -126,8 +104,8 @@ Color gFogColor = { 0xFF, 0xFF, 0xFF };
f32 gFogIntensity = 1;
// need inverse camera matrix to compute world space for lighting engine
static Mat4 sInverseCameraMatrix;
static bool sHasInverseCameraMatrix = false;
Mat4 sInverseCameraMatrix;
bool sHasInverseCameraMatrix = false;
// 4x4 pink-black checkerboard texture to indicate missing textures
#define MISSING_W 4
@ -1156,6 +1134,7 @@ static void OPTIMIZE_O3 gfx_sp_tri1(uint8_t vtx1_idx, uint8_t vtx2_idx, uint8_t
bool z_is_from_0_to_1 = gfx_rapi->z_is_from_0_to_1();
for (int32_t i = 0; i < 3; i++) {
// send triangle data
float z = v_arr[i]->z, w = v_arr[i]->w;
if (z_is_from_0_to_1) {
z = (z + w) / 2.0f;
@ -1165,95 +1144,112 @@ static void OPTIMIZE_O3 gfx_sp_tri1(uint8_t vtx1_idx, uint8_t vtx2_idx, uint8_t
buf_vbo[buf_vbo_len++] = z;
buf_vbo[buf_vbo_len++] = w;
if (use_texture) {
float u = (v_arr[i]->u - rdp.texture_tile.uls * 8) / 32.0f;
float v = (v_arr[i]->v - rdp.texture_tile.ult * 8) / 32.0f;
if ((rdp.other_mode_h & (3U << G_MDSFT_TEXTFILT)) != G_TF_POINT) {
// Linear filter adds 0.5f to the coordinates (why?)
u += 0.5f;
v += 0.5f;
}
buf_vbo[buf_vbo_len++] = u / tex_width;
buf_vbo[buf_vbo_len++] = v / tex_height;
// send texture info
float u = (v_arr[i]->u - rdp.texture_tile.uls * 8) / 32.0f;
float v = (v_arr[i]->v - rdp.texture_tile.ult * 8) / 32.0f;
if ((rdp.other_mode_h & (3U << G_MDSFT_TEXTFILT)) != G_TF_POINT) {
// Linear filter adds 0.5f to the coordinates (why?)
u += 0.5f;
v += 0.5f;
}
buf_vbo[buf_vbo_len++] = u / tex_width;
buf_vbo[buf_vbo_len++] = v / tex_height;
if (cm->use_fog) {
f32 r = gFogColor[0] / 255.0f;
f32 g = gFogColor[1] / 255.0f;
f32 b = gFogColor[2] / 255.0f;
buf_vbo[buf_vbo_len++] = (rdp.fog_color.r / 255.0f) * r;
buf_vbo[buf_vbo_len++] = (rdp.fog_color.g / 255.0f) * g;
buf_vbo[buf_vbo_len++] = (rdp.fog_color.b / 255.0f) * b;
buf_vbo[buf_vbo_len++] = v_arr[i]->fog_z / 255.0f; // fog factor (not alpha)
}
// send fog data
f32 r = gFogColor[0] / 255.0f;
f32 g = gFogColor[1] / 255.0f;
f32 b = gFogColor[2] / 255.0f;
buf_vbo[buf_vbo_len++] = (rdp.fog_color.r / 255.0f) * r;
buf_vbo[buf_vbo_len++] = (rdp.fog_color.g / 255.0f) * g;
buf_vbo[buf_vbo_len++] = (rdp.fog_color.b / 255.0f) * b;
buf_vbo[buf_vbo_len++] = v_arr[i]->fog_z / 255.0f; // fog factor (not alpha)
if (cm->light_map) {
struct RGBA* col = &v_arr[i]->color;
buf_vbo[buf_vbo_len++] = ( (((uint16_t)col->g) << 8) | ((uint16_t)col->r) ) / 65535.0f;
buf_vbo[buf_vbo_len++] = 1.0f - (( (((uint16_t)col->a) << 8) | ((uint16_t)col->b) ) / 65535.0f);
}
// send lightmap info
struct RGBA* col = &v_arr[i]->color;
buf_vbo[buf_vbo_len++] = ( (((uint16_t)col->g) << 8) | ((uint16_t)col->r) ) / 65535.0f;
buf_vbo[buf_vbo_len++] = 1.0f - (( (((uint16_t)col->a) << 8) | ((uint16_t)col->b) ) / 65535.0f);
for (int j = 0; j < num_inputs; j++) {
for (int j = 0; j < CC_MAX_INPUTS; j++) {
struct RGBA *color = NULL;
struct RGBA tmp = { 0 };
for (int a = 0; a < (cm->use_alpha ? 2 : 1 ); a++) {
u8 mapping = comb->shader_input_mapping[j];
switch (mapping) {
case CC_PRIM:
color = &rdp.prim_color;
break;
case CC_SHADE:
color = &v_arr[i]->color;
break;
case CC_ENV:
color = &rdp.env_color;
break;
case CC_PRIMA:
memset(&tmp, rdp.prim_color.a, sizeof(tmp));
color = &tmp;
break;
case CC_SHADEA:
memset(&tmp, v_arr[i]->color.a, sizeof(tmp));
color = &tmp;
break;
case CC_ENVA:
memset(&tmp, rdp.env_color.a, sizeof(tmp));
color = &tmp;
break;
case CC_LOD:
{
float distance_frac = (v1->w - 3000.0f) / 3000.0f;
if (distance_frac < 0.0f) distance_frac = 0.0f;
if (distance_frac > 1.0f) distance_frac = 1.0f;
tmp.r = tmp.g = tmp.b = tmp.a = distance_frac * 255.0f;
color = &tmp;
break;
}
default:
memset(&tmp, 0, sizeof(tmp));
color = &tmp;
break;
u8 mapping = (j < num_inputs) ? comb->shader_input_mapping[j] : 255;
switch (mapping) {
case CC_PRIM: color = &rdp.prim_color; break;
case CC_SHADE: color = &v_arr[i]->color; break;
case CC_ENV: color = &rdp.env_color; break;
case CC_PRIMA:
memset(&tmp, rdp.prim_color.a, sizeof(tmp));
color = &tmp;
break;
case CC_SHADEA:
memset(&tmp, v_arr[i]->color.a, sizeof(tmp));
color = &tmp;
break;
case CC_ENVA:
memset(&tmp, rdp.env_color.a, sizeof(tmp));
color = &tmp;
break;
case CC_LOD: {
float distance_frac = (v_arr[i]->w - 3000.0f) / 3000.0f;
if (distance_frac < 0.0f) distance_frac = 0.0f;
if (distance_frac > 1.0f) distance_frac = 1.0f;
tmp.r = tmp.g = tmp.b = tmp.a = distance_frac * 255.0f;
color = &tmp;
break;
}
if (a == 0) {
buf_vbo[buf_vbo_len++] = color->r / 255.0f;
buf_vbo[buf_vbo_len++] = color->g / 255.0f;
buf_vbo[buf_vbo_len++] = color->b / 255.0f;
default:
memset(&tmp, 0, sizeof(tmp));
color = &tmp;
break;
}
// send over input colors
buf_vbo[buf_vbo_len++] = color->r / 255.0f;
buf_vbo[buf_vbo_len++] = color->g / 255.0f;
buf_vbo[buf_vbo_len++] = color->b / 255.0f;
if (cm->use_alpha) {
if (cm->use_fog && (color == &v_arr[i]->color || cm->light_map)) {
buf_vbo[buf_vbo_len++] = 1.0f;
} else {
if (cm->use_fog && (color == &v_arr[i]->color || cm->light_map)) {
// Shade alpha is 100% for fog
buf_vbo[buf_vbo_len++] = 1.0f;
} else {
buf_vbo[buf_vbo_len++] = color->a / 255.0f;
}
buf_vbo[buf_vbo_len++] = color->a / 255.0f;
}
} else {
buf_vbo[buf_vbo_len++] = 1.0f;
}
}
/*struct RGBA *color = &v_arr[i]->color;
buf_vbo[buf_vbo_len++] = color->r / 255.0f;
buf_vbo[buf_vbo_len++] = color->g / 255.0f;
buf_vbo[buf_vbo_len++] = color->b / 255.0f;
buf_vbo[buf_vbo_len++] = color->a / 255.0f;*/
// calculate normal
f32 ux = v2->x - v1->x;
f32 uy = v2->y - v1->y;
f32 uz = v2->z - v1->z;
f32 vx = v3->x - v1->x;
f32 vy = v3->y - v1->y;
f32 vz = v3->z - v1->z;
f32 nx = uy * vz - uz * vy;
f32 ny = uz * vx - ux * vz;
f32 nz = ux * vy - uy * vx;
float len = sqrtf(nx*nx + ny*ny + nz*nz);
if (len > 0.0f) {
nx /= len;
ny /= len;
nz /= len;
}
// send normal
buf_vbo[buf_vbo_len++] = nx;
buf_vbo[buf_vbo_len++] = ny;
buf_vbo[buf_vbo_len++] = nz;
// send barycentric coords
buf_vbo[buf_vbo_len++] = i == 0 ? 1.0f : 0.0f;
buf_vbo[buf_vbo_len++] = i == 1 ? 1.0f : 0.0f;
buf_vbo[buf_vbo_len++] = i == 2 ? 1.0f : 0.0f;
}
if (++buf_vbo_num_tris == MAX_BUFFERED) {
gfx_flush();
@ -2064,6 +2060,15 @@ void gfx_shutdown(void) {
gGfxInited = false;
}
void gfx_remove_all_color_combiners() {
for (int i = 0; i < CC_MAX_SHADERS; i++) {
memset(&color_combiner_pool[i], 0, sizeof(color_combiner_pool[i]));
}
color_combiner_pool_index = 0;
color_combiner_pool_size = 0;
}
/////////////////////////
// v custom for djui v //
/////////////////////////

View file

@ -7,12 +7,41 @@
struct GfxRenderingAPI;
struct GfxWindowManagerAPI;
struct RSP {
ALIGNED16 Mat4 MP_matrix;
ALIGNED16 Mat4 P_matrix;
ALIGNED16 Mat4 modelview_matrix_stack[MAX_MATRIX_STACK_SIZE];
uint32_t modelview_matrix_stack_size;
uint32_t geometry_mode;
int16_t fog_mul, fog_offset;
int16_t fresnel_scale, fresnel_offset;
struct {
// U0.16
uint16_t s, t;
} texture_scaling_factor;
bool lights_changed;
uint8_t current_num_lights; // includes ambient light
Vec3f current_lights_coeffs[MAX_LIGHTS];
Vec3f current_lookat_coeffs[2]; // lookat_x, lookat_y
Light_t current_lights[MAX_LIGHTS + 1];
struct GfxVertex loaded_vertices[MAX_VERTICES + 4];
};
extern struct RSP rsp;
extern Vec3f gLightingDir;
extern Color gLightingColor[2];
extern Color gVertexColor;
extern Color gFogColor;
extern f32 gFogIntensity;
extern Mat4 sInverseCameraMatrix;
extern bool sHasInverseCameraMatrix;
#ifdef __cplusplus
extern "C" {
#endif
@ -25,6 +54,7 @@ void gfx_end_frame_render(void);
void gfx_display_frame(void);
void gfx_end_frame(void);
void gfx_shutdown(void);
void gfx_remove_all_color_combiners(void);
void gfx_pc_precomp_shader(uint32_t rgb1, uint32_t alpha1, uint32_t rgb2, uint32_t alpha2, uint32_t flags);
#ifdef __cplusplus

View file

@ -12,8 +12,10 @@ struct GfxRenderingAPI {
bool (*z_is_from_0_to_1)(void);
void (*unload_shader)(struct ShaderProgram *old_prg);
void (*load_shader)(struct ShaderProgram *new_prg);
void (*remove_shaders)(void);
struct ShaderProgram *(*create_and_load_new_shader)(struct ColorCombiner* cc);
struct ShaderProgram *(*lookup_shader)(struct ColorCombiner* cc);
struct ShaderProgram *(*lookup_shader_using_index)(uint8_t shaderIndex);
void (*shader_get_info)(struct ShaderProgram *prg, uint8_t *num_inputs, bool used_textures[2]);
uint32_t (*new_texture)(void);
void (*select_texture)(int tile, uint32_t texture_id);

View file

@ -134,6 +134,10 @@ static void gfx_sdl_init(const char *window_title) {
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); // These attributes allow for hardware acceleration on RPis.
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
#else
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
#endif
int xpos = (configWindow.x == WAPI_WIN_CENTERPOS) ? SDL_WINDOWPOS_CENTERED : configWindow.x;

View file

@ -83,6 +83,8 @@ static const char *sLuaLvtNames[] = {
[LVT_S16_P] = "s16 pointer",
[LVT_S32] = "s32",
[LVT_S32_P] = "s32 pointer",
[LVT_S64] = "s64",
[LVT_S64_P] = "s64 pointer",
[LVT_F32] = "f32",
[LVT_F32_P] = "f32 pointer",
[LVT_U64] = "u64",
@ -377,6 +379,7 @@ static bool smlua_push_field(lua_State* L, u8* p, struct LuaObjectField *data) {
case LVT_S8: lua_pushinteger(L, *(s8* )p); break;
case LVT_S16: lua_pushinteger(L, *(s16*)p); break;
case LVT_S32: lua_pushinteger(L, *(s32*)p); break;
case LVT_S64: lua_pushinteger(L, *(s64*)p); break;
case LVT_F32: lua_pushnumber( L, *(f32*)p); break;
case LVT_U64: lua_pushinteger(L, *(u64*)p); break;
case LVT_COBJECT: smlua_push_object(L, data->lot, p, NULL); break;
@ -392,6 +395,7 @@ static bool smlua_push_field(lua_State* L, u8* p, struct LuaObjectField *data) {
case LVT_S8_P:
case LVT_S16_P:
case LVT_S32_P:
case LVT_S64_P:
case LVT_F32_P:
case LVT_U64_P:
case LVT_BEHAVIORSCRIPT_P:
@ -419,6 +423,7 @@ static bool smlua_set_field(lua_State* L, u8* p, struct LuaObjectField *data) {
case LVT_S8: *(s8*) p = smlua_to_integer(L, 3); break;
case LVT_S16: *(s16*)p = smlua_to_integer(L, 3); break;
case LVT_S32: *(s32*)p = smlua_to_integer(L, 3); break;
case LVT_S64: *(s64*)p = smlua_to_integer(L, 3); break;
case LVT_F32: *(f32*)p = smlua_to_number(L, 3); break;
case LVT_U64: *(s64*)p = smlua_to_integer(L, 3); break;
@ -441,6 +446,7 @@ static bool smlua_set_field(lua_State* L, u8* p, struct LuaObjectField *data) {
case LVT_S8_P:
case LVT_S16_P:
case LVT_S32_P:
case LVT_S64_P:
case LVT_F32_P:
case LVT_U64_P:
case LVT_BEHAVIORSCRIPT_P:

View file

@ -18,6 +18,8 @@ enum LuaValueType {
LVT_S16_P,
LVT_S32,
LVT_S32_P,
LVT_S64,
LVT_S64_P,
LVT_F32,
LVT_F32_P,
LVT_U64,

View file

@ -25,6 +25,8 @@
#include "src/pc/lua/utils/smlua_audio_utils.h"
#include "src/game/paintings.h"
#include "src/pc/djui/djui_types.h"
#include "src/pc/gfx/gfx_cc.h"
#include "src/pc/gfx/gfx_opengl.h"
#include "src/game/first_person_cam.h"
#include "src/game/player_palette.h"
#include "src/engine/graph_node.h"
@ -377,6 +379,17 @@ static struct LuaObjectField sBehaviorValuesFields[LUA_BEHAVIOR_VALUES_FIELD_COU
{ "trajectories", LVT_COBJECT, offsetof(struct BehaviorValues, trajectories), true, LOT_BEHAVIORTRAJECTORIES, 1, sizeof(struct BehaviorTrajectories) },
};
#define LUA_CCFEATURES_FIELD_COUNT 7
static struct LuaObjectField sCCFeaturesFields[LUA_CCFEATURES_FIELD_COUNT] = {
{ "color_alpha_same", LVT_BOOL, offsetof(struct CCFeatures, color_alpha_same), false, LOT_NONE, 2, sizeof(bool) },
{ "do_mix", LVT_BOOL, offsetof(struct CCFeatures, do_mix), false, LOT_NONE, 4, sizeof(bool) },
{ "do_multiply", LVT_BOOL, offsetof(struct CCFeatures, do_multiply), false, LOT_NONE, 4, sizeof(bool) },
{ "do_noise", LVT_BOOL, offsetof(struct CCFeatures, do_noise), false, LOT_NONE, 1, sizeof(bool) },
{ "do_single", LVT_BOOL, offsetof(struct CCFeatures, do_single), false, LOT_NONE, 4, sizeof(bool) },
{ "num_inputs", LVT_S32, offsetof(struct CCFeatures, num_inputs), false, LOT_NONE, 1, sizeof(int) },
{ "used_textures", LVT_BOOL, offsetof(struct CCFeatures, used_textures), false, LOT_NONE, 2, sizeof(bool) },
};
#define LUA_CAMERA_FIELD_COUNT 15
static struct LuaObjectField sCameraFields[LUA_CAMERA_FIELD_COUNT] = {
{ "areaCenX", LVT_F32, offsetof(struct Camera, areaCenX), false, LOT_NONE, 1, sizeof(f32) },
@ -684,6 +697,34 @@ static struct LuaObjectField sCharacterFields[LUA_CHARACTER_FIELD_COUNT] = {
{ "type", LVT_S32, offsetof(struct Character, type), true, LOT_NONE, 1, sizeof(enum CharacterType) },
};
#define LUA_COLOR_COMBINER_FIELD_COUNT 7
static struct LuaObjectField sColorCombinerFields[LUA_COLOR_COMBINER_FIELD_COUNT] = {
{ "cm", LVT_COBJECT, offsetof(struct ColorCombiner, cm), true, LOT_COMBINEMODE, 1, sizeof(struct CombineMode) },
{ "hash", LVT_U64, offsetof(struct ColorCombiner, hash), false, LOT_NONE, 1, sizeof(u64) },
{ "prg", LVT_COBJECT_P, offsetof(struct ColorCombiner, prg), false, LOT_SHADERPROGRAM, 1, sizeof(struct ShaderProgram*) },
{ "shader_commands", LVT_U8, offsetof(struct ColorCombiner, shader_commands), false, LOT_NONE, 16, sizeof(u8) },
{ "shader_commands_as_u64", LVT_U64, offsetof(struct ColorCombiner, shader_commands_as_u64), false, LOT_NONE, 8, sizeof(u64) },
{ "shader_input_mapping", LVT_U8, offsetof(struct ColorCombiner, shader_input_mapping), false, LOT_NONE, 16, sizeof(u8) },
{ "shader_input_mapping_as_u64", LVT_U64, offsetof(struct ColorCombiner, shader_input_mapping_as_u64), false, LOT_NONE, 8, sizeof(u64) },
};
#define LUA_COMBINE_MODE_FIELD_COUNT 7
static struct LuaObjectField sCombineModeFields[LUA_COMBINE_MODE_FIELD_COUNT] = {
// { "1", LVT_???, offsetof(struct CombineMode, 1), false, LOT_???, 1, sizeof(u8 use_alpha :) }, <--- UNIMPLEMENTED
// { "1", LVT_???, offsetof(struct CombineMode, 1), false, LOT_???, 1, sizeof(u8 use_fog :) }, <--- UNIMPLEMENTED
// { "1", LVT_???, offsetof(struct CombineMode, 1), false, LOT_???, 1, sizeof(u8 texture_edge :) }, <--- UNIMPLEMENTED
// { "1", LVT_???, offsetof(struct CombineMode, 1), false, LOT_???, 1, sizeof(u8 use_dither :) }, <--- UNIMPLEMENTED
// { "1", LVT_???, offsetof(struct CombineMode, 1), false, LOT_???, 1, sizeof(u8 use_2cycle :) }, <--- UNIMPLEMENTED
// { "1", LVT_???, offsetof(struct CombineMode, 1), false, LOT_???, 1, sizeof(u8 light_map :) }, <--- UNIMPLEMENTED
{ "all_values", LVT_U8, offsetof(struct CombineMode, all_values), false, LOT_NONE, 16, sizeof(u8) },
{ "alpha1", LVT_U32, offsetof(struct CombineMode, alpha1), false, LOT_NONE, 1, sizeof(u32) },
{ "alpha2", LVT_U32, offsetof(struct CombineMode, alpha2), false, LOT_NONE, 1, sizeof(u32) },
{ "flags", LVT_U32, offsetof(struct CombineMode, flags), false, LOT_NONE, 1, sizeof(u32) },
{ "hash", LVT_S64, offsetof(struct CombineMode, hash), false, LOT_NONE, 1, sizeof(s64) },
{ "rgb1", LVT_U32, offsetof(struct CombineMode, rgb1), false, LOT_NONE, 1, sizeof(u32) },
{ "rgb2", LVT_U32, offsetof(struct CombineMode, rgb2), false, LOT_NONE, 1, sizeof(u32) },
};
#define LUA_CONTROLLER_FIELD_COUNT 11
static struct LuaObjectField sControllerFields[LUA_CONTROLLER_FIELD_COUNT] = {
{ "buttonDown", LVT_U16, offsetof(struct Controller, buttonDown), false, LOT_NONE, 1, sizeof(u16) },
@ -2501,6 +2542,21 @@ static struct LuaObjectField sServerSettingsFields[LUA_SERVER_SETTINGS_FIELD_COU
{ "stayInLevelAfterStar", LVT_U8, offsetof(struct ServerSettings, stayInLevelAfterStar), false, LOT_NONE, 1, sizeof(u8) },
};
#define LUA_SHADER_PROGRAM_FIELD_COUNT 11
static struct LuaObjectField sShaderProgramFields[LUA_SHADER_PROGRAM_FIELD_COUNT] = {
{ "attrib_locations", LVT_U32, offsetof(struct ShaderProgram, attrib_locations), false, LOT_NONE, MAX_SHADER_ATTRIBUTES, sizeof(u32) },
{ "attrib_sizes", LVT_U8, offsetof(struct ShaderProgram, attrib_sizes), false, LOT_NONE, MAX_SHADER_ATTRIBUTES, sizeof(u8) },
{ "hash", LVT_U64, offsetof(struct ShaderProgram, hash), false, LOT_NONE, 1, sizeof(u64) },
{ "num_attribs", LVT_U8, offsetof(struct ShaderProgram, num_attribs), false, LOT_NONE, 1, sizeof(u8) },
{ "num_floats", LVT_U8, offsetof(struct ShaderProgram, num_floats), false, LOT_NONE, 1, sizeof(u8) },
{ "num_inputs", LVT_U8, offsetof(struct ShaderProgram, num_inputs), false, LOT_NONE, 1, sizeof(u8) },
{ "opengl_program_id", LVT_U32, offsetof(struct ShaderProgram, opengl_program_id), false, LOT_NONE, 1, sizeof(u32) },
{ "uniform_locations", LVT_U32, offsetof(struct ShaderProgram, uniform_locations), false, LOT_NONE, MAX_SHADER_UNIFORMS, sizeof(u32) },
{ "used_lightmap", LVT_BOOL, offsetof(struct ShaderProgram, used_lightmap), false, LOT_NONE, 1, sizeof(bool) },
{ "used_noise", LVT_BOOL, offsetof(struct ShaderProgram, used_noise), false, LOT_NONE, 1, sizeof(bool) },
{ "used_textures", LVT_BOOL, offsetof(struct ShaderProgram, used_textures), false, LOT_NONE, MAX_SHADER_TEXTURES, sizeof(bool) },
};
#define LUA_SPAWN_INFO_FIELD_COUNT 8
static struct LuaObjectField sSpawnInfoFields[LUA_SPAWN_INFO_FIELD_COUNT] = {
{ "activeAreaIndex", LVT_S8, offsetof(struct SpawnInfo, activeAreaIndex), false, LOT_NONE, 1, sizeof(s8) },
@ -2679,9 +2735,12 @@ struct LuaObjectTable sLuaObjectAutogenTable[LOT_AUTOGEN_MAX - LOT_AUTOGEN_MIN]
{ LOT_BEHAVIORDIALOGS, sBehaviorDialogsFields, LUA_BEHAVIOR_DIALOGS_FIELD_COUNT },
{ LOT_BEHAVIORTRAJECTORIES, sBehaviorTrajectoriesFields, LUA_BEHAVIOR_TRAJECTORIES_FIELD_COUNT },
{ LOT_BEHAVIORVALUES, sBehaviorValuesFields, LUA_BEHAVIOR_VALUES_FIELD_COUNT },
{ LOT_CCFEATURES, sCCFeaturesFields, LUA_CCFEATURES_FIELD_COUNT },
{ LOT_CAMERA, sCameraFields, LUA_CAMERA_FIELD_COUNT },
{ LOT_CHAINSEGMENT, sChainSegmentFields, LUA_CHAIN_SEGMENT_FIELD_COUNT },
{ LOT_CHARACTER, sCharacterFields, LUA_CHARACTER_FIELD_COUNT },
{ LOT_COLORCOMBINER, sColorCombinerFields, LUA_COLOR_COMBINER_FIELD_COUNT },
{ LOT_COMBINEMODE, sCombineModeFields, LUA_COMBINE_MODE_FIELD_COUNT },
{ LOT_CONTROLLER, sControllerFields, LUA_CONTROLLER_FIELD_COUNT },
{ LOT_CUSTOMLEVELINFO, sCustomLevelInfoFields, LUA_CUSTOM_LEVEL_INFO_FIELD_COUNT },
{ LOT_DATETIME, sDateTimeFields, LUA_DATE_TIME_FIELD_COUNT },
@ -2747,6 +2806,7 @@ struct LuaObjectTable sLuaObjectAutogenTable[LOT_AUTOGEN_MAX - LOT_AUTOGEN_MIN]
{ LOT_RAYINTERSECTIONINFO, sRayIntersectionInfoFields, LUA_RAY_INTERSECTION_INFO_FIELD_COUNT },
{ LOT_ROMHACKCAMERASETTINGS, sRomhackCameraSettingsFields, LUA_ROMHACK_CAMERA_SETTINGS_FIELD_COUNT },
{ LOT_SERVERSETTINGS, sServerSettingsFields, LUA_SERVER_SETTINGS_FIELD_COUNT },
{ LOT_SHADERPROGRAM, sShaderProgramFields, LUA_SHADER_PROGRAM_FIELD_COUNT },
{ LOT_SPAWNINFO, sSpawnInfoFields, LUA_SPAWN_INFO_FIELD_COUNT },
{ LOT_SPAWNPARTICLESINFO, sSpawnParticlesInfoFields, LUA_SPAWN_PARTICLES_INFO_FIELD_COUNT },
{ LOT_STARPOSITIONS, sStarPositionsFields, LUA_STAR_POSITIONS_FIELD_COUNT },
@ -2784,9 +2844,12 @@ const char *sLuaLotNames[] = {
[LOT_BEHAVIORDIALOGS] = "BehaviorDialogs",
[LOT_BEHAVIORTRAJECTORIES] = "BehaviorTrajectories",
[LOT_BEHAVIORVALUES] = "BehaviorValues",
[LOT_CCFEATURES] = "CCFeatures",
[LOT_CAMERA] = "Camera",
[LOT_CHAINSEGMENT] = "ChainSegment",
[LOT_CHARACTER] = "Character",
[LOT_COLORCOMBINER] = "ColorCombiner",
[LOT_COMBINEMODE] = "CombineMode",
[LOT_CONTROLLER] = "Controller",
[LOT_CUSTOMLEVELINFO] = "CustomLevelInfo",
[LOT_DATETIME] = "DateTime",
@ -2852,6 +2915,7 @@ const char *sLuaLotNames[] = {
[LOT_RAYINTERSECTIONINFO] = "RayIntersectionInfo",
[LOT_ROMHACKCAMERASETTINGS] = "RomhackCameraSettings",
[LOT_SERVERSETTINGS] = "ServerSettings",
[LOT_SHADERPROGRAM] = "ShaderProgram",
[LOT_SPAWNINFO] = "SpawnInfo",
[LOT_SPAWNPARTICLESINFO] = "SpawnParticlesInfo",
[LOT_STARPOSITIONS] = "StarPositions",

View file

@ -29,9 +29,12 @@ enum LuaObjectAutogenType {
LOT_BEHAVIORDIALOGS,
LOT_BEHAVIORTRAJECTORIES,
LOT_BEHAVIORVALUES,
LOT_CCFEATURES,
LOT_CAMERA,
LOT_CHAINSEGMENT,
LOT_CHARACTER,
LOT_COLORCOMBINER,
LOT_COMBINEMODE,
LOT_CONTROLLER,
LOT_CUSTOMLEVELINFO,
LOT_DATETIME,
@ -97,6 +100,7 @@ enum LuaObjectAutogenType {
LOT_RAYINTERSECTIONINFO,
LOT_ROMHACKCAMERASETTINGS,
LOT_SERVERSETTINGS,
LOT_SHADERPROGRAM,
LOT_SPAWNINFO,
LOT_SPAWNPARTICLESINFO,
LOT_STARPOSITIONS,

View file

@ -1595,6 +1595,53 @@ char gSmluaConstants[] = ""
"BACKGROUND_ABOVE_CLOUDS=8\n"
"BACKGROUND_PURPLE_SKY=9\n"
"BACKGROUND_CUSTOM=10\n"
"CC_0=0\n"
"CC_TEXEL0=1\n"
"CC_TEXEL1=2\n"
"CC_PRIM=3\n"
"CC_SHADE=4\n"
"CC_ENV=5\n"
"CC_TEXEL0A=6\n"
"CC_LOD=7\n"
"CC_1=8\n"
"CC_TEXEL1A=9\n"
"CC_COMBINED=10\n"
"CC_COMBINEDA=11\n"
"CC_PRIMA=12\n"
"CC_SHADEA=13\n"
"CC_ENVA=14\n"
"CC_NOISE=15\n"
"CC_ENUM_MAX=16\n"
"SHADER_0=0\n"
"SHADER_INPUT_1=1\n"
"SHADER_INPUT_2=2\n"
"SHADER_INPUT_3=3\n"
"SHADER_INPUT_4=4\n"
"SHADER_INPUT_5=5\n"
"SHADER_INPUT_6=6\n"
"SHADER_INPUT_7=7\n"
"SHADER_INPUT_8=8\n"
"SHADER_TEXEL0=9\n"
"SHADER_TEXEL0A=10\n"
"SHADER_TEXEL1=11\n"
"SHADER_TEXEL1A=12\n"
"SHADER_1=13\n"
"SHADER_COMBINED=14\n"
"SHADER_COMBINEDA=15\n"
"SHADER_NOISE=16\n"
"SHADER_OPT_ALPHA=(1 << 24)\n"
"SHADER_OPT_FOG=(1 << 25)\n"
"SHADER_OPT_TEXTURE_EDGE=(1 << 26)\n"
"SHADER_OPT_NOISE=(1 << 27)\n"
"USE_ALPHA=1 << 0\n"
"USE_FOG=1 << 1\n"
"TEXTURE_EDGE=1 << 2\n"
"USE_DITHER=1 << 3\n"
"USE_2CYCLE=1 << 4\n"
"LIGHT_MAP=1 << 5\n"
"SHADER_CMD_LENGTH=16\n"
"CC_MAX_SHADERS=64\n"
"CC_MAX_INPUTS=8\n"
"GRAPH_RENDER_ACTIVE=(1 << 0)\n"
"GRAPH_RENDER_CHILDREN_FIRST=(1 << 1)\n"
"GRAPH_RENDER_BILLBOARD=(1 << 2)\n"
@ -3553,7 +3600,10 @@ char gSmluaConstants[] = ""
"HOOK_ON_FIND_WATER_LEVEL=63\n"
"HOOK_ON_FIND_POISON_GAS_LEVEL=64\n"
"HOOK_ON_FIND_SURFACE_ON_RAY=65\n"
"HOOK_MAX=66\n"
"HOOK_ON_REFRESH_SHADERS=66\n"
"HOOK_ON_VERTEX_SHADER_CREATE=67\n"
"HOOK_ON_FRAGMENT_SHADER_CREATE=68\n"
"HOOK_MAX=69\n"
"MAX_HOOKED_BEHAVIORS=1024\n"
"HUD_DISPLAY_LIVES=0\n"
"HUD_DISPLAY_COINS=1\n"

View file

@ -32547,6 +32547,219 @@ int smlua_func_gfx_delete_all(UNUSED lua_State* L) {
return 1;
}
int smlua_func_gfx_reload_shaders(UNUSED lua_State* L) {
if (L == NULL) { return 0; }
int top = lua_gettop(L);
if (top != 0) {
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "gfx_reload_shaders", 0, top);
return 0;
}
gfx_reload_shaders();
return 1;
}
int smlua_func_gfx_color_combiner_get_features(lua_State* L) {
if (L == NULL) { return 0; }
int top = lua_gettop(L);
if (top != 1) {
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "gfx_color_combiner_get_features", 1, top);
return 0;
}
struct ColorCombiner* cc = (struct ColorCombiner*)smlua_to_cobject(L, 1, LOT_COLORCOMBINER);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "gfx_color_combiner_get_features"); return 0; }
smlua_push_object(L, LOT_CCFEATURES, gfx_color_combiner_get_features(cc), NULL);
return 1;
}
int smlua_func_gfx_get_program_id_from_shader_index(lua_State* L) {
if (L == NULL) { return 0; }
int top = lua_gettop(L);
if (top != 1) {
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "gfx_get_program_id_from_shader_index", 1, top);
return 0;
}
u8 shaderIndex = smlua_to_integer(L, 1);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "gfx_get_program_id_from_shader_index"); return 0; }
lua_pushinteger(L, gfx_get_program_id_from_shader_index(shaderIndex));
return 1;
}
int smlua_func_gfx_use_program(lua_State* L) {
if (L == NULL) { return 0; }
int top = lua_gettop(L);
if (top != 1) {
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "gfx_use_program", 1, top);
return 0;
}
u32 program = smlua_to_integer(L, 1);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "gfx_use_program"); return 0; }
gfx_use_program(program);
return 1;
}
int smlua_func_gfx_shader_get_uniform_location(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", "gfx_shader_get_uniform_location", 2, top);
return 0;
}
u32 program = smlua_to_integer(L, 1);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "gfx_shader_get_uniform_location"); return 0; }
const char* name = smlua_to_string(L, 2);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "gfx_shader_get_uniform_location"); return 0; }
lua_pushinteger(L, gfx_shader_get_uniform_location(program, name));
return 1;
}
int smlua_func_gfx_shader_set_int(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", "gfx_shader_set_int", 2, top);
return 0;
}
int loc = smlua_to_integer(L, 1);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "gfx_shader_set_int"); return 0; }
int value = smlua_to_integer(L, 2);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "gfx_shader_set_int"); return 0; }
gfx_shader_set_int(loc, value);
return 1;
}
int smlua_func_gfx_shader_set_float(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", "gfx_shader_set_float", 2, top);
return 0;
}
int loc = smlua_to_integer(L, 1);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "gfx_shader_set_float"); return 0; }
float value = smlua_to_number(L, 2);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "gfx_shader_set_float"); return 0; }
gfx_shader_set_float(loc, value);
return 1;
}
int smlua_func_gfx_shader_set_vec2(lua_State* L) {
if (L == NULL) { return 0; }
int top = lua_gettop(L);
if (top != 3) {
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "gfx_shader_set_vec2", 3, top);
return 0;
}
int loc = smlua_to_integer(L, 1);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "gfx_shader_set_vec2"); return 0; }
float x = smlua_to_number(L, 2);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "gfx_shader_set_vec2"); return 0; }
float y = smlua_to_number(L, 3);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "gfx_shader_set_vec2"); return 0; }
gfx_shader_set_vec2(loc, x, y);
return 1;
}
int smlua_func_gfx_shader_set_vec3(lua_State* L) {
if (L == NULL) { return 0; }
int top = lua_gettop(L);
if (top != 4) {
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "gfx_shader_set_vec3", 4, top);
return 0;
}
int loc = smlua_to_integer(L, 1);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "gfx_shader_set_vec3"); return 0; }
float x = smlua_to_number(L, 2);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "gfx_shader_set_vec3"); return 0; }
float y = smlua_to_number(L, 3);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "gfx_shader_set_vec3"); return 0; }
float z = smlua_to_number(L, 4);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 4, "gfx_shader_set_vec3"); return 0; }
gfx_shader_set_vec3(loc, x, y, z);
return 1;
}
int smlua_func_gfx_shader_set_vec4(lua_State* L) {
if (L == NULL) { return 0; }
int top = lua_gettop(L);
if (top != 5) {
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "gfx_shader_set_vec4", 5, top);
return 0;
}
int loc = smlua_to_integer(L, 1);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "gfx_shader_set_vec4"); return 0; }
float w = smlua_to_number(L, 2);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "gfx_shader_set_vec4"); return 0; }
float x = smlua_to_number(L, 3);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "gfx_shader_set_vec4"); return 0; }
float y = smlua_to_number(L, 4);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 4, "gfx_shader_set_vec4"); return 0; }
float z = smlua_to_number(L, 5);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 5, "gfx_shader_set_vec4"); return 0; }
gfx_shader_set_vec4(loc, w, x, y, z);
return 1;
}
int smlua_func_gfx_shader_set_mat4(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", "gfx_shader_set_mat4", 2, top);
return 0;
}
int loc = smlua_to_integer(L, 1);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "gfx_shader_set_mat4"); return 0; }
Mat4 mat;
smlua_get_mat4(mat, 2);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "gfx_shader_set_mat4"); return 0; }
gfx_shader_set_mat4(loc, mat);
return 1;
}
int smlua_func_vtx_get_from_name(lua_State* L) {
if (L == NULL) { return 0; }
@ -38616,6 +38829,17 @@ void smlua_bind_functions_autogen(void) {
smlua_bind_function(L, "gfx_resize", smlua_func_gfx_resize);
smlua_bind_function(L, "gfx_delete", smlua_func_gfx_delete);
smlua_bind_function(L, "gfx_delete_all", smlua_func_gfx_delete_all);
smlua_bind_function(L, "gfx_reload_shaders", smlua_func_gfx_reload_shaders);
smlua_bind_function(L, "gfx_color_combiner_get_features", smlua_func_gfx_color_combiner_get_features);
smlua_bind_function(L, "gfx_get_program_id_from_shader_index", smlua_func_gfx_get_program_id_from_shader_index);
smlua_bind_function(L, "gfx_use_program", smlua_func_gfx_use_program);
smlua_bind_function(L, "gfx_shader_get_uniform_location", smlua_func_gfx_shader_get_uniform_location);
smlua_bind_function(L, "gfx_shader_set_int", smlua_func_gfx_shader_set_int);
smlua_bind_function(L, "gfx_shader_set_float", smlua_func_gfx_shader_set_float);
smlua_bind_function(L, "gfx_shader_set_vec2", smlua_func_gfx_shader_set_vec2);
smlua_bind_function(L, "gfx_shader_set_vec3", smlua_func_gfx_shader_set_vec3);
smlua_bind_function(L, "gfx_shader_set_vec4", smlua_func_gfx_shader_set_vec4);
smlua_bind_function(L, "gfx_shader_set_mat4", smlua_func_gfx_shader_set_mat4);
smlua_bind_function(L, "vtx_get_from_name", smlua_func_vtx_get_from_name);
smlua_bind_function(L, "vtx_get_name", smlua_func_vtx_get_name);
smlua_bind_function(L, "vtx_get_count", smlua_func_vtx_get_count);

View file

@ -64,3 +64,6 @@ SMLUA_EVENT_HOOK(HOOK_ON_FIND_FLOOR, _, f32 posX, f32 posY, f32 posZ, struct Sur
SMLUA_EVENT_HOOK(HOOK_ON_FIND_WATER_LEVEL, _, f32 x, f32 z, f32 *waterLevel) // Manually defined hook
SMLUA_EVENT_HOOK(HOOK_ON_FIND_POISON_GAS_LEVEL, _, f32 x, f32 z, f32 *gasLevel) // Manually defined hook
SMLUA_EVENT_HOOK(HOOK_ON_FIND_SURFACE_ON_RAY, _, Vec3f orig, Vec3f dir, struct Surface **hit_surface, Vec3f hit_pos) // Manually defined hook
SMLUA_EVENT_HOOK(HOOK_ON_REFRESH_SHADERS, HOOK_RETURN_NEVER)
SMLUA_EVENT_HOOK(HOOK_ON_VERTEX_SHADER_CREATE, HOOK_RETURN_ON_OUTPUT_SET, struct ColorCombiner *cc, u8 shaderIndex, OUTPUT const char **vertexShader)
SMLUA_EVENT_HOOK(HOOK_ON_FRAGMENT_SHADER_CREATE, HOOK_RETURN_ON_OUTPUT_SET, struct ColorCombiner *cc, u8 shaderIndex, OUTPUT const char **fragmentShader)

View file

@ -1863,3 +1863,97 @@ bool smlua_call_event_hooks_HOOK_ON_PACKET_BYTESTRING_RECEIVE(s32 modIndex, s32
}
return hookResult;
}
bool smlua_call_event_hooks_HOOK_ON_REFRESH_SHADERS() {
lua_State *L = gLuaState;
if (L == NULL) { return false; }
bool hookResult = false;
struct LuaHookedEvent *hook = &sHookedEvents[HOOK_ON_REFRESH_SHADERS];
for (int i = 0; i < hook->count; i++) {
s32 prevTop = lua_gettop(L);
// push the callback onto the stack
lua_rawgeti(L, LUA_REGISTRYINDEX, hook->reference[i]);
// call the callback
if (0 != smlua_call_hook(L, 0, 0, 0, hook->mod[i], hook->modFile[i])) {
LOG_LUA("Failed to call the callback for hook %s - '%s/%s'", sLuaHookedEventTypeName[HOOK_ON_REFRESH_SHADERS], hook->mod[i]->relativePath, hook->modFile[i]->relativePath);
continue;
}
hookResult = true;
lua_settop(L, prevTop);
}
return hookResult;
}
bool smlua_call_event_hooks_HOOK_ON_VERTEX_SHADER_CREATE(struct ColorCombiner *cc, u8 shaderIndex, const char **vertexShader) {
lua_State *L = gLuaState;
if (L == NULL) { return false; }
struct LuaHookedEvent *hook = &sHookedEvents[HOOK_ON_VERTEX_SHADER_CREATE];
for (int i = 0; i < hook->count; i++) {
s32 prevTop = lua_gettop(L);
// push the callback onto the stack
lua_rawgeti(L, LUA_REGISTRYINDEX, hook->reference[i]);
// push cc
smlua_push_object(L, LOT_COLORCOMBINER, cc, NULL);
// push shaderIndex
lua_pushinteger(L, shaderIndex);
// call the callback
if (0 != smlua_call_hook(L, 2, 1, 0, hook->mod[i], hook->modFile[i])) {
LOG_LUA("Failed to call the callback for hook %s - '%s/%s'", sLuaHookedEventTypeName[HOOK_ON_VERTEX_SHADER_CREATE], hook->mod[i]->relativePath, hook->modFile[i]->relativePath);
continue;
}
// return vertexShader
if (lua_type(L, -1) == LUA_TSTRING) {
*vertexShader = smlua_to_string(L, -1);
lua_settop(L, prevTop);
return true;
}
lua_settop(L, prevTop);
}
return false;
}
bool smlua_call_event_hooks_HOOK_ON_FRAGMENT_SHADER_CREATE(struct ColorCombiner *cc, u8 shaderIndex, const char **fragmentShader) {
lua_State *L = gLuaState;
if (L == NULL) { return false; }
struct LuaHookedEvent *hook = &sHookedEvents[HOOK_ON_FRAGMENT_SHADER_CREATE];
for (int i = 0; i < hook->count; i++) {
s32 prevTop = lua_gettop(L);
// push the callback onto the stack
lua_rawgeti(L, LUA_REGISTRYINDEX, hook->reference[i]);
// push cc
smlua_push_object(L, LOT_COLORCOMBINER, cc, NULL);
// push shaderIndex
lua_pushinteger(L, shaderIndex);
// call the callback
if (0 != smlua_call_hook(L, 2, 1, 0, hook->mod[i], hook->modFile[i])) {
LOG_LUA("Failed to call the callback for hook %s - '%s/%s'", sLuaHookedEventTypeName[HOOK_ON_FRAGMENT_SHADER_CREATE], hook->mod[i]->relativePath, hook->modFile[i]->relativePath);
continue;
}
// return fragmentShader
if (lua_type(L, -1) == LUA_TSTRING) {
*fragmentShader = smlua_to_string(L, -1);
lua_settop(L, prevTop);
return true;
}
lua_settop(L, prevTop);
}
return false;
}

View file

@ -21,6 +21,7 @@
#include "pc/configfile.h"
#include "pc/utils/misc.h"
#include "pc/lua/utils/smlua_model_utils.h"
#include "pc/gfx/gfx_cc.h"
#include "../mods/mods.h"
#include "game/print.h"

View file

@ -7,6 +7,7 @@
#include "smlua.h"
#include "pc/mods/mod.h"
#include "pc/lua/utils/smlua_model_utils.h"
#include "pc/gfx/gfx_cc.h"
// forward declare
struct Camera;
@ -82,6 +83,9 @@ enum LuaHookedEventType {
HOOK_ON_FIND_WATER_LEVEL,
HOOK_ON_FIND_POISON_GAS_LEVEL,
HOOK_ON_FIND_SURFACE_ON_RAY,
HOOK_ON_REFRESH_SHADERS,
HOOK_ON_VERTEX_SHADER_CREATE,
HOOK_ON_FRAGMENT_SHADER_CREATE,
HOOK_MAX,
};

View file

@ -1,4 +1,26 @@
#if defined(__MINGW32__) || defined(OSX_BUILD)
# define GLEW_STATIC
# include <GL/glew.h>
#endif
#define GL_GLEXT_PROTOTYPES 1
#ifdef WAPI_SDL2
# include <SDL2/SDL.h>
# ifdef USE_GLES
# include <SDL2/SDL_opengles2.h>
# else
# include <SDL2/SDL_opengl.h>
# endif
#elif defined(WAPI_SDL1)
# include <SDL/SDL.h>
# ifndef GLEW_STATIC
# include <SDL/SDL_opengl.h>
# endif
#endif
#include "smlua_gfx_utils.h"
#include "pc/pc_main.h"
#include "pc/gfx/gfx_pc.h"
#include "game/rendering_graph_node.h"
#include "game/skybox.h"
@ -360,6 +382,69 @@ void gfx_delete_all() {
dynos_gfx_delete_all();
}
void gfx_reload_shaders() {
gfx_remove_all_color_combiners();
RAPI.remove_shaders();
smlua_call_event_hooks(HOOK_ON_REFRESH_SHADERS);
}
struct CCFeatures *gfx_color_combiner_get_features(struct ColorCombiner *cc) {
static struct CCFeatures sCcf = { 0 };
gfx_cc_get_features(cc, &sCcf);
return &sCcf;
}
u32 gfx_get_program_id_from_shader_index(u8 shaderIndex) {
struct ShaderProgram* program = RAPI.lookup_shader_using_index(shaderIndex);
if (!program) return 0;
return program->opengl_program_id;
}
void gfx_use_program(u32 program) {
glUseProgram(program);
}
int gfx_shader_get_uniform_location(u32 program, const char* name) {
return glGetUniformLocation(program, name);
}
void gfx_shader_set_int(int loc, int value) {
if (loc != -1) {
glUniform1i(loc, value);
}
}
void gfx_shader_set_float(int loc, float value) {
if (loc != -1) {
glUniform1f(loc, value);
}
}
void gfx_shader_set_vec2(int loc, float x, float y) {
if (loc != -1) {
glUniform2f(loc, x, y);
}
}
void gfx_shader_set_vec3(int loc, float x, float y, float z) {
if (loc != -1) {
glUniform3f(loc, x, y, z);
}
}
void gfx_shader_set_vec4(int loc, float x, float y, float z, float w) {
if (loc != -1) {
glUniform4f(loc, x, y, z, w);
}
}
void gfx_shader_set_mat4(int loc, const Mat4 mat) {
if (loc != -1) {
glUniformMatrix4fv(loc, 1, GL_FALSE, (const GLfloat*)mat);
}
}
Vtx *vtx_get_from_name(const char *name, RET u32 *count) {
*count = 0;
return dynos_vtx_get(name, count);

View file

@ -92,6 +92,28 @@ void gfx_resize(Gfx *gfx, u32 newLength);
void gfx_delete(Gfx *gfx);
/* |description|Deletes all display lists created by `gfx_create`|descriptionEnd| */
void gfx_delete_all();
/* |description|Reloads all shaders|descriptionEnd| */
void gfx_reload_shaders();
/* |description|Gets features from a color combiner.|descriptionEnd| */
struct CCFeatures *gfx_color_combiner_get_features(struct ColorCombiner *cc);
/* |description|Gets a program id from the shader index.|descriptionEnd| */
u32 gfx_get_program_id_from_shader_index(u8 shaderIndex);
/* |description|Uses a specific program. Required for setting uniforms.|descriptionEnd| */
void gfx_use_program(u32 program);
/* |description|Gets the location of a shader uniform in a program for modification.|descriptionEnd| */
int gfx_shader_get_uniform_location(u32 program, const char* name);
/* |description|Sets the value of a shader uniform of type int.|descriptionEnd| */
void gfx_shader_set_int(int loc, int value);
/* |description|Sets the value of a shader uniform of type float.|descriptionEnd| */
void gfx_shader_set_float(int loc, float value);
/* |description|Sets the value of a shader uniform of type vec2.|descriptionEnd| */
void gfx_shader_set_vec2(int loc, float x, float y);
/* |description|Sets the value of a shader uniform of type vec3.|descriptionEnd| */
void gfx_shader_set_vec3(int loc, float x, float y, float z);
/* |description|Sets the value of a shader uniform of type vec4.|descriptionEnd| */
void gfx_shader_set_vec4(int loc, float w, float x, float y, float z);
/* |description|Sets the value of a shader uniform of type mat4.|descriptionEnd| */
void gfx_shader_set_mat4(int loc, const Mat4 mat);
/* |description|

View file

@ -773,6 +773,8 @@ void network_shutdown(bool sendLeaving, bool exiting, bool popup, bool reconnect
first_person_reset();
le_shutdown();
gfx_remove_all_color_combiners();
RAPI.remove_shaders();
extern void save_file_load_all(UNUSED u8 reload);
save_file_load_all(TRUE);