Enums, example based on LumiLights, README
This commit is contained in:
parent
fd3e722391
commit
3043a8cde2
8
.gitignore
vendored
8
.gitignore
vendored
@ -112,7 +112,11 @@ gradle-app.setting
|
|||||||
**/build/
|
**/build/
|
||||||
|
|
||||||
# Common working directory
|
# Common working directory
|
||||||
run/
|
!/run
|
||||||
|
/run/*
|
||||||
|
!/run/resourcepacks
|
||||||
|
/run/resourcepacks/*
|
||||||
|
!/run/resourcepacks/lumi
|
||||||
|
|
||||||
# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
|
# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
|
||||||
!gradle-wrapper.jar
|
!gradle-wrapper.jar
|
37
README.md
Normal file
37
README.md
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
# Respackopts
|
||||||
|
Respackopts provides resource packs with config menus\
|
||||||
|
By default it integrates with frex (canvas shaders) and libcd (use this as reference)\
|
||||||
|
An example for the frex/canvas integration can be found [here](https://gitlab.com/JFronny/respackopts/-/tree/master/run/resourcepacks/lumi)
|
||||||
|
|
||||||
|
# Using Respackopts
|
||||||
|
## Users
|
||||||
|
You will just need to install Respackopts. A menu button will appear besides all supported resourcepacks.
|
||||||
|
## Resource pack authors
|
||||||
|
You will need to define a respackopts conf as seen [here](https://gitlab.com/JFronny/respackopts/-/blob/master/run/resourcepacks/lumi/assets/respackopts/conf.json)
|
||||||
|
|
||||||
|
This config may include:
|
||||||
|
- boolean values, expressed as Json bools
|
||||||
|
- number values, expressed as Json numbers
|
||||||
|
- string values (not accessible from default integrations), expressed as Json strings
|
||||||
|
- enums, expressed as Json arrays containing simple strings
|
||||||
|
|
||||||
|
The version property defines the format version. It will be incremented if changes to the layout of the config are made\
|
||||||
|
I will likely attempt to support older versions if I decide to make an incompatible change.\
|
||||||
|
To use the information from the config you will need to use and integration module/plugin.\
|
||||||
|
For the ones included by default:
|
||||||
|
### Canvas
|
||||||
|
Respackopts defines a config supplier, you can include it with `#include respackopts:config_supplier`\
|
||||||
|
Values can be accessed with `packId_entryId` for basic elements.\
|
||||||
|
Enum values can be accessed with `packId_entryId_enumKey`.\
|
||||||
|
Examples of using these are available [here](https://gitlab.com/JFronny/respackopts/-/tree/master/run/resourcepacks/lumi)
|
||||||
|
### LibCD
|
||||||
|
The LibCD integration defines a condition named `respackopts:cfg` that takes a string describing the location of a bool as `packId:entryId`
|
||||||
|
|
||||||
|
There have been issues with LibCD in development, so it might be smart not to use it.
|
||||||
|
## Mod developers
|
||||||
|
All data is available in static HashMaps in `io.gitlab.jfronny.respackopts.Respackopts`.\
|
||||||
|
To save information, call `Respackopts.save()`, `Respackopts.load()` to load.
|
||||||
|
`boolVals`, `numVals`, `strVals` and `enumKeys` use the resource pack ID as their first key,
|
||||||
|
then the property name. After that you get the value. Enums are expressed as numbers with enum key names in enumKeys.\
|
||||||
|
If you need code to be ran after changes are made to the state, add an action to `saveActions`.\
|
||||||
|
This is currently used for the Canvas/FREX integration, which uses it to generate shader code.
|
@ -0,0 +1,377 @@
|
|||||||
|
/*
|
||||||
|
* Lumi Lights - A shader pack for Canvas
|
||||||
|
* Copyright (c) 2020 spiralhalo and Contributors
|
||||||
|
*
|
||||||
|
* See `README.md` for license notice.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include canvas:shaders/internal/header.glsl
|
||||||
|
#include canvas:shaders/internal/varying.glsl
|
||||||
|
#include canvas:shaders/internal/diffuse.glsl
|
||||||
|
#include canvas:shaders/internal/flags.glsl
|
||||||
|
#include canvas:shaders/internal/fog.glsl
|
||||||
|
#include frex:shaders/api/world.glsl
|
||||||
|
#include frex:shaders/api/player.glsl
|
||||||
|
#include frex:shaders/api/material.glsl
|
||||||
|
#include frex:shaders/api/fragment.glsl
|
||||||
|
#include frex:shaders/api/sampler.glsl
|
||||||
|
#include frex:shaders/lib/math.glsl
|
||||||
|
#include frex:shaders/lib/color.glsl
|
||||||
|
#include canvas:shaders/internal/program.glsl
|
||||||
|
#include lumi:shaders/api/varying.glsl
|
||||||
|
|
||||||
|
#include canvas:apitarget
|
||||||
|
#include respackopts:config_supplier
|
||||||
|
|
||||||
|
/******************************************************
|
||||||
|
canvas:shaders/internal/material_main.frag
|
||||||
|
******************************************************/
|
||||||
|
|
||||||
|
#define M_PI 3.1415926535897932384626433832795
|
||||||
|
|
||||||
|
const float hdr_sunStr = 3;
|
||||||
|
const float hdr_moonStr = 0.4;
|
||||||
|
const float hdr_blockStr = 1.5;
|
||||||
|
const float hdr_handHeldStr = 0.9;
|
||||||
|
const float hdr_skylessStr = 0.2;
|
||||||
|
const float hdr_baseMinStr = 0.0;
|
||||||
|
const float hdr_baseMaxStr = 0.25;
|
||||||
|
const float hdr_emissiveStr = 1;
|
||||||
|
const float hdr_relAmbient = 0.09;
|
||||||
|
const float hdr_relSunHorizon = 0.5;
|
||||||
|
const float hdr_zWobbleDefault = 0.1;
|
||||||
|
const float hdr_finalMult = 1;
|
||||||
|
const float hdr_gamma = 2.2;
|
||||||
|
|
||||||
|
float hdr_gammaAdjust(float x){
|
||||||
|
return pow(x, hdr_gamma);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 hdr_gammaAdjust(vec3 x){
|
||||||
|
return pow(x, vec3(hdr_gamma));
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 hdr_reinhardJodieTonemap(in vec3 v) {
|
||||||
|
float l = frx_luminance(v);
|
||||||
|
vec3 tv = v / (1.0f + v);
|
||||||
|
return mix(v / (1.0f + l), tv, tv);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 hdr_vibrantTonemap(in vec3 v){
|
||||||
|
return v / (frx_luminance(v) + vec3(1.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
void _cv_startFragment(inout frx_FragmentData data) {
|
||||||
|
int cv_programId = _cv_fragmentProgramId();
|
||||||
|
#include canvas:startfragment
|
||||||
|
}
|
||||||
|
|
||||||
|
float l2_clampScale(float e0, float e1, float v){
|
||||||
|
return clamp((v-e0)/(e1-e0), 0.0, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
float l2_max3(vec3 vec){
|
||||||
|
return max(vec.x, max(vec.y, vec.z));
|
||||||
|
}
|
||||||
|
|
||||||
|
// vec3 l2_what(vec3 rgb){
|
||||||
|
// return vec3(0.4123910 * rgb.r + 0.3575840 * rgb.g + 0.1804810 * rgb.b,
|
||||||
|
// 0.2126390 * rgb.r + 0.7151690 * rgb.g + 0.0721923 * rgb.b,
|
||||||
|
// 0.0193308 * rgb.r + 0.1191950 * rgb.g + 0.9505320 * rgb.b);
|
||||||
|
// }
|
||||||
|
|
||||||
|
vec3 l2_blockLight(float blockLight){
|
||||||
|
float bl = l2_clampScale(0.03125, 1.0, blockLight);
|
||||||
|
bl *= bl * hdr_blockStr;
|
||||||
|
vec3 block = hdr_gammaAdjust(vec3(bl, bl*0.875, bl*0.75));
|
||||||
|
|
||||||
|
#if HANDHELD_LIGHT_RADIUS != 0
|
||||||
|
vec4 held = frx_heldLight();
|
||||||
|
if (held.w > 0.0) {
|
||||||
|
float hl = l2_clampScale(held.w * HANDHELD_LIGHT_RADIUS, 0.0, gl_FogFragCoord);
|
||||||
|
hl *= hl * hdr_handHeldStr;
|
||||||
|
|
||||||
|
return block + hdr_gammaAdjust(held.rgb * hl);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return block;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 l2_emissiveLight(float emissivity){
|
||||||
|
return vec3(hdr_gammaAdjust(emissivity) * hdr_emissiveStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
float l2_skyLight(float skyLight, float intensity)
|
||||||
|
{
|
||||||
|
float sl = l2_clampScale(0.03125, 1.0, skyLight);
|
||||||
|
return hdr_gammaAdjust(sl) * intensity;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 l2_ambientColor(float time){
|
||||||
|
vec3 ambientColor = hdr_gammaAdjust(vec3(0.6, 0.9, 1.0)) * hdr_sunStr * hdr_relAmbient;
|
||||||
|
vec3 sunriseAmbient = hdr_gammaAdjust(vec3(1.0, 0.8, 0.4)) * hdr_sunStr * hdr_relAmbient * hdr_relSunHorizon;
|
||||||
|
vec3 sunsetAmbient = hdr_gammaAdjust(vec3(1.0, 0.6, 0.2)) * hdr_sunStr * hdr_relAmbient * hdr_relSunHorizon;
|
||||||
|
vec3 nightAmbient = hdr_gammaAdjust(vec3(1.0, 1.0, 2.0)) * hdr_moonStr * hdr_relAmbient;
|
||||||
|
if(time > 0.94){
|
||||||
|
ambientColor = mix(nightAmbient, sunriseAmbient, l2_clampScale(0.94, 0.98, time));
|
||||||
|
} else if(time > 0.52){
|
||||||
|
ambientColor = mix(sunsetAmbient, nightAmbient, l2_clampScale(0.52, 0.56, time));
|
||||||
|
} else if(time > 0.48){
|
||||||
|
ambientColor = mix(ambientColor, sunsetAmbient, l2_clampScale(0.48, 0.5, time));
|
||||||
|
} else if(time < 0.02){
|
||||||
|
ambientColor = mix(ambientColor, sunriseAmbient, l2_clampScale(0.02, 0, time));
|
||||||
|
}
|
||||||
|
return ambientColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 l2_skyAmbient(float skyLight, float time, float intensity){
|
||||||
|
float sa = l2_skyLight(skyLight, intensity) * 2.5;
|
||||||
|
return sa * l2_ambientColor(time);
|
||||||
|
}
|
||||||
|
|
||||||
|
float l2_userBrightness(){
|
||||||
|
float base = texture2D(frxs_lightmap, vec2(0.03125, 0.03125)).r;
|
||||||
|
// if(frx_isWorldTheNether()){
|
||||||
|
// return smoothstep(0.15/*0.207 no true darkness in nether*/, 0.577, base);
|
||||||
|
// } else if (frx_isWorldTheEnd(){
|
||||||
|
// return smoothstep(0.18/*0.271 no true darkness in the end*/, 0.685, base);
|
||||||
|
// } else {
|
||||||
|
// return smoothstep(0.053, 0.135, base);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Simplify nether/the end check
|
||||||
|
if(frx_worldHasSkylight()){
|
||||||
|
return smoothstep(0.053, 0.135, base);
|
||||||
|
} else {
|
||||||
|
return smoothstep(0.15, 0.63, base);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 l2_skylessLightColor(){
|
||||||
|
return hdr_gammaAdjust(vec3(1.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 l2_dimensionColor(){
|
||||||
|
if (frx_isWorldTheNether()) {
|
||||||
|
float min_col = min(min(gl_Fog.color.rgb.x, gl_Fog.color.rgb.y), gl_Fog.color.rgb.z);
|
||||||
|
float max_col = max(max(gl_Fog.color.rgb.x, gl_Fog.color.rgb.y), gl_Fog.color.rgb.z);
|
||||||
|
float sat = 0.0;
|
||||||
|
if (max_col != 0.0) {
|
||||||
|
sat = (max_col-min_col)/max_col;
|
||||||
|
}
|
||||||
|
|
||||||
|
return hdr_gammaAdjust(clamp((gl_Fog.color.rgb*(1/max_col))+pow(sat,2)/2, 0.0, 1.0));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return hdr_gammaAdjust(vec3(0.8, 0.7, 1.0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 l2_skylessLight(vec3 normal){
|
||||||
|
if(frx_worldHasSkylight()){
|
||||||
|
return vec3(0);
|
||||||
|
} else {
|
||||||
|
float yalign = dot(normal,vec3(0, 0.977358, 0.211593)); // a bit towards z for more interesting effect
|
||||||
|
yalign = frx_isSkyDarkened()?abs(yalign):max(0,yalign);
|
||||||
|
return yalign * hdr_skylessStr * l2_skylessLightColor() * l2_userBrightness();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 l2_baseAmbient(){
|
||||||
|
if(frx_worldHasSkylight()){
|
||||||
|
return vec3(0.1) * mix(hdr_baseMinStr, hdr_baseMaxStr, l2_userBrightness());
|
||||||
|
} else {
|
||||||
|
return l2_dimensionColor() * mix(hdr_baseMinStr, hdr_baseMaxStr, l2_userBrightness());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 l2_sunColor(float time){
|
||||||
|
vec3 sunColor = hdr_gammaAdjust(vec3(1.0, 1.0, lumi_sunColorFactor)) * hdr_sunStr;
|
||||||
|
vec3 sunriseColor = hdr_gammaAdjust(vec3(1.0, 0.8, 0.4)) * hdr_sunStr * hdr_relSunHorizon;
|
||||||
|
vec3 sunsetColor = hdr_gammaAdjust(vec3(1.0, 0.6, 0.4)) * hdr_sunStr * hdr_relSunHorizon;
|
||||||
|
if(time > 0.94){
|
||||||
|
sunColor = sunriseColor;
|
||||||
|
} else if(time > 0.56){
|
||||||
|
sunColor = vec3(0); // pitch black at night
|
||||||
|
} else if(time > 0.54){
|
||||||
|
sunColor = mix(sunsetColor, vec3(0), l2_clampScale(0.54, 0.56, time));
|
||||||
|
} else if(time > 0.5){
|
||||||
|
sunColor = sunsetColor;
|
||||||
|
} else if(time > 0.48){
|
||||||
|
sunColor = mix(sunColor, sunsetColor, l2_clampScale(0.48, 0.5, time));
|
||||||
|
} else if(time < 0.02){
|
||||||
|
sunColor = mix(sunColor, sunriseColor, l2_clampScale(0.02, 0, time));
|
||||||
|
}
|
||||||
|
return sunColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 l2_vanillaSunDir(in float time, float zWobble){
|
||||||
|
|
||||||
|
// wrap time to account for sunrise
|
||||||
|
time -= (time >= 0.75) ? 1.0 : 0.0;
|
||||||
|
|
||||||
|
// supposed offset of sunset/sunrise from 0/12000 daytime. might get better result with datamining?
|
||||||
|
float sunHorizonDur = 0.04;
|
||||||
|
|
||||||
|
// angle of sun in radians
|
||||||
|
float angleRad = l2_clampScale(-sunHorizonDur, 0.5+sunHorizonDur, time) * M_PI;
|
||||||
|
|
||||||
|
return normalize(vec3(cos(angleRad), sin(angleRad), zWobble));
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 l2_sunLight(float skyLight, in float time, float intensity, float rainGradient, vec3 diffuseNormal){
|
||||||
|
|
||||||
|
// wrap time to account for sunrise
|
||||||
|
float customTime = (time >= 0.75) ? (time - 1.0) : time;
|
||||||
|
|
||||||
|
float customIntensity = l2_clampScale(-0.08, 0.00, customTime);
|
||||||
|
|
||||||
|
if(customTime >= 0.25){
|
||||||
|
customIntensity = l2_clampScale(0.58, 0.5, customTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
customIntensity *= mix(1.0, 0.0, rainGradient);
|
||||||
|
|
||||||
|
float sl = l2_skyLight(skyLight, max(customIntensity, intensity));
|
||||||
|
|
||||||
|
// direct sun light doesn't reach into dark spot as much as sky ambient
|
||||||
|
sl = frx_smootherstep(0.5,1.0,sl);
|
||||||
|
|
||||||
|
// zWobble is added to make more interesting looking diffuse light
|
||||||
|
// TODO: might be fun to use frx_worldDay() with sine wave for the zWobble to simulate annual sun position change
|
||||||
|
sl *= max(0.0, dot(l2_vanillaSunDir(time, hdr_zWobbleDefault), diffuseNormal));
|
||||||
|
return sl * l2_sunColor(time);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 l2_moonLight(float skyLight, float time, float intensity, vec3 diffuseNormal){
|
||||||
|
float ml = l2_skyLight(skyLight, intensity) * frx_moonSize() * hdr_moonStr;
|
||||||
|
float aRad = l2_clampScale(0.56, 0.94, time) * M_PI;
|
||||||
|
ml *= max(0.0, dot(vec3(cos(aRad), sin(aRad), 0), diffuseNormal));
|
||||||
|
if(time < 0.58){
|
||||||
|
ml *= l2_clampScale(0.54, 0.58, time);
|
||||||
|
} else if(time > 0.92){
|
||||||
|
ml *= l2_clampScale(0.96, 0.92, time);
|
||||||
|
}
|
||||||
|
return vec3(ml);
|
||||||
|
}
|
||||||
|
|
||||||
|
float l2_specular(float time, vec3 aNormal, vec3 aPos, vec3 cameraPos, float power)
|
||||||
|
{
|
||||||
|
// calculate sun position (0 zWobble to make it look accurate with vanilla sun visuals)
|
||||||
|
vec3 sunDir = l2_vanillaSunDir(time, 0);
|
||||||
|
|
||||||
|
// obtain the direction of the camera
|
||||||
|
vec3 viewDir = normalize(cameraPos - aPos);
|
||||||
|
|
||||||
|
// calculate the specular light
|
||||||
|
return pow(max(0.0, dot(reflect(-sunDir, aNormal), viewDir)),power);
|
||||||
|
}
|
||||||
|
|
||||||
|
float l2_ao(frx_FragmentData fragData) {
|
||||||
|
#if AO_SHADING_MODE != AO_MODE_NONE
|
||||||
|
float ao = fragData.ao ? _cvv_ao : 1.0;
|
||||||
|
return hdr_gammaAdjust(min(1.0, ao + fragData.emissivity));
|
||||||
|
#else
|
||||||
|
return 1.0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
frx_FragmentData fragData = frx_FragmentData (
|
||||||
|
texture2D(frxs_spriteAltas, _cvv_texcoord, _cv_getFlag(_CV_FLAG_UNMIPPED) * -4.0),
|
||||||
|
_cvv_color,
|
||||||
|
frx_matEmissive() ? 1.0 : 0.0,
|
||||||
|
!frx_matDisableDiffuse(),
|
||||||
|
!frx_matDisableAo(),
|
||||||
|
_cvv_normal,
|
||||||
|
_cvv_lightcoord
|
||||||
|
);
|
||||||
|
|
||||||
|
_cv_startFragment(fragData);
|
||||||
|
|
||||||
|
vec4 a = fragData.spriteColor * fragData.vertexColor;
|
||||||
|
float bloom = fragData.emissivity; // separate bloom from emissivity
|
||||||
|
|
||||||
|
if(frx_isGui()){
|
||||||
|
#if DIFFUSE_SHADING_MODE != DIFFUSE_MODE_NONE
|
||||||
|
if(fragData.diffuse){
|
||||||
|
float diffuse = mix(_cvv_diffuse, 1, fragData.emissivity);
|
||||||
|
vec3 shading = mix(vec3(0.5, 0.4, 0.8) * diffuse * diffuse, vec3(1.0), diffuse);
|
||||||
|
a.rgb *= shading;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
a.rgb = hdr_gammaAdjust(a.rgb);
|
||||||
|
|
||||||
|
// If diffuse is disabled (e.g. grass) then the normal points up by default
|
||||||
|
float ao = l2_ao(fragData);
|
||||||
|
vec3 diffuseNormal = fragData.diffuse?fragData.vertexNormal * frx_normalModelMatrix():vec3(0,1,0);
|
||||||
|
vec3 block = l2_blockLight(fragData.light.x);
|
||||||
|
vec3 sun = l2_sunLight(fragData.light.y, frx_worldTime(), frx_ambientIntensity(), frx_rainGradient(), diffuseNormal);
|
||||||
|
vec3 moon = l2_moonLight(fragData.light.y, frx_worldTime(), frx_ambientIntensity(), diffuseNormal);
|
||||||
|
vec3 skyAmbient = l2_skyAmbient(fragData.light.y, frx_worldTime(), frx_ambientIntensity());
|
||||||
|
vec3 emissive = l2_emissiveLight(fragData.emissivity);
|
||||||
|
vec3 nether = l2_skylessLight(diffuseNormal);
|
||||||
|
|
||||||
|
vec3 light = block + moon + l2_baseAmbient() + skyAmbient + sun + nether;
|
||||||
|
light *= ao; // AO is supposed to be applied to ambient only, but things look better with AO on everything except for emissive light
|
||||||
|
light += emissive;
|
||||||
|
|
||||||
|
vec3 specular = vec3(0.0);
|
||||||
|
if (wwv_specPower > 0.01) {
|
||||||
|
vec3 specularNormal = fragData.vertexNormal * frx_normalModelMatrix();
|
||||||
|
|
||||||
|
float skyAccess = smoothstep(0.89, 1.0, fragData.light.y);
|
||||||
|
|
||||||
|
vec3 fragPos = frx_var0.xyz;
|
||||||
|
vec3 cameraPos = frx_var1.xyz;
|
||||||
|
vec3 sunDir = l2_vanillaSunDir(frx_worldTime(), 0);
|
||||||
|
vec3 sun = l2_sunLight(fragData.light.y, frx_worldTime(), frx_ambientIntensity(), frx_rainGradient(), sunDir);
|
||||||
|
|
||||||
|
float specularAmount = l2_specular(frx_worldTime(), specularNormal, fragPos, cameraPos, wwv_specPower);
|
||||||
|
|
||||||
|
specular = sun * specularAmount * skyAccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.rgb *= light;
|
||||||
|
a.rgb += specular;
|
||||||
|
|
||||||
|
float specularLuminance = frx_luminance(specular);
|
||||||
|
a.a += specularLuminance;
|
||||||
|
bloom += specularLuminance;
|
||||||
|
|
||||||
|
a.rgb *= hdr_finalMult;
|
||||||
|
#if lumi_tonemap == lumi_tonemap_vibrant
|
||||||
|
a.rgb = pow(hdr_vibrantTonemap(a.rgb), vec3(1.0 / hdr_gamma));
|
||||||
|
#elif lumi_tonemap == reinhardJodie
|
||||||
|
a.rgb = pow(hdr_reinhardJodieTonemap(a.rgb), vec3(1.0 / hdr_gamma));
|
||||||
|
#else
|
||||||
|
a.rgb = pow(frx_toneMap(a.rgb), vec3(1.0 / hdr_gamma));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// PERF: varyings better here?
|
||||||
|
if (_cv_getFlag(_CV_FLAG_CUTOUT) == 1.0) {
|
||||||
|
float t = _cv_getFlag(_CV_FLAG_TRANSLUCENT_CUTOUT) == 1.0 ? _CV_TRANSLUCENT_CUTOUT_THRESHOLD : 0.5;
|
||||||
|
|
||||||
|
if (a.a < t) {
|
||||||
|
discard;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PERF: varyings better here?
|
||||||
|
if (_cv_getFlag(_CV_FLAG_FLASH_OVERLAY) == 1.0) {
|
||||||
|
a = a * 0.25 + 0.75;
|
||||||
|
} else if (_cv_getFlag(_CV_FLAG_HURT_OVERLAY) == 1.0) {
|
||||||
|
a = vec4(0.25 + a.r * 0.75, a.g * 0.75, a.b * 0.75, a.a);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: need a separate fog pass?
|
||||||
|
gl_FragData[TARGET_BASECOLOR] = _cv_fog(a);
|
||||||
|
gl_FragDepth = gl_FragCoord.z;
|
||||||
|
|
||||||
|
#if TARGET_EMISSIVE > 0
|
||||||
|
gl_FragData[TARGET_EMISSIVE] = vec4(bloom * a.a, 1.0, 0.0, 1.0);
|
||||||
|
#endif
|
||||||
|
}
|
@ -0,0 +1,89 @@
|
|||||||
|
#include canvas:shaders/internal/header.glsl
|
||||||
|
#include frex:shaders/api/context.glsl
|
||||||
|
#include canvas:shaders/internal/varying.glsl
|
||||||
|
#include canvas:shaders/internal/vertex.glsl
|
||||||
|
#include canvas:shaders/internal/flags.glsl
|
||||||
|
#include frex:shaders/api/vertex.glsl
|
||||||
|
#include frex:shaders/api/sampler.glsl
|
||||||
|
#include canvas:shaders/internal/diffuse.glsl
|
||||||
|
#include canvas:shaders/internal/program.glsl
|
||||||
|
#include lumi:shaders/api/varying.glsl
|
||||||
|
|
||||||
|
#include canvas:apitarget
|
||||||
|
|
||||||
|
/******************************************************
|
||||||
|
canvas:shaders/internal/material_main.vert
|
||||||
|
******************************************************/
|
||||||
|
|
||||||
|
void _cv_startVertex(inout frx_VertexData data, in int cv_programId) {
|
||||||
|
#include canvas:startvertex
|
||||||
|
}
|
||||||
|
|
||||||
|
void _cv_endVertex(inout frx_VertexData data, in int cv_programId) {
|
||||||
|
#include canvas:endvertex
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
frx_VertexData data = frx_VertexData(
|
||||||
|
gl_Vertex,
|
||||||
|
in_uv,
|
||||||
|
in_color,
|
||||||
|
(in_normal_flags.xyz - 127.0) / 127.0,
|
||||||
|
in_lightmap.rg * 0.00390625 + 0.03125
|
||||||
|
);
|
||||||
|
|
||||||
|
// Adding +0.5 prevents striping or other strangeness in flag-dependent rendering
|
||||||
|
// due to FP error on some cards/drivers. Also made varying attribute invariant (rolls eyes at OpenGL)
|
||||||
|
_cvv_flags = uint(in_normal_flags.w + 0.5);
|
||||||
|
|
||||||
|
wwv_specPower = 0.0;
|
||||||
|
|
||||||
|
_cv_setupProgram();
|
||||||
|
|
||||||
|
int cv_programId = _cv_vertexProgramId();
|
||||||
|
_cv_startVertex(data, cv_programId);
|
||||||
|
|
||||||
|
if (_cvu_atlas[_CV_SPRITE_INFO_TEXTURE_SIZE] != 0.0) {
|
||||||
|
float spriteIndex = in_material.x;
|
||||||
|
// for sprite atlas textures, convert from normalized (0-1) to interpolated coordinates
|
||||||
|
vec4 spriteBounds = texture2DLod(frxs_spriteInfo, vec2(0, spriteIndex / _cvu_atlas[_CV_SPRITE_INFO_TEXTURE_SIZE]), 0);
|
||||||
|
|
||||||
|
float atlasHeight = _cvu_atlas[_CV_ATLAS_HEIGHT];
|
||||||
|
float atlasWidth = _cvu_atlas[_CV_ATLAS_WIDTH];
|
||||||
|
|
||||||
|
// snap sprite bounds to integer coordinates to correct for floating point error
|
||||||
|
spriteBounds *= vec4(atlasWidth, atlasHeight, atlasWidth, atlasHeight);
|
||||||
|
spriteBounds += vec4(0.5, 0.5, 0.5, 0.5);
|
||||||
|
spriteBounds -= fract(spriteBounds);
|
||||||
|
spriteBounds /= vec4(atlasWidth, atlasHeight, atlasWidth, atlasHeight);
|
||||||
|
|
||||||
|
data.spriteUV = spriteBounds.xy + data.spriteUV * spriteBounds.zw;
|
||||||
|
}
|
||||||
|
|
||||||
|
data.spriteUV = _cv_textureCoord(data.spriteUV, 0);
|
||||||
|
|
||||||
|
vec4 viewCoord = gl_ModelViewMatrix * data.vertex;
|
||||||
|
gl_ClipVertex = viewCoord;
|
||||||
|
gl_FogFragCoord = length(viewCoord.xyz);
|
||||||
|
|
||||||
|
//data.normal *= gl_NormalMatrix;
|
||||||
|
data.vertex = gl_ModelViewProjectionMatrix * data.vertex;
|
||||||
|
|
||||||
|
gl_Position = data.vertex;
|
||||||
|
|
||||||
|
_cv_endVertex(data, cv_programId);
|
||||||
|
|
||||||
|
_cvv_texcoord = data.spriteUV;
|
||||||
|
_cvv_color = data.color;
|
||||||
|
_cvv_normal = data.normal;
|
||||||
|
|
||||||
|
#if DIFFUSE_SHADING_MODE != DIFFUSE_MODE_NONE
|
||||||
|
_cvv_diffuse = _cv_diffuse(_cvv_normal);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if AO_SHADING_MODE != AO_MODE_NONE
|
||||||
|
_cvv_ao = in_lightmap.b / 255.0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
_cvv_lightcoord = data.light;
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* Derived from Canvas source code (https://github.com/grondag/canvas/)
|
||||||
|
*
|
||||||
|
* Changes are made to add bloom to sky fragments.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include canvas:shaders/internal/process/header.glsl
|
||||||
|
#include frex:shaders/lib/color.glsl
|
||||||
|
#include frex:shaders/lib/sample.glsl
|
||||||
|
#include frex:shaders/lib/math.glsl
|
||||||
|
|
||||||
|
/******************************************************
|
||||||
|
canvas:shaders/internal/process/emissive_color.frag
|
||||||
|
******************************************************/
|
||||||
|
uniform sampler2D _cvu_base;
|
||||||
|
uniform sampler2D _cvu_emissive;
|
||||||
|
uniform ivec2 _cvu_size;
|
||||||
|
|
||||||
|
varying vec2 _cvv_texcoord;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec4 e = texture2D(_cvu_emissive, _cvv_texcoord);
|
||||||
|
|
||||||
|
bool sky = e.g == 0.0;
|
||||||
|
float bloom = sky ? 0.25 : e.r;
|
||||||
|
|
||||||
|
vec4 c = frx_fromGamma(texture2D(_cvu_base, _cvv_texcoord));
|
||||||
|
|
||||||
|
gl_FragData[0] = vec4(c.rgb * bloom, e.r);
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"blendMode": "translucent",
|
||||||
|
"disableAo": true,
|
||||||
|
"disableDiffuse": true,
|
||||||
|
"vertexSource": "lumi:shaders/material/water.vert",
|
||||||
|
"fragmentSource": "lumi:shaders/material/water.frag"
|
||||||
|
}
|
@ -0,0 +1,2 @@
|
|||||||
|
// If wwv_specPower is used, frx_var0 must be reserved for fragPos and frx_var1 must be reserved for cameraPos
|
||||||
|
varying float wwv_specPower;
|
@ -0,0 +1,7 @@
|
|||||||
|
#include frex:shaders/lib/noise/noise3d.glsl
|
||||||
|
|
||||||
|
float l2_noise(vec3 aPos, float renderTime, float scale, float amplitude)
|
||||||
|
{
|
||||||
|
float invScale = 1/scale;
|
||||||
|
return (snoise(vec3(aPos.x*invScale, aPos.z*invScale, renderTime)) * 0.5+0.5) * amplitude;
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
#include lumi:shaders/api/varying.glsl
|
||||||
|
#include lumi:shaders/lib/noise.glsl
|
||||||
|
#include frex:shaders/api/fragment.glsl
|
||||||
|
#include frex:shaders/api/world.glsl
|
||||||
|
#include respackopts:config_supplier
|
||||||
|
|
||||||
|
void frx_startFragment(inout frx_FragmentData fragData) {
|
||||||
|
fragData.spriteColor.rgb *= fragData.spriteColor.rgb * lumi_waterColorFactor;
|
||||||
|
|
||||||
|
if(fragData.vertexNormal.y > 0.01) {
|
||||||
|
|
||||||
|
// hack
|
||||||
|
fragData.light.y += 0.077 * smoothstep(1.0, 0.99, fragData.vertexNormal.y);
|
||||||
|
fragData.light.y = min(0.96875, fragData.light.y);
|
||||||
|
|
||||||
|
vec3 worldPos = frx_modelOriginWorldPos() + frx_var0.xyz;
|
||||||
|
// water wavyness parameter
|
||||||
|
float timeScale = 2; // speed
|
||||||
|
float noiseScale = 2; // wavelength
|
||||||
|
float noiseAmp = 0.03125 * noiseScale;// * timeScale; // amplitude
|
||||||
|
|
||||||
|
// inferred parameter
|
||||||
|
float renderTime = frx_renderSeconds() * 0.5 * timeScale;
|
||||||
|
float microSample = 0.01 * noiseScale;
|
||||||
|
|
||||||
|
// base noise
|
||||||
|
float noise = l2_noise(worldPos, renderTime, noiseScale, noiseAmp);
|
||||||
|
|
||||||
|
// normal recalculation
|
||||||
|
vec3 noiseOrigin = vec3(0, noise, 0);
|
||||||
|
vec3 noiseTangent = vec3(microSample, l2_noise(worldPos + vec3(microSample,0,0), renderTime, noiseScale, noiseAmp), 0) - noiseOrigin;
|
||||||
|
vec3 noiseBitangent = vec3(0, l2_noise(worldPos + vec3(0,0,microSample), renderTime, noiseScale, noiseAmp), microSample) - noiseOrigin;
|
||||||
|
|
||||||
|
// noisy normal
|
||||||
|
vec3 noisyNormal = normalize(cross(noiseBitangent, noiseTangent));
|
||||||
|
fragData.vertexNormal = noisyNormal;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
#include frex:shaders/api/vertex.glsl
|
||||||
|
#include lumi:shaders/api/varying.glsl
|
||||||
|
|
||||||
|
void frx_startVertex(inout frx_VertexData data) {
|
||||||
|
frx_var0.xyz = data.vertex.xyz;
|
||||||
|
frx_var1.xyz = (gl_ModelViewMatrixInverse * vec4(0.0, 0.0, 0.0, 1.0)).xyz;
|
||||||
|
wwv_specPower = 100.0;
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"defaultMaterial": "lumi:tasty_liquid"
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"defaultMaterial": "lumi:tasty_liquid"
|
||||||
|
}
|
13
run/resourcepacks/lumi/assets/respackopts/conf.json
Normal file
13
run/resourcepacks/lumi/assets/respackopts/conf.json
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"id": "lumi",
|
||||||
|
"version": 1,
|
||||||
|
"conf": {
|
||||||
|
"tonemap": [
|
||||||
|
"reinhardJodie",
|
||||||
|
"vibrant",
|
||||||
|
"fxr"
|
||||||
|
],
|
||||||
|
"sunColorFactor": 0.8,
|
||||||
|
"waterColorFactor": 1
|
||||||
|
}
|
||||||
|
}
|
6
run/resourcepacks/lumi/pack.mcmeta
Normal file
6
run/resourcepacks/lumi/pack.mcmeta
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"pack": {
|
||||||
|
"pack_format": 6,
|
||||||
|
"description": "§3Aesthetic shader pack\n§8by awoo [v1.0-wip]"
|
||||||
|
}
|
||||||
|
}
|
BIN
run/resourcepacks/lumi/pack.png
Normal file
BIN
run/resourcepacks/lumi/pack.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 24 KiB |
@ -6,6 +6,8 @@ import com.google.gson.JsonPrimitive;
|
|||||||
import me.shedaniel.clothconfig2.api.ConfigBuilder;
|
import me.shedaniel.clothconfig2.api.ConfigBuilder;
|
||||||
import me.shedaniel.clothconfig2.api.ConfigCategory;
|
import me.shedaniel.clothconfig2.api.ConfigCategory;
|
||||||
import me.shedaniel.clothconfig2.api.ConfigEntryBuilder;
|
import me.shedaniel.clothconfig2.api.ConfigEntryBuilder;
|
||||||
|
import me.shedaniel.clothconfig2.gui.entries.DropdownBoxEntry;
|
||||||
|
import me.shedaniel.clothconfig2.impl.builders.DropdownMenuBuilder;
|
||||||
import net.minecraft.client.gui.screen.FatalErrorScreen;
|
import net.minecraft.client.gui.screen.FatalErrorScreen;
|
||||||
import net.minecraft.client.gui.screen.Screen;
|
import net.minecraft.client.gui.screen.Screen;
|
||||||
import net.minecraft.text.*;
|
import net.minecraft.text.*;
|
||||||
@ -13,6 +15,7 @@ import net.minecraft.util.Language;
|
|||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.TreeSet;
|
||||||
|
|
||||||
public class GuiFactory {
|
public class GuiFactory {
|
||||||
public void buildCategory(JsonObject source, String screenId, ConfigCategory config, ConfigEntryBuilder entryBuilder) {
|
public void buildCategory(JsonObject source, String screenId, ConfigCategory config, ConfigEntryBuilder entryBuilder) {
|
||||||
@ -22,6 +25,8 @@ public class GuiFactory {
|
|||||||
Respackopts.numVals.put(screenId, new HashMap<>());
|
Respackopts.numVals.put(screenId, new HashMap<>());
|
||||||
if (!Respackopts.strVals.containsKey(screenId))
|
if (!Respackopts.strVals.containsKey(screenId))
|
||||||
Respackopts.strVals.put(screenId, new HashMap<>());
|
Respackopts.strVals.put(screenId, new HashMap<>());
|
||||||
|
if (!Respackopts.enumKeys.containsKey(screenId))
|
||||||
|
Respackopts.enumKeys.put(screenId, new HashMap<>());
|
||||||
String b = "respackopts.field." + screenId;
|
String b = "respackopts.field." + screenId;
|
||||||
for (Map.Entry<String, JsonElement> entry : source.entrySet()) {
|
for (Map.Entry<String, JsonElement> entry : source.entrySet()) {
|
||||||
String n = entry.getKey();
|
String n = entry.getKey();
|
||||||
@ -41,23 +46,19 @@ public class GuiFactory {
|
|||||||
Respackopts.boolVals.get(screenId).put(n, defaultValue);
|
Respackopts.boolVals.get(screenId).put(n, defaultValue);
|
||||||
config.addEntry(entryBuilder.startBooleanToggle(getText(n, b), currentValue)
|
config.addEntry(entryBuilder.startBooleanToggle(getText(n, b), currentValue)
|
||||||
.setDefaultValue(defaultValue)
|
.setDefaultValue(defaultValue)
|
||||||
.setSaveConsumer(v -> {
|
.setSaveConsumer(v -> Respackopts.boolVals.get(screenId).put(n, v))
|
||||||
Respackopts.boolVals.get(screenId).put(n, v);
|
|
||||||
})
|
|
||||||
.build());
|
.build());
|
||||||
}
|
}
|
||||||
else if (p.isNumber()) {
|
else if (p.isNumber()) {
|
||||||
double defaultValue = p.getAsDouble();
|
double defaultValue = p.getAsDouble();
|
||||||
double currentValue = defaultValue;
|
Double currentValue = defaultValue;
|
||||||
if (Respackopts.numVals.get(screenId).containsKey(n))
|
if (Respackopts.numVals.get(screenId).containsKey(n))
|
||||||
currentValue = Respackopts.numVals.get(screenId).get(n);
|
currentValue = Respackopts.numVals.get(screenId).get(n);
|
||||||
else
|
else
|
||||||
Respackopts.numVals.get(screenId).put(n, defaultValue);
|
Respackopts.numVals.get(screenId).put(n, defaultValue);
|
||||||
config.addEntry(entryBuilder.startDoubleField(getText(n, b), currentValue)
|
config.addEntry(entryBuilder.startDoubleField(getText(n, b), currentValue)
|
||||||
.setDefaultValue(defaultValue)
|
.setDefaultValue(defaultValue)
|
||||||
.setSaveConsumer(v -> {
|
.setSaveConsumer(v -> Respackopts.numVals.get(screenId).put(n, v))
|
||||||
Respackopts.numVals.get(screenId).put(n, v);
|
|
||||||
})
|
|
||||||
.build());
|
.build());
|
||||||
}
|
}
|
||||||
else if (p.isString()) {
|
else if (p.isString()) {
|
||||||
@ -69,12 +70,34 @@ public class GuiFactory {
|
|||||||
Respackopts.strVals.get(screenId).put(n, defaultValue);
|
Respackopts.strVals.get(screenId).put(n, defaultValue);
|
||||||
config.addEntry(entryBuilder.startStrField(getText(n, b), currentValue)
|
config.addEntry(entryBuilder.startStrField(getText(n, b), currentValue)
|
||||||
.setDefaultValue(defaultValue)
|
.setDefaultValue(defaultValue)
|
||||||
.setSaveConsumer(v -> {
|
.setSaveConsumer(v -> Respackopts.strVals.get(screenId).put(n, v))
|
||||||
Respackopts.strVals.get(screenId).put(n, v);
|
|
||||||
})
|
|
||||||
.build());
|
.build());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (e.isJsonArray()) {
|
||||||
|
TreeSet<String> ev = Respackopts.enumKeys.get(screenId).get(n);
|
||||||
|
Double c = Respackopts.numVals.get(screenId).get(n);
|
||||||
|
String sel = ev.first();
|
||||||
|
int i = 0;
|
||||||
|
for (String s1 : ev) {
|
||||||
|
if (c.intValue() == i) {
|
||||||
|
sel = s1;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
config.addEntry(entryBuilder.startDropdownMenu(getText(n, b), (DropdownBoxEntry.SelectionTopCellElement) DropdownMenuBuilder.TopCellElementBuilder.of(sel, (s) -> s, (s) -> getText(s, n + "." + b)), new DropdownBoxEntry.DefaultSelectionCellCreator())
|
||||||
|
.setSuggestionMode(false)
|
||||||
|
.setDefaultValue(ev.first())
|
||||||
|
.setSelections(() -> ev.iterator())
|
||||||
|
.setSaveConsumer(v -> {
|
||||||
|
int j = 0;
|
||||||
|
for (String s1 : ev) {
|
||||||
|
if (s1.equals(v))
|
||||||
|
Respackopts.numVals.get(screenId).put(n, (double) j);
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
}).build());
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
System.err.println("[respackopts] Unsupported non-primitive datatype");
|
System.err.println("[respackopts] Unsupported non-primitive datatype");
|
||||||
}
|
}
|
||||||
@ -88,11 +111,7 @@ public class GuiFactory {
|
|||||||
.setParentScreen(parent)
|
.setParentScreen(parent)
|
||||||
.setTitle(getText(resourcepackid, "respackopts.title"));
|
.setTitle(getText(resourcepackid, "respackopts.title"));
|
||||||
ConfigEntryBuilder entryBuilder = builder.entryBuilder();
|
ConfigEntryBuilder entryBuilder = builder.entryBuilder();
|
||||||
builder.setSavingRunnable(() -> {
|
builder.setSavingRunnable(Respackopts::save);
|
||||||
System.out.println("Save");
|
|
||||||
Respackopts.updateShaders();
|
|
||||||
Respackopts.save();
|
|
||||||
});
|
|
||||||
ConfigCategory config = builder.getOrCreateCategory(getText(resourcepackid, "respackopts.category"));
|
ConfigCategory config = builder.getOrCreateCategory(getText(resourcepackid, "respackopts.category"));
|
||||||
buildCategory(source, resourcepackid, config, entryBuilder);
|
buildCategory(source, resourcepackid, config, entryBuilder);
|
||||||
return builder.build();
|
return builder.build();
|
||||||
|
@ -18,10 +18,7 @@ public class MMI implements ModMenuApi {
|
|||||||
.setParentScreen(parent)
|
.setParentScreen(parent)
|
||||||
.setTitle(new TranslatableText("respackopts.mainconfig"));
|
.setTitle(new TranslatableText("respackopts.mainconfig"));
|
||||||
ConfigEntryBuilder entryBuilder = builder.entryBuilder();
|
ConfigEntryBuilder entryBuilder = builder.entryBuilder();
|
||||||
builder.setSavingRunnable(() -> {
|
builder.setSavingRunnable(Respackopts::save);
|
||||||
Respackopts.updateShaders();
|
|
||||||
Respackopts.save();
|
|
||||||
});
|
|
||||||
Respackopts.resPackMetas.forEach((s, v) -> {
|
Respackopts.resPackMetas.forEach((s, v) -> {
|
||||||
ConfigCategory config = builder.getOrCreateCategory(new TranslatableText("respackopts.category." + v.id));
|
ConfigCategory config = builder.getOrCreateCategory(new TranslatableText("respackopts.category." + v.id));
|
||||||
Respackopts.factory.buildCategory(v.conf, v.id, config, entryBuilder);
|
Respackopts.factory.buildCategory(v.conf, v.id, config, entryBuilder);
|
||||||
|
@ -8,11 +8,13 @@ import net.fabricmc.api.EnvType;
|
|||||||
import net.fabricmc.api.Environment;
|
import net.fabricmc.api.Environment;
|
||||||
import net.fabricmc.loader.api.FabricLoader;
|
import net.fabricmc.loader.api.FabricLoader;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.TreeSet;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
@Environment(EnvType.CLIENT)
|
@Environment(EnvType.CLIENT)
|
||||||
@ -20,19 +22,20 @@ public class Respackopts implements ClientModInitializer {
|
|||||||
public static HashMap<String, HashMap<String, Boolean>> boolVals;
|
public static HashMap<String, HashMap<String, Boolean>> boolVals;
|
||||||
public static HashMap<String, HashMap<String, Double>> numVals;
|
public static HashMap<String, HashMap<String, Double>> numVals;
|
||||||
public static HashMap<String, HashMap<String, String>> strVals;
|
public static HashMap<String, HashMap<String, String>> strVals;
|
||||||
|
public static HashMap<String, HashMap<String, TreeSet<String>>> enumKeys;
|
||||||
public static Gson g = new Gson();
|
public static Gson g = new Gson();
|
||||||
public static GuiFactory factory = new GuiFactory();
|
public static GuiFactory factory = new GuiFactory();
|
||||||
public static final Integer metaVersion = 1;
|
public static final Integer metaVersion = 1;
|
||||||
public static HashMap<String, Respackmeta> resPackMetas = new HashMap<>();
|
public static HashMap<String, Respackmeta> resPackMetas = new HashMap<>();
|
||||||
public static final String ID = "respackopts";
|
public static final String ID = "respackopts";
|
||||||
static final Path p = FabricLoader.getInstance().getConfigDir().resolve("respackopts");
|
static final Path p = FabricLoader.getInstance().getConfigDir().resolve("respackopts");
|
||||||
public static final HashSet<Consumer<String>> shaderConsumers = new HashSet<>();
|
public static final HashSet<Runnable> saveActions = new HashSet<>();
|
||||||
@Override
|
@Override
|
||||||
public void onInitializeClient() {
|
public void onInitializeClient() {
|
||||||
load();
|
load();
|
||||||
Respackopts.updateShaders();
|
Respackopts.save();
|
||||||
if (FabricLoader.getInstance().isDevelopmentEnvironment())
|
if (FabricLoader.getInstance().isDevelopmentEnvironment())
|
||||||
shaderConsumers.add(System.out::println);
|
saveActions.add(() -> System.out.println("Save"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void save() {
|
public static void save() {
|
||||||
@ -61,6 +64,9 @@ public class Respackopts implements ClientModInitializer {
|
|||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (Runnable action : saveActions) {
|
||||||
|
action.run();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void load() {
|
public static void load() {
|
||||||
@ -90,37 +96,14 @@ public class Respackopts implements ClientModInitializer {
|
|||||||
deNull();
|
deNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void deNull() {
|
private static void deNull() {
|
||||||
if (boolVals == null)
|
if (boolVals == null)
|
||||||
boolVals = new HashMap<>();
|
boolVals = new HashMap<>();
|
||||||
if (numVals == null)
|
if (numVals == null)
|
||||||
numVals = new HashMap<>();
|
numVals = new HashMap<>();
|
||||||
if (strVals == null)
|
if (strVals == null)
|
||||||
strVals = new HashMap<>();
|
strVals = new HashMap<>();
|
||||||
}
|
if (enumKeys == null)
|
||||||
|
enumKeys = new HashMap<>();
|
||||||
public static void updateShaders() {
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
numVals.forEach((s, v) -> v.forEach((s1, v1) -> {
|
|
||||||
sb.append("\n");
|
|
||||||
sb.append("#define ");
|
|
||||||
sb.append(s);
|
|
||||||
sb.append("_");
|
|
||||||
sb.append(s1);
|
|
||||||
sb.append(" ");
|
|
||||||
sb.append(v1);
|
|
||||||
}));
|
|
||||||
boolVals.forEach((s, v) -> v.forEach((s1, v1) -> {
|
|
||||||
if (v1) {
|
|
||||||
sb.append("\n");
|
|
||||||
sb.append("#define ");
|
|
||||||
sb.append(s);
|
|
||||||
sb.append("_");
|
|
||||||
sb.append(s1);
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
for (Consumer<String> consumer : shaderConsumers) {
|
|
||||||
consumer.accept(sb.toString());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,14 +6,52 @@ import io.gitlab.jfronny.respackopts.Respackopts;
|
|||||||
import net.fabricmc.loader.api.FabricLoader;
|
import net.fabricmc.loader.api.FabricLoader;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
public class FrexCompat implements FrexInitializer {
|
public class FrexCompat implements FrexInitializer {
|
||||||
String currentShaderCode = "";
|
|
||||||
@Override
|
@Override
|
||||||
public void onInitalizeFrex() {
|
public void onInitalizeFrex() {
|
||||||
System.out.println("[respackopts] enabling canvas support");
|
ShaderConfig.registerShaderConfigSupplier(new Identifier(Respackopts.ID, "config_supplier"), () -> {
|
||||||
ShaderConfig.registerShaderConfigSupplier(new Identifier(Respackopts.ID, "config_supplier"), () -> currentShaderCode);
|
StringBuilder sb = new StringBuilder();
|
||||||
Respackopts.shaderConsumers.add((s) -> {
|
Respackopts.numVals.forEach((s, v) -> v.forEach((s1, v1) -> {
|
||||||
currentShaderCode = s;
|
sb.append("\n");
|
||||||
|
sb.append("#define ");
|
||||||
|
sb.append(s);
|
||||||
|
sb.append("_");
|
||||||
|
sb.append(s1);
|
||||||
|
sb.append(" ");
|
||||||
|
String tmp = v1.toString();
|
||||||
|
if (tmp.endsWith(".0"))
|
||||||
|
tmp = tmp.substring(0, tmp.length() - 2);
|
||||||
|
sb.append(tmp);
|
||||||
|
}));
|
||||||
|
Respackopts.boolVals.forEach((s, v) -> v.forEach((s1, v1) -> {
|
||||||
|
if (v1) {
|
||||||
|
sb.append("\n");
|
||||||
|
sb.append("#define ");
|
||||||
|
sb.append(s);
|
||||||
|
sb.append("_");
|
||||||
|
sb.append(s1);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
Respackopts.enumKeys.forEach((s, v) -> v.forEach((s1, v1) -> {
|
||||||
|
AtomicInteger i = new AtomicInteger(0);
|
||||||
|
v1.forEach((s2) -> {
|
||||||
|
sb.append("\n");
|
||||||
|
sb.append("#define ");
|
||||||
|
sb.append(s);
|
||||||
|
sb.append("_");
|
||||||
|
sb.append(s1);
|
||||||
|
sb.append("_");
|
||||||
|
sb.append(s2);
|
||||||
|
sb.append(" ");
|
||||||
|
sb.append(i.getAndIncrement());
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
return sb.toString();
|
||||||
|
});
|
||||||
|
System.out.println("[respackopts] enabled frex/canvas support");
|
||||||
|
Respackopts.saveActions.add(() -> {
|
||||||
try {
|
try {
|
||||||
ShaderConfig.invalidateShaderConfig();
|
ShaderConfig.invalidateShaderConfig();
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
package io.gitlab.jfronny.respackopts.mixin;
|
package io.gitlab.jfronny.respackopts.mixin;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.*;
|
||||||
import com.google.gson.JsonElement;
|
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
import com.google.gson.JsonPrimitive;
|
|
||||||
import io.gitlab.jfronny.respackopts.Respackopts;
|
import io.gitlab.jfronny.respackopts.Respackopts;
|
||||||
import io.gitlab.jfronny.respackopts.data.Respackmeta;
|
import io.gitlab.jfronny.respackopts.data.Respackmeta;
|
||||||
import net.minecraft.resource.ResourcePackManager;
|
import net.minecraft.resource.ResourcePackManager;
|
||||||
@ -20,7 +17,9 @@ import java.io.ByteArrayOutputStream;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.TreeSet;
|
||||||
|
|
||||||
@Mixin(ResourcePackManager.class)
|
@Mixin(ResourcePackManager.class)
|
||||||
public class ResourcePackManagerMixin {
|
public class ResourcePackManagerMixin {
|
||||||
@ -38,9 +37,11 @@ public class ResourcePackManagerMixin {
|
|||||||
Respackopts.numVals.put(conf.id, new HashMap<>());
|
Respackopts.numVals.put(conf.id, new HashMap<>());
|
||||||
if (!Respackopts.strVals.containsKey(conf.id))
|
if (!Respackopts.strVals.containsKey(conf.id))
|
||||||
Respackopts.strVals.put(conf.id, new HashMap<>());
|
Respackopts.strVals.put(conf.id, new HashMap<>());
|
||||||
|
if (!Respackopts.enumKeys.containsKey(conf.id))
|
||||||
|
Respackopts.enumKeys.put(conf.id, new HashMap<>());
|
||||||
for (Map.Entry<String, JsonElement> entry : conf.conf.entrySet()) {
|
for (Map.Entry<String, JsonElement> entry : conf.conf.entrySet()) {
|
||||||
String n = entry.getKey();
|
String n = entry.getKey();
|
||||||
if (n.contains(":") || n.contains(".")) {
|
if (n.contains(":") || n.contains(".") || n.contains("_")) {
|
||||||
System.err.println(n + " contains invalid characters");
|
System.err.println(n + " contains invalid characters");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -60,6 +61,32 @@ public class ResourcePackManagerMixin {
|
|||||||
Respackopts.strVals.get(conf.id).put(n, p.getAsString());
|
Respackopts.strVals.get(conf.id).put(n, p.getAsString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (e.isJsonArray()) {
|
||||||
|
JsonArray a = e.getAsJsonArray();
|
||||||
|
for (JsonElement element : a) {
|
||||||
|
if (!element.isJsonPrimitive()) {
|
||||||
|
System.err.println("[respackopts] Unsupported non-primitive datatype");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!Respackopts.enumKeys.get(conf.id).containsKey(n)) {
|
||||||
|
Respackopts.enumKeys.get(conf.id).put(n, new TreeSet<>());
|
||||||
|
}
|
||||||
|
JsonPrimitive p = element.getAsJsonPrimitive();
|
||||||
|
if (!p.isString()) {
|
||||||
|
System.err.println("[respackopts] Unsupported non-string enum key");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String b = p.getAsString();
|
||||||
|
if (b.contains(":") || b.contains(".") || b.contains("_")) {
|
||||||
|
System.err.println(b + " contains invalid characters");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Respackopts.enumKeys.get(conf.id).get(n).add(b);
|
||||||
|
}
|
||||||
|
if (!Respackopts.numVals.get(conf.id).containsKey(n)) {
|
||||||
|
Respackopts.numVals.get(conf.id).put(n, 0d);
|
||||||
|
}
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
System.err.println("[respackopts] Unsupported non-primitive datatype");
|
System.err.println("[respackopts] Unsupported non-primitive datatype");
|
||||||
}
|
}
|
||||||
@ -75,9 +102,8 @@ public class ResourcePackManagerMixin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Respackopts.load();
|
|
||||||
Respackopts.updateShaders();
|
|
||||||
Respackopts.save();
|
Respackopts.save();
|
||||||
|
Respackopts.load();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasMetadata(ResourcePackProfile v, String fname) {
|
private boolean hasMetadata(ResourcePackProfile v, String fname) {
|
||||||
|
@ -2,5 +2,6 @@
|
|||||||
"respackopts.loadFailed": "Failed to load resourcepacks",
|
"respackopts.loadFailed": "Failed to load resourcepacks",
|
||||||
"respackopts.loadError": "There is an issue with the resourcepack configs. Please take a look at the game log",
|
"respackopts.loadError": "There is an issue with the resourcepack configs. Please take a look at the game log",
|
||||||
"respackopts.configure": "Configure",
|
"respackopts.configure": "Configure",
|
||||||
"respackopts.mainconfig": "ResPack Opts"
|
"respackopts.mainconfig": "ResPack Opts",
|
||||||
|
"respackopts.invalid": "Invalider Wert"
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user