Compare commits

..
Author SHA1 Message Date
boubou19 701f55b5a5 Merge branch 'master' into glparser-util 2024-11-26 12:37:26 +01:00
kurrycat 5afb5d8f5a properly integrate mcpatcherforge connected textures + better grass (#745) 2024-11-25 21:38:01 +00:00
ah-OOG-ah c353c83cf3 Backport MemoryStack to reduce direct buffer allocations (#751)
* Initial MemoryStack backport

* Remove stubs, for now

Will re-add as needed

* Implement mallocInt

* Replace some buffer allocation

* Add mallocFloat

* Replace more uses of direct buffer allocation

* Reorder methods

Fixes a clinit crash and makes it easier to compare to upstream

* Remove another direct buffer creation
2024-11-25 16:26:07 -05:00
Martin Robertz 6563c7c0ce Merge branch 'master' into glparser-util 2024-11-25 22:03:00 +01:00
Darren Eberly 78072236d2 GLSL 120 Tweaks to Iris Shader Transformation (#743) 2024-11-24 01:04:30 -05:00
Darren Eberly 52dae51121 star imports 2024-11-23 02:16:55 -05:00
Darren Eberly b42eb9a6b2 Switch to static gl_functions csv 2024-11-23 02:16:24 -05:00
Darren Eberly 5925c28d29 star import 2024-11-23 01:33:57 -05:00
Darren Eberly fedabd0fb6 Add a GLParser utility for comparing GLSM to OpenGL Spec 2024-11-23 01:24:36 -05:00
Darren Eberly 350fdcd7e4 Fix for Extra Utilities ethereal blocks with connected textures (#746) 2024-11-22 03:22:14 +00:00
Darren Eberly 3d98e57178 Gracefully handle nested display list compilations in GLSM (#744) 2024-11-21 14:26:40 -08:00
Jason Mitchell 55c1786811 Update README.MD 2024-11-21 11:13:55 -08:00
Robert 356d826387 non silly pr title [ci skip] (#728) 2024-11-21 10:56:13 -08:00
Darren Eberly c34d8548a5 Item Renderer Optimization (#741) 2024-11-20 17:22:07 -05:00
Kotmatross 81a000af75 Backport F3 crosshair directions (#740)
* Backport F3 crosshair directions

* Remove render duplicate
2024-11-20 11:02:54 -05:00
ah-OOG-ahandkurrycat 711c23c722 Add frametime and TPS graphs (#739)
* Track frametimes

* impl rest of frametime graph, missing resize to not go over middle of screen when small

* only show fps graph with alt+f3 like in modern

* Add integrated server TPS reporting

---------

Co-authored-by: kurrycat <[email protected]>
2024-11-20 05:53:24 +00:00
Jason Mitchell 5aa1d504b0 Update README.MD 2024-11-18 00:12:04 -08:00
Jason Mitchell 60ab3b7900 Null check 2024-11-17 08:21:34 -08:00
Alexdoru 912e0e83b8 fix ArrayOutOfBounds in F3 debug text handler (#736) 2024-11-16 20:25:31 -08:00
Jason Mitchell 104eda0b51 Handle more incompatible mods (#735) 2024-11-16 19:23:39 +00:00
Alexdoruandkurrycat 7fb8cde66d Zoom (#724)
Co-authored-by: kurrycat <[email protected]>
2024-11-08 09:00:05 -08:00
kurrycat 0e4421f2ce fix wrong mixin remap values (#726) 2024-11-07 15:51:18 -08:00
Darren EberlyandAlexdoru 3cf3d096fd New Compat System for ASM Transformations + Immersive Engineering patches (#719)
Co-authored-by: Alexdoru <[email protected]>
2024-11-06 16:59:43 -08:00
Darren Eberly ffa1193dd2 Better ANTLR error handling for GLSL transformations (#715) 2024-11-01 17:40:34 -07:00
kurrycat d180023469 Fix entity render (#707) 2024-10-31 13:36:24 -07:00
Darren Eberly 762275a6da Cursor based positioning for shader setting tooltips (#711) 2024-10-31 16:31:33 -04:00
ah-OOG-ah 0e66bcf42f Fix inverted config (#710) 2024-10-31 19:59:17 +00:00
TotallyNotOndre 979ad344a1 Show tooltips for shader options (#705)
* Fix tooltiops

* Foolproof
2024-10-31 16:03:52 +00:00
Darren Eberly 5f328e9b57 Add ASM for handling field level tessellator usage, and also Stacks on Stacks compatibility (#703)
* Add new FieldLevelTessellator and StacksOnStacks ASM transformers

* star imports
2024-10-31 01:08:15 -04:00
Jason Mitchell 2dba62bf20 Update README.MD 2024-10-30 18:05:34 -07:00
kurrycat 0fd4d457e2 implement Iris ShadowRenderer 2024-10-30 14:42:16 -07:00
ah-OOG-ah b56e803622 Add a config to the total world time patch (#701)
* Add a config to the total world time patch

Shaders will still desync from time of day, but only when the (default off) setting is enabled.

* Namespace the configs
2024-10-30 12:47:10 -07:00
Caedis 3ab965ded7 Add realtime dynamic lights mode with no delay (#694)
Fancy changed to 50ms
Added config to force dynamic lights even when shaders are active
2024-10-30 14:45:03 -04:00
Jason Mitchell 538b38898c "Fix" world time.... (#693) 2024-10-29 20:22:24 -07:00
Jason Mitchell e43cd6f18e Update 000-report-bug.yml 2024-10-29 19:24:47 -07:00
Darren Eberly 38285087c9 Forcibly disable separateAo 2024-10-29 16:26:10 -07:00
Darren Eberly deb6c2b6e5 Add an IS_ANGELICA and ANGELICA_VERSION define for shaders 2024-10-29 16:24:48 -07:00
Darren Eberly e11985a913 Handle auto enablement of texture LOD extension for GLSL 120 (#684)
* Handle auto enablement of texture LOD extension for GLSL 120

* Add some more clear comments for random hacks

* Remove extraneous semicolon
2024-10-29 16:22:57 -07:00
Jason Mitchell 4bbf39eb4d null guard 2024-10-28 21:22:41 -07:00
Darren Eberly 8c90f79c17 Add reserved keywords and replace GLSLPreParser with regex (#683)
* Add reserved keywords and replace GLSLPreParser with regex

* Add a newline to the version directive in patched shader output

* Only process reserved keywords on GLSL < 400

* Better reserved keyword handling
2024-10-28 16:21:05 -07:00
kurrycat e4e657846d implement Iris HandRenderer (#681) 2024-10-28 16:20:00 -07:00
Darren Eberly 2dace708b4 Get frame start time properly for Iris (#682) 2024-10-28 11:12:57 -07:00
Darren Eberly 1df1ec3530 Conversion to glsl-transformation-lib (#680)
* Initial conversion to glsl-transformation-lib

* compatibility transformer

* Add taumc maven repo for glsl-transformation-lib

* Add credits for glsl-transformation-lib

* Remove extra storage drawers dependency

* Enable shaders by default

* Update issue templates
2024-10-27 21:17:29 -07:00
kurrycat d96ac28043 fix destroy block animation like 1.12 (#679) 2024-10-26 16:48:39 -07:00
kurrycat 72c13cff67 add correct pipeline phase on block destroy animation 2024-10-26 16:44:18 -07:00
kurrycat f233ba65e3 add syncProgram call to glDrawElements + glBegin 2024-10-26 13:47:26 -07:00
kurrycat c0d636d4f7 fix entities being rendered completely black 2024-10-26 12:10:52 -07:00
RecursivePineappleandDarren Eberly bd5cd350c3 Replace BlockError mixin with event handler (#671)
* Replace BlockError mixin with event handler

Something is calling TextureMap.registerIcons before preInit() sets up
the BlockError reference. While adding a null check to the mixin would
also fix this, a mixin isn't needed here since forge exposes an event
for this purpose.

* Add client sideonly for texture stitch event

---------

Co-authored-by: Darren Eberly <[email protected]>
2024-10-22 16:33:11 -04:00
kurrycat 88936d3713 fix horizon rendering before camera transform (#669) 2024-10-21 16:31:44 -04:00
Darren Eberly cf5bf2e2e7 Handle logging of ISBRH exception and multiple exception types 2024-10-21 10:44:52 -07:00
chochem cfd2388c85 add minimal tooltips 2024-10-20 09:47:40 -07:00
Darren Eberly fd78f63f12 Handle FMLRenderAccessLibrary obfuscation properly (#663)
* Handle FMLRenderAccessLibrary obfuscation properly

* Add a comment explaining jankness
2024-10-16 22:35:12 -04:00
AlexdoruandJason Mitchell 6cf119dfee Dynamically modify the render distance for dropped items entities to preserve performance (#653)
* change sodium EntityMixin to use modify arg instead of @inject that cancels all the time

* restore the 16 block render distance for dropped items

* set EntityItem render distance to 32 blocks

* dynamically reduce the render distance for dropped Item entities when there is too many

* Add dropped item limit setting to video settings

Add some missing notfine tooltip entries while I was in there

* set maximum of dropped items to 2048

---------

Co-authored-by: Jason Mitchell <[email protected]>
2024-10-16 08:55:03 -07:00
embeddedtandJason Mitchell 8c5f4d2543 Replace chunk tracker (#661)
* Replace chunk tracker

---------

Co-authored-by: Jason Mitchell <[email protected]>
2024-10-15 22:17:33 -04:00
Caedis 9e1fa7b80f Remove compat with original release of BG2 (#652) 2024-10-14 05:12:12 +00:00
Darren Eberly 6c99872459 Add an error block, and render it in case of NPE in ISBRH (#658)
* Catch and ignore NPE during ISBRH rendering

* Make a fake ErrorBlock

* working block for rendering with no registration

* More suitable texture for BlockError
2024-10-13 14:59:49 -07:00
Jason Mitchell f0809410ee Update 000-report-bug.yml 2024-10-13 10:47:39 -07:00
Jason Mitchell 98299b69d2 Update 000-report-bug.yml 2024-10-13 10:47:00 -07:00
Jason Mitchell fed0aa77c5 Update 000-report-bug.yml 2024-10-13 10:46:23 -07:00
Jason Mitchell f7fb3186c8 Revert back to old behavior
* RFB Plugin loads earlier and can run in both obf and deobf
2024-10-09 18:12:49 -07:00
Alexdoru ab243bb936 fix obfuscation error from last commit D: (#648) 2024-10-09 22:45:03 +02:00
Alexdoru 60cce7ea1d Deal with obfuscation properly (#645)
* make one method to dump the classes instead of copy pasting 6 times

* deal with obfuscation properly in ASM transformers instead of brute forcing both obfuscated and clear names

* remove sorting index on AngelicaTweaker to avoid confusion

* use static final variables for the class names with "."
2024-10-09 08:07:22 -07:00
Alexdoru b837b0571d fix strikethrough line being off by one 2024-10-08 09:47:20 -07:00
Alexdoru 7abc6213f5 only init NotFine's obfuscation helper if at least one transformer is loaded 2024-10-03 15:34:41 -07:00
Alexdoru b46643ae8c use GTNHLib ASMUtil to dump the class files + always dump in dev env 2024-10-03 15:34:41 -07:00
Gleaseandah-OOG-ah e3d1fedd48 replace MixinBlockLiquid with non-mixin implementation (#642)
* replace MixinBlockLiquid with non-mixin implementation

* Update GTNHLib

---------

Co-authored-by: ah-OOG-ah <[email protected]>
2024-09-29 19:25:53 +00:00
Caedis ebcee499eb Fancy Dynamic Lights is now default (#629) 2024-09-08 15:31:51 -05:00
PlayfulPiano ad26b1ad6f Update README.MD - add more links for compatibility (#626)
No links were listed for a couple mod version incompatibilities. they're now listed.
2024-09-04 16:32:45 +00:00
Safixo 73338e3c3e Fix cull state leaking sometimes (#614) 2024-09-02 13:50:53 -07:00
mist475 2c89244fbe Archaicfix branding fix (#621)
* move angelica branding text up if archaicfix is present
2024-09-02 13:50:10 -07:00
Jason Mitchell 991f658819 Add GLSM to transformer exclusions (#612) 2024-08-25 16:51:33 -07:00
ah-OOG-ah 1588c7000d Remove model loading from Angelica (#610) 2024-08-21 08:18:58 -07:00
NealDeal34andMartin Robertz 260d57e308 Update zh_CN.lang (#565)
* Update zh_CN.lang

* Update zh_CN.lang

* Update zh_CN.lang

* Update zh_CN.lang

---------

Co-authored-by: Martin Robertz <[email protected]>
2024-08-17 17:05:00 +02:00
Caedis 3a1d1b03b3 [Dynamic Lights] Add Baubles Support (#595)
* [Dynamic Lights] Add Baubles Support

* Add IDynamicLightProducer
2024-08-15 10:25:06 -07:00
cutiegin 66563f41c8 Update ru_RU.lang (#593)
* Update ru_RU.lang
2024-08-07 07:50:22 -07:00
Unicornbl00d a52adb9190 Make shaders automatically work with modded leaves using the ore dictionary tag treeLeaves if the shader calls for minecraft:leaves 2024-08-06 18:13:07 -07:00
Jason Mitchell 1c6f9aa131 Bump gtnhlib dep 2024-08-06 17:57:02 -07:00
czerwonogrodzki 8c584fed05 Update README.MD 2024-08-05 07:36:05 -07:00
Jason Mitchell 558ea0fe12 Moves CapturingTesselator, JSON Models, and misc utility classes to GTNHlib (#587)
* Moves CapturingTesselator, JSON Models, and misc utility classes to GTNHlib
* Switch to separate source set for mixins - faster incremental builds
2024-08-04 15:41:58 -07:00
Darren EberlyandCaedis 1315d8971a More AO Fixes (#578)
* Only use sodium AO for standard blocks and disable flat pipeline optimization

* Option for sodium smooth lighting. Currently default to true

* Remove tessellator ignore from renderQuadList

* Add back cull and sodium lighting check in renderQuadList

* Disable sodium AO by default

* fix culling

---------

Co-authored-by: Caedis <[email protected]>
2024-08-02 23:51:30 +07:00
Caedis e33f2ff7e3 Fix sodium smooth dynamic lights (#577) 2024-07-31 16:13:15 -04:00
Darren Eberly 29072ee3f8 Ambient Occlusion Fixes (#575)
* Disable broken optimizations for Sodium AO

* Use Sodium AO by default for standard block rendering
2024-07-30 22:31:27 -04:00
Rad ff8315270b Update pl_PL.lang (#564)
* Update pl_PL.lang

* Update pl_PL.lang (NotFine)
2024-07-30 16:37:55 +00:00
Darren Eberly 54f276a460 More GLSM Lighting and Material work (#569)
* Initial glMaterial work
* Explicitly reset material state during enable bit test
2024-07-25 00:42:27 +00:00
Darren Eberly feef745722 Support for glColorMaterial and glLightModel in GLSM (#556)
* Support for glColorMaterial and glLightModel in GLSM

* Tests for light model

* Tests for glColorMaterial
2024-07-23 22:26:23 -07:00
ah-OOG-ahandJason Mitchell 88cb3faf47 Merge beta JSON loading API (#567)
* Remove ARR assets

* Refactor leaf mixins

* Refactor asset loading

Introduces a resource reload in POSTINIT, just before loading models

* Move lectern model to template

* Unlink test blocks and injected QuadProviders

Now they can be enabled or disabled separately

* Replace log renderer

* Fix JSON model culling

* Actually fix culling this time

* Update NdQuadBuilder.java

* Remove unused method

* Support tris

Hasn't been tested

* Pull QuadBuilder into an API

* Move Variant and Loader to API

* Glass QP and minor FluidRenderer improvement

* Rename Loader

* Move injected QuadProviders to a field

This way they don't get inherited

* Prioritize 7.10 textures over modern

* Use JSON models for vanilla logs

* Add a rewind method

This doesn't fix the problem, but it looks interesting, maybe it's closer?

* Fix texture loading

* Reenable rewinding

* FRAPI AO builds

Still useless tho

* Super broken, but maybe salvageable?

* Revert "Super broken, but maybe salvageable?"

This reverts commit ef4352f0d82f93039547bacdd38bddca65193743.

* Revert "FRAPI AO builds"

This reverts commit 7a4fd800831f973ea25c6a3c2b088afcf224770f.

* Cleanroom Mojang's rewinder

* Not-really-working-rewinding

* Mark JSON API as beta

* Ew, star imports

* Update gtnh gradle

* Update dependencies.gradle

* Update dependencies.gradle

---------

Co-authored-by: Jason Mitchell <[email protected]>
2024-07-23 19:17:59 -07:00
Caedis f477675ee9 HUD Caching Early Return (#562)
* Initial logic

* Cleanup

* change to 1 parameter + hashset

* handle methods that return a bool or int

* move some stuff around

* clean up

* update

* delete that

* update .gitignore

* Add null check

* update gitignore

* Simplify ASM injection

* Rework ASM logic

* switch to MixinClassWriter

* update

* change folder name

* cleanup hook
2024-07-21 10:05:58 -05:00
Rad 4294059fbe Create pl_PL.lang + minor README improvements (#560)
* Slight Readme.md improvements

* Create pl_PL.lang
2024-07-20 11:21:23 -07:00
Caedis e40c9f2441 Fix Thaumic Horizons Lens Selector (#561)
* Fix line endings

* Fix Lens Selector Rendering
2024-07-20 11:08:20 -07:00
Caedis 52e886adcc Fix Thaumcraft foci rendering (#559)
* remove redundent @Getter

* Fix slow thaumcraft rendering

* swap to @Getter

* Revert "swap to @Getter"

This reverts commit 92f216a0db.

* fix getter
2024-07-18 22:33:46 -07:00
Jason Mitchell f38fcd1d82 Update MixinCompatHackTweaker.java 2024-07-16 21:33:21 -07:00
Jason Mitchell fbebbd4049 Also disable Better FPS (#558) 2024-07-16 21:00:21 -07:00
cutiegin 03a0406199 Create ru_RU.lang (#552)
* russian translation
2024-07-15 10:05:43 -07:00
Jason Mitchell 1ef691ecc8 Beta Release - Shaders sneak preview (Don't submit issues yet)
Beta Release - Shaders sneak preview (Don't submit issues yet)
Latest set of shader fixes and other improvements
2024-07-14 23:24:03 -07:00
Jason Mitchell b242a13fd6 Update README.MD 2024-07-14 23:17:12 -07:00
2274bfabfd Beta (#461)
* Beta, maybe
* Fixes for entityColor uniform in Iris
* Handle Iris Texture input hook properly in GLSM
* Iris Entity Fixes
* Gbuffer progress
* Wire up BlockEntity gbuffer
* Move Entity gbuffer to a more appropriate place to avoid reentrancy
* Wire up ENTITY_EYES and BEACOM_BEAM
* Clean up unused RenderStateShard files
* This seems marginally more correct?
* Fix shadows from showing on sides of blocks
* Remove overlay
* yeet
* More gl debugging
* Grr, fix water textures
* Add missed enable checks
* Workaround for unset depth texture when using apitrace...
   Use a WrapOperation instead of an Inject with local capture - it wasn't working in dev w/ mixin debug set
* update bs
* Fix crosshair rendering with shaders
* more final
* Disable dynamic lights if shaders are in use
* No light when in water
* Add Void Particle Option + Mixin cleanup
* update bs
* less false

---------

Co-authored-by: Darren Eberly <[email protected]>
Co-authored-by: Caedis <[email protected]>
2024-07-14 23:09:03 -07:00
ev chang 7e4292bdba Add HUDCaching FPS (from PolyPatcher) 2024-07-12 10:49:07 -07:00
Darren Eberly f79e112700 More GLSM Lighting Fixes (#554) 2024-07-11 15:16:15 -04:00
Darren Eberly ba46feb20b GLSM Lighting (#553) 2024-07-11 11:10:04 -04:00
Jason Mitchell 33804c67da Use gtnhlib for coordinate packing/unpacking (#550) 2024-07-07 22:48:58 -07:00
Caedis 3c9353e143 Update dynamic lights from beta branch (#534)
* move dynamic lights lang to angelica

* No light when in water

* update bs

* add battlegear2 compat

Can't add backhand compat since it shares api package path with
battlegear2 (mods/battlegear2/api/core/BattlegearUtils)

* Add backhand 1.4.1+ support
2024-06-26 05:39:26 -07:00
JL2210 77eb3ad46a Fix NPE from MineFactory Reloaded during lag spikes (#522)
* Fix NPE from MineFactory Reloaded during lag spikes

This is an ARR mod and hence cannot be forked.
I decided to put the fix here rather than e.g. Hodgepodge as this is only an
issue with Angelica and seems to be due to its thread safety patches.

* Rewrite as injector

IDE go brr
2024-06-24 17:45:37 -07:00
FalsePattern 8a56ab8ca1 fixed crash with EndlessIDs when joining a multiplayer server 2024-06-09 21:24:26 +08:00
Dakotah fe065803aa THIS ADDS FEATURE REQUEST ISSUE TO GITHUB (#514)
* Add feature request template

* Add feature request template

* Add labels to feature request template automatically

* switch labels to enhancement
2024-05-30 16:30:09 -07:00
ah-OOG-ah f94268c384 Add null check to FluidRenderer (#513)
* Add null check to FluidRenderer

* Update FluidRenderer.java
2024-05-30 17:56:32 -04:00
jss2a98aj f7a8b0f3bf Cloud scaling, distance, and some fixes 2024-05-24 22:16:41 -07:00
embeddedt 8893cf2291 Mark chunk graph as dirty when FOV changes (#506) 2024-05-24 15:59:46 -04:00
Jason Mitchell adc575c5ab remaps 2024-05-23 20:00:21 -07:00
Jason Mitchell 35a056b73b Patches vanilla getFlowDirection to not crash with a ClassCastException if another mod implements their own fluid renderer and calls getFlowDirection when COFH ASM is loaded 2024-05-23 20:00:21 -07:00
jss2a98aj fbbb0ed4f2 Various cleanup (IJK -> XYZ etc) 2024-05-23 19:49:49 -07:00
jss2a98aj bc148ba09c Updated file overlooked in previous sync 2024-05-23 19:49:49 -07:00
jss2a98aj 1db3932af0 Roll ITileOverride into TileOverride 2024-05-23 19:49:49 -07:00
jss2a98aj 0fd4611a97 Refactor glass pane mixins to solve compat issues 2024-05-23 19:49:49 -07:00
jss2a98aj 27243991b7 Add near fog distance percentage slider
Initial commit by MellowArpeggiation and George Paton
FOG_NEAR to FOG_NEAR_DISTANCE, minimum of 1% by jss2a98aj
2024-05-23 19:49:49 -07:00
jss2a98aj 956eec0366 Face culling for the Enchantment Table 2024-05-23 19:49:49 -07:00
jss2a98aj 9b06c5a210 Add interpolated icon support (Roadhog360) 2024-05-23 19:49:49 -07:00
jss2a98aj 5511759b6d Fix door smooth lighting, cull sides against solid blocks 2024-05-23 19:49:49 -07:00
jss2a98aj fb5aa81e01 Sandstone connected textures 2024-05-23 19:49:49 -07:00
jss2a98aj 6592e13e02 Improve Bookshelf connected textures 2024-05-23 19:49:49 -07:00
Jason Mitchell 31174dc35a Update README.MD 2024-05-23 17:57:46 -07:00
Caedis f0bd9de081 Disable Dynamic Lights video option when module is disabled (#491) 2024-05-17 20:18:23 +00:00
Jason Mitchell 75617a5456 More null checks 2024-05-14 23:23:01 -07:00
Jason Mitchell e158faada0 Only set/access texture info cache from the main thread 2024-05-14 22:35:21 -07:00
Raven Szewczyk f684bc0a1b Fix RenderBlockFluid reading the block type from the world access multiple times (#482)
* Fix RenderBlockFluid reading the block type from the world access multiple times

* Fix compiler warnings
2024-05-13 18:04:58 +01:00
Jason Mitchell 3d56b1c2fc Make TextureInfoCache safer 2024-05-12 09:35:43 -07:00
Jason Mitchell 6e60f671b5 Neuter FML optifine detection/reporting 2024-05-11 10:33:45 -07:00
Caedis 323d2e726c Adjust dynamic lights in World#getLightBrightnessForSkyBlocks as well (#466)
This can be called when rendering is done on the main there as
WorldSlice is only used outside the main thread.
2024-05-06 08:50:25 -07:00
88d5030aa9 Add Dynamic Lights to Alpha (Module Off, Lights Off) (#465)
If a player is reading this and wants dynamic lights during alpha, please enable the module in the angelica-modules config file then the config option in the video settings will take effect.

* Implement Dynamic Lights (#360)

* inital dynamicLights

* continue work

* Add credit

* More implementations

* "Working"

* NotFine 0.2.2 sync (#462)

* Slight cleanup in ColorizeBlock

* Don't call System.gc

* Add toggle for Renderpass (forced to false)

* Dont rebuild the same chunk 8 times

* Use client pos

* Fully working + configs

* Clean up

* Fix readme and gradle properties

* Fix tooltip

* nit changes

---------

Co-authored-by: jss2a98aj <[email protected]>

* Might help if the dynamic lights mixins follow the config setting

* Fix shadows from showing on sides of blocks

* Set dynamic lights module to off for alpha

* Add missed enable checks

---------

Co-authored-by: jss2a98aj <[email protected]>
Co-authored-by: Jason Mitchell <[email protected]>
2024-05-06 00:19:50 +00:00
jss2a98aj 894b9573db Natura + Tinker's Construct berry bush leaf mode support 2024-05-05 13:42:36 -07:00
jss2a98aj d8d8cd93c5 Leaf render mode edge case handling 2024-05-05 13:42:36 -07:00
jss2a98aj 986f1bd6a1 NotFine 0.2.2 sync (#462)
* Slight cleanup in ColorizeBlock

* Don't call System.gc

* Add toggle for Renderpass (forced to false)
2024-05-03 23:54:02 -04:00
jss2a98aj e85ca85027 Small NotFine style settings menu fix (#457)
* Fix allowToggle3DAnaglyph

* Remove unused import
2024-05-01 07:26:18 -07:00
Raven Szewczyk d96023f36c Fix FontRenderer intel issue (#456) 2024-04-30 17:55:03 +00:00
Jason Mitchell 203b552993 Attempt at BetterCrashes Compat
- clean up the CapturingTessellator
- clean up GLStateManager
2024-04-29 10:50:56 -07:00
Jason Mitchell 96e2f42251 Update Mixins.java (#447)
Move some Notfine guarded mixins to enableMCPatcherForgeFeatures
2024-04-28 15:06:23 -07:00
Raven Szewczyk 9a73dc9bfd Fix glMultMatrix using the wrong variable for multiplication (#444)
* Fix glMultMatrix using the wrong variable for multiplication

* Fix "conersion" typo
2024-04-27 18:46:35 +00:00
Darren Eberly f01cdfda4b Thread safe ISBRH compatibility with Extra Utilities 2 (#439)
* Initial ASM stuff for Extra Utils thread safety

* Thread safety for connected textures

* More thread-safe blocks

* Remove EU2 references, combine ASM transformers

* Remove unusued ModStatus check for Extra Utils
2024-04-25 12:56:24 -07:00
Caedis daa1405ba4 Only disable holoinventory when hudcaching is enabled 2024-04-25 08:14:24 -07:00
jss2a98aj 846d70f0c0 Fix NotFine Twilight Forest compat mixins builder 2024-04-19 11:35:56 -07:00
jss2a98aj e59e41bfdb Sync NotFine
Could scale and render distance NYI
2024-04-19 07:56:08 -07:00
George PatonandGeorge Paton eb8a826419 Fix render distance being capped at 20 (#428)
* Fix render distance being capped at 20 in singleplayer

* Clean up imports

---------

Co-authored-by: George Paton <[email protected]>
2024-04-19 12:58:33 +00:00
boubou19 efe7c16c50 remove donations as author has nothing to do with angelica 2024-04-17 12:49:21 +02:00
wahfl2 c4b4b79f6c Add more methods present in modern MatrixStack 2024-04-11 09:37:54 -07:00
Caedis 2e5ce0abdb Check if hudcaching is enabled before removing xaeros ASM (#419) 2024-04-10 19:36:49 -07:00
Caedis d317b05f5b Fix flickering of Xaero's Map Waypoints (#418)
* update bs

* Fix Xaero's Waypoints
2024-04-10 16:05:45 +00:00
Jason Mitchell cc51a464f1 Remove duplicate unimixins dependency 2024-04-04 10:23:50 -07:00
makamys 3e6aa461c6 Fix crash when Sodium is disabled 2024-03-27 09:06:48 -07:00
Moses Miller d236689e6a Allow the user to select more gui scales (#399) 2024-03-25 09:19:35 -07:00
Caedis d15bbb56ee Add void fog option (default false) (#398) 2024-03-24 19:48:09 -07:00
Jason Mitchell f4355bd4c4 More readable 2024-03-23 21:14:11 -07:00
makamys 5dbd244d72 Readme tweaks (#391)
* [skip ci] Add logo to readme

* [skip ci] README: add CurseForge and Modrinth links
2024-03-20 16:48:06 -07:00
Jason Mitchell 367c82a225 [ci skip] Add CF/MN project info 2024-03-18 08:19:07 -07:00
Jason Mitchell 852bcbb38b Check before casting.
Fixes https://github.com/GTNewHorizons/Angelica/issues/388
2024-03-16 11:24:38 -07:00
ah-OOG-ah 464af945b2 Fix AIOBE in debug screen and NPE on world join (#385)
* Fix AIIOBE

* Fix NPE

* Actually fix
2024-03-15 21:42:38 -04:00
makamys 996b3df9cb Use vanilla field to count number of chunk updates
Fixes D-Tools compat
2024-03-15 15:23:48 -07:00
makamys 22d28abce6 Use ByteBuffer overload when indirect buffer is in client memory
Fixes #373
2024-03-15 15:23:37 -07:00
Jason Mitchell 636b616f64 Stop blacklisting bartworks. (#369)
Needs https://github.com/GTNewHorizons/bartworks/commit/50dfbb44acdd28bc183dc58b9cd40d5ba5121685
2024-03-09 09:27:22 -08:00
Caedis 14b7178419 Initialize toggle keybind when registering (#366)
* Initialize toggle keybind when registering

* Add comment
2024-03-08 15:26:36 -08:00
Caedis 22bf48c093 Potential fix for splash screen crashes (#363)
* Move framebuffer static initializor to getter

* missed one

* Revert "missed one"

This reverts commit 97027c1372.

* Revert "Move framebuffer static initializor to getter"

This reverts commit 6ef65735ff.

* Initialize HudCaching on world join

* run it on the client only

* remove unused imports
2024-03-08 12:40:51 -06:00
Caedis 4600bca2d0 Mixin to override FOV multiplier instead of using the forge event (#361)
* Mixin to speed check instead of using fov event

* scratch that, override return value entirely

* Revert "scratch that, override return value entirely"

This reverts commit 20a379d766.

* Revert "Mixin to speed check instead of using fov event"

This reverts commit 22db36d677.

* Change to lowest priority event so it is ran last (hopefully)
2024-03-08 10:26:34 -06:00
Jason Mitchell fcb9536d93 Don't blacklist gregtech from the render thread (#356) 2024-03-03 15:20:04 -08:00
embeddedt 51a6a72ae5 Only track rendered sprites on specific RenderBlocks instances (#355)
* Only track rendered sprites on specific RenderBlocks instances
2024-03-03 10:10:47 -08:00
Jason Mitchell f41f27e706 Some misbehaving mods *cough GT5u cough* enjoy reallocating textures all the time, so try a normal hash set instead of a reference one... 2024-03-03 09:26:33 -08:00
ah-OOG-ah 346a305f1d Refactor Quad, BlockPos, and QuadProvider API
Also optimize static models
2024-02-29 21:17:46 -05:00
ah-OOG-ah da8f700068 Update LICENSE 2024-02-29 21:17:46 -05:00
ah-OOG-ah f2445fabba Minor patches + license rewording 2024-02-29 21:17:46 -05:00
makamys bc3ca5209f Clean up tags
Also fixes names of enum compound tags missing
2024-02-29 21:17:46 -05:00
makamys 00517079d2 Fix broken links 2024-02-29 21:17:46 -05:00
makamys 7b8a64ec94 Move model-spec.md to docs dir 2024-02-29 21:17:46 -05:00
ah-OOG-ah 794e59b6de Readd CapturingTesselator workaround 2024-02-29 21:17:46 -05:00
ah-OOG-ah 9710801cb1 Fix underwater lighting on QuadProviders 2024-02-29 21:17:46 -05:00
ah-OOG-ah c5bda3b19c Update JsonModel.java 2024-02-29 21:17:46 -05:00
ah-OOG-ah f9678a3793 Batch colorizing 2024-02-29 21:17:46 -05:00
ah-OOG-ah 091290b218 Clean all the things 2024-02-29 21:17:46 -05:00
ah-OOG-ah d991b55af7 Update ClientProxy.java 2024-02-29 21:17:46 -05:00
ah-OOG-ah 1530a8f6fe Clean up CubeModel 2024-02-29 21:17:46 -05:00
ah-OOG-ah 98156191fe Update Loader.java 2024-02-29 21:17:46 -05:00
ah-OOG-ah 956914efa3 Delete ModelHelper.java 2024-02-29 21:17:46 -05:00
ah-OOG-ah 51c3beea9e The purge continues 2024-02-29 21:17:46 -05:00
ah-OOG-ah 657ff921de Fix sided lighting on copied quads 2024-02-29 21:17:46 -05:00
ah-OOG-ah c9539faf44 Update JsonModel.java 2024-02-29 21:17:46 -05:00
ah-OOG-ah 2ca4d5338f Purge FRAPI code
Also use a baked stone model and fix a stupid in JSON
2024-02-29 21:17:46 -05:00
ah-OOG-ah 236a513705 FRAPI materials + NdQuadBuilder performance
Also speed up the offThreadSafety map
2024-02-29 21:17:46 -05:00
ah-OOG-ah 6d49e82a0c Revert "Set aside JSON model code for now"
This reverts commit 31fdf3383195b65a00e999a5634ed3ead8f060b2.
2024-02-29 21:17:46 -05:00
ah-OOG-ah 2fea614a45 Revert "Remove unready code, for now"
This reverts commit b626e3fa8f83013e5b4a68e787ffed9b75d8a679.
2024-02-29 21:17:46 -05:00
ah-OOG-ah 85ed121158 Remove unready code, for now 2024-02-29 21:17:46 -05:00
ah-OOG-ah 9316f42808 Set aside JSON model code for now
Item models my behated
2024-02-29 21:17:46 -05:00
ah-OOG-ah 74b66746eb Dual-license the model package for Fabric 2024-02-29 21:17:46 -05:00
ah-OOG-ah 5abeb9709e Credit FRAPI 2024-02-29 21:17:46 -05:00
ah-OOG-ah 5ec50f22d9 Remove Fabric license headers 2024-02-29 21:17:46 -05:00
ah-OOG-ah dfe3a4220b Add convenience methods 2024-02-29 21:17:46 -05:00
ah-OOG-ah 1e1e95f249 Variant handling 2024-02-29 21:17:46 -05:00
ah-OOG-ah 02b0d1b728 Update JsonModel.java
This fixes things and I don't know why
2024-02-29 21:17:46 -05:00
ah-OOG-ah 9c81c96bb3 Dang, BlockState is hard
YEET
2024-02-29 21:17:46 -05:00
ah-OOG-ah fff5b2cb01 Implement initial BlockState API 2024-02-29 21:17:46 -05:00
ah-OOG-ah 77f1e9b5a2 Support element rotation 2024-02-29 21:17:46 -05:00
ah-OOG-ah 3158a33a65 Texture loading 2024-02-29 21:17:46 -05:00
ah-OOG-ah f6f840235e Does everything but textures 2024-02-29 21:17:46 -05:00
ah-OOG-ah 793f668ef8 Copyright-clear model parsing 2024-02-29 21:17:46 -05:00
Jason Mitchell da01393799 Try an Int2ObjectMap instead of an ObjectList 2024-02-28 23:02:02 -08:00
Jason Mitchell 3030be32f4 Apparently some mods rely on ForgeHooksClient.getWorldRenderPass() (#347)
* Apparently some mods rely on ForgeHooksClient.getWorldRenderPass()
2024-02-28 19:00:26 +00:00
Caedis dbdeba9865 Up required gtnhlib version to 0.2.9 (#340)
* Update README.MD

* Update AngelicaMod.java
2024-02-27 16:49:23 +00:00
Caedis 80ff6af14e Replace config with gtnhlib's config (#337)
* Remove own config

* update bs + deps

* update gtnhlib

* Replace config with gtnhlib's config
2024-02-27 08:37:17 -08:00
Jason Mitchell c34290d182 Ignore the iris/mcpf configs, hardcode angelica-modules.cfg filename 2024-02-26 12:57:47 -08:00
Jason Mitchell 6e3235a985 Gate some advanced/beta features behind java properties 2024-02-26 10:31:54 -08:00
Caedis 419fa9f0c0 Add Dynamic FOV toggle (#331) 2024-02-26 09:19:32 -08:00
Raven Szewczyk c996e5e58c Use a RFB plugin for GLSM transforms when available (#329) 2024-02-25 12:58:19 -08:00
mts2200 6d28df74a6 Fix #320 (#325)
* Fix https://github.com/GTNewHorizons/Angelica/issues/320

* Fix tests on AMD
2024-02-25 01:00:32 -08:00
Jason Mitchell ce97ef876d Switch up the signature to take ints instead of a blockpos and stop allocating one (#324) 2024-02-21 21:29:56 -08:00
Jason Mitchell 8898a6f252 Switcharoo on detecting ThreadSafeISBRHFactory... (#318)
other method apparently wasn't working
2024-02-20 22:17:00 -08:00
Jason Mitchell 37f638ac34 scheduleRebuildOffThread (#316)
* scheduleRebuildOffThread
2024-02-20 08:58:03 -08:00
Jason Mitchell f73c698a5a Don't crash wit invalid lightquality/particalmode options 2024-02-17 22:46:31 -08:00
Jason Mitchell 029da0e7fa Fix glLoadMatrix and add a test for it
Fixes https://github.com/GTNewHorizons/Angelica/issues/299
2024-02-17 18:15:58 -08:00
Darren Eberly e40ee19ac8 Move JOML dependency to GTNHLib (#301)
* Move JOML dependency to GTNHLib

* Update GTNHLib version in README
2024-02-15 10:51:44 -08:00
jss2a98aj 33832fe547 Sync with NotFine (#296)
* Sync with NotFine

* Fix mistake in package name

* Re-separate stars mode and stars total settings
2024-02-15 10:20:13 -08:00
Jason Mitchell 671a776952 Test Matrix operations (#295)
* Test Matrix operations
2024-02-13 23:20:01 -08:00
Matthew William Noel 445b6a3e68 Partially fix entity shaders (#294)
* Partially fix entity shaders
2024-02-13 20:57:44 +00:00
Jason Mitchell ff65370cc5 Blacklist bartworks from the main thread (#286)
Fixes #181
2024-02-12 22:34:24 -08:00
Jason MitchellandCaedis ff290c19e2 GLSM Tests & AMD Driver Workaround (#290)
* Store graphics vendor
* AMD driver workarounds

* Test TRANSFORM_BIT

* Test GL_TEXTURE_BIT
* Fix handling of bound textures on glDeleteTextures

* Switch up the LOGGER in RenderSystem so we don't trigger a Forge Configuration load; AMD driver default matrix mode workaround

* Switch BatchingFontRenderer to use the gl methods via GLSM to better respect cache bypassing
Fix a few instances of GLSM not respecting the bypass

* Start with "runningSplash" true always to disable the cache until loaded into the world

---------

Co-authored-by: Caedis <[email protected]>
2024-02-12 22:33:23 -08:00
Jason Mitchell d1e505308c Ask for graphics card vendor on bugs 2024-02-12 08:36:24 -08:00
Caedis 594799103b Exclude AMD in testPushPopEnableBit 2024-02-11 20:01:53 -08:00
Jason Mitchell 8a65f471a0 Make getBlockType and getBlockMetadata atomic
* Sidesteps/fixes a race condition in the WIP carpenter block thread safe ISBRH implementation
2024-02-11 19:29:17 -08:00
Jason Mitchellandembeddedt d52e2b0454 Do not return null results in translucency sort task if not cancelled (#284)
* Do not return null results in translucency sort task if not cancelled

Co-authored-by: embeddedt <[email protected]>
2024-02-11 22:55:16 +00:00
Raven Szewczyk 9b31bae1c8 Log more information in the no-result task exception (#283) 2024-02-11 22:12:05 +00:00
Ginsway 7cbb905bd7 Update Chinese translation (#261)
* 固有的

* 自己翻译的

* Update src/main/resources/assets/angelica/lang/zh_CN.lang
2024-02-11 13:32:18 -08:00
Jason Mitchell 8a50ed036d More GLSM Tests (#282)
* Properly Cache GL_SHADE_MODEL and make it a stack

* Add opengl_32_core to docs, so we can easily see what is needed to be deprecated/emulated
Add some stub functions to be fleshed out later
2024-02-11 12:13:51 -08:00
Jason Mitchell f1394382ab Make note of required versions of mods if present 2024-02-11 10:45:20 -08:00
Raven Szewczyk 74e6c80aad A few buildscript and test tweaks (#281)
* Kotlin buildscript for better IDE integration

* Fix transitive Bauble dep, move CoreTweaks to a fake-ivy dependency

* Don't scan fullscreen modes for window creation

* Update GTNHGradle
2024-02-11 05:24:08 -08:00
ah-OOG-ah da9d6bad56 Fix typo in issue template (#280) 2024-02-10 20:57:40 -08:00
Jason Mitchell 58a6fabf3c Enough with the bug reports about disabled features 2024-02-10 20:51:18 -08:00
Jason MitchellandDarren Eberly f8c11967d1 Glsm tests (#275)
* Tests for GL_DEPTH_BUFFER_BIT
* Swizzle DepthState.mask ~> enabled
* Use AssertAll so we can clearly see gl/glsm state differences
* Reset test state leakage from ColorBufferBit
* Add start of test for GL_CURRENT_BIT
* Initial basic display list tests
* Print mismatched array index for array comparisions
* Add message for all tests
* Test GL_CURRENT_BIT
* Implement GLSM stub functions
* Test GL_ENABLE_BIT
* Add verifyNotDefaultState when we don't care about the values, just that they're not the default
* GL_MULTISAMPLE seems to be broken on Nvidia
* Test GL_FOG_BIT
* Check glGetError() after every test
* Exclude some tests based on vendor
* Test most of GL_LIGHTING_BIT

---------

Co-authored-by: Darren Eberly <[email protected]>
2024-02-10 16:51:12 -08:00
Jason Mitchell 6d1c4bf39c Revert "fix release workaround"
This reverts commit 018a47e400.
2024-02-10 09:43:48 -08:00
Jason Mitchell 018a47e400 fix release workaround 2024-02-09 17:53:26 -08:00
ah-OOG-ahandmakamys 509017551a Initial QuadProvider API (#256)
* Initial model testing

* Fix UV

* More quad work

* Update BlockRenderer.java

* QuadProvider renders right!

* Clean up

* Update CubeModel.java

* Initial colorization work

* (Badly) color grass

Unbreaks vanilla blocks

* Leaves are easier

* Add separate AO back

* Relocate to Angelica

* Cleanup + pool quads

* Add TODOs for future reference

* Update LightDataAccess.java

* Replace code comment with TODO

* Update WorldSlice.java

Co-authored-by: makamys <[email protected]>

* Default quads to UP

* Only coerce facing in Quad#getFace

Mirrors 1.16's face handling more accurately.
Fixes face culling not working properly for blocks like tall grass

* Iterate over unaligned quads too

* Don't cull unaligned faces

* Release QP quads

---------

Co-authored-by: makamys <[email protected]>
2024-02-09 17:41:15 -08:00
Jason Mitchell cf454f287c GLSM Improvements (#272)
* GLSM Improvements
* Add an IntegerStateStack
* Use IntegerStateStack to track the active texture unit
* Track activeTextureUnit with GL_TEXTURE_BIT
* Bugfix - Don't include color with GL_COLOR_BUFFER_BIT
* Fully test glPush/PopAttrib for GL_COLOR_BUFFER_BIT
* Split GLStateManager init into two pieces
2024-02-09 17:35:58 -08:00
Darren Eberly 0e3e4283af Compat with NotEnoughIDs 16-bit Metadata (#271)
* Compat with NotEnoughIDs 16-bit Metadata

* Less bad(maybe) version parsing
2024-02-09 00:33:42 -05:00
Bogdan 8176e1cd1c Don't put excessive buffer size (#267) 2024-02-04 13:57:04 -08:00
ah-OOG-ah d2cba7c321 Update settings.gradle (#268) 2024-02-04 13:56:22 -08:00
Raven Szewczyk f791b0dab3 [ci skip] upgraded build system 2024-02-04 19:56:28 +00:00
Jason Mitchell 5093531811 Cleanup 2024-02-03 16:04:19 -08:00
Jason Mitchellandmakamys c942df386a OpenGL State Debugging (#262)
* OpenGL State Debugging
* Add OpenGLDebugging
* Enhance GLSM to be aware of single vs multiple return values for glGet

* Capacity vs Remaining (needs NPE saftey?)
Int -> float
glLoadMatrix

* Update src/main/java/com/gtnewhorizons/angelica/glsm/debug/OpenGLDebugging.java

Co-authored-by: makamys <[email protected]>

* Update src/main/java/com/gtnewhorizons/angelica/glsm/debug/OpenGLDebugging.java

Co-authored-by: makamys <[email protected]>

* tweaks

* Fixes
* Have checkGLSM compare matricies differently than other things
* Each Texture Unit has it's own TextureMatrix stack
* Switch to a ClientTickEvent and directly query the Keyboard so we can run the checkGLSM in GUIs and other places
* Remove default keybind

* Don't trigger quite so often

---------

Co-authored-by: makamys <[email protected]>
2024-02-03 15:00:21 -08:00
mist475 1d24789362 Minor cleanup (#264)
* add missing remap = false

* deobfParams

* applyDecompilerCleanupToMain
2024-02-03 09:13:40 -08:00
Jason Mitchell b8b445322c Fix some missing state for push/pop attrib (#260)
* Fix some missing state for push/pop attrib

* Add Color as well
2024-02-02 11:19:26 -08:00
Jason Mitchell 38c72b7af0 Bypass getting anything from the GLSM cache until after world load, but ensure we set everything. 2024-02-02 09:19:25 -08:00
Jason Mitchell 466b0544e3 Add a Vector3dStack - Fix nested translations being stored 2024-02-02 09:19:12 -08:00
Jason Mitchell 26da0c2b64 Update buildscript 2024-02-01 08:04:51 -08:00
Jason Mitchell 8c3ac9e310 null check (#255) 2024-01-31 21:30:59 -08:00
Jason Mitchellandmakamys 6a7c2520d0 Opt in thread saftey (#254)
* Evolution of thread safe ISBRH
* Add API package

Co-authored-by: makamys <[email protected]>
2024-01-31 16:53:45 -08:00
makamys a0d782a1a5 Add dependency hints (#253)
* Crash with a helpful error if FastUtil is missing

* Add UniMixins dep to readme
2024-01-31 08:22:22 -08:00
makamys aebaab8d6f Make RedirectorTransformer handle block subclasses correctly (#249)
Fixes #248
2024-01-30 11:47:28 -08:00
Matthew William Noel 05158317e8 Fix PBR (#252) 2024-01-30 11:46:53 -08:00
embeddedt 4d39c90ba6 Only return null if job is explicitly cancelled (#251) 2024-01-30 09:27:58 -08:00
Jason Mitchell 83cf0801ef Remaining instead of capacity 2024-01-29 08:00:14 -08:00
jss2a98aj db49a613a0 Fix leaf rendering issue (#247)
* Fix and simplify leaf code

* Add SettingsManager.graphicsUpdated() call

Fixes an additional leaf rendering issue and some other things.
2024-01-28 14:18:30 -08:00
Jason Mitchell 64087f53c5 This wasn't supposed to be private 🤦 (#246) 2024-01-28 09:26:51 -08:00
Jason Mitchell efb039ff38 Remove unused option 2024-01-27 16:26:46 -08:00
Jason Mitchell 388929cc0c Fewer Allocations (#243) 2024-01-27 16:17:06 -08:00
Jason Mitchell 6691511e17 More Caching (#242)
* More Caching
* Pull TextureTracker & TextureInfoCache out of Iris and into GLSM
* Cache more TextureInfo state
* GLSM: glTexParameter, glGetTexParameter(i|f), glGetTexLevelParameteri
* Move IrisRenderSystem -> GLSM.RenderSystem
* Ensure DSA works properly with GLSM
 * Further updates to DSA for texParameter/getTexParameter
* A few more cached fields for TextureInfo
* Properly handle deleteTextures
* Ensure anyone crazy enough to use an Int/FloatBuffer for single value params get redirected
* Add optional runtime disabling of GLSM
* Switch checkGLError from an inject to a redirect, hopefully fewer allocations
* Fewer allocations for clearBufferState
* Microoptimization for (setup|clear)BufferState
2024-01-27 15:52:57 -08:00
Michael Zhao b956a44857 fix texture state leak in BatchedFontRenderer (#240) 2024-01-27 14:27:01 -08:00
Jason Mitchell 8863826d0e More aggressive caching (#239)
* More aggressive caching
2024-01-27 10:19:37 -08:00
Pistonight 65d9bf8f2f copy depth buffer from MC for HUD caching 2024-01-26 10:34:46 -08:00
Jason Mitchell 3ee82e7157 OpenGL Debugging
* Move GLDebug and gl capabilitiesinto angelica/glsm instead of Iris
* Wire up GLDebug.pushGroup && popGroup via mixins if lwjgl debug is enabled (useful for api trace)
2024-01-24 20:33:09 -08:00
Pistonight 3b61bb74a2 fix hud caching alpha handling and boss health 2024-01-24 07:59:54 -08:00
Jason Mitchell f378b6e7ba VBO related Tweaks (#227)
* Expose original translation for tesselator, so we can reset it after doing VBO stuff

other small VBO cleanup

* Properly manage the tessellator's state...
2024-01-23 07:54:30 -08:00
Jason Mitchellandmakamys aff05e1812 Add Reese's Sodium Options (#219)
* Add Reese's Sodium Options

Co-authored-by: makamys <[email protected]>
2024-01-21 15:54:03 -08:00
Jason Mitchell 806bcf2d6b Config updates (#225)
* Make in game config for Angelica work
* Backport https://github.com/embeddedt/embeddium/commit/7476bf9b13fcb9a302722b350ef4e6e7d2b8a8c8 to rename angelica-options.json
2024-01-21 13:47:45 -08:00
makamys 3755e2595f Fix campfire backport animations (#224)
* Mark animations of crossed squares

Fixes Angelica's equivalent of https://github.com/GTNewHorizons/Hodgepodge/issues/264
Fixes Campfire Backport campfire flames not animating (but the embers and the
mixed NEI flames are still broken)

* Add Campfire Backport compatibility to animation speedup

Fixes Angelica's equivalent of https://github.com/GTNewHorizons/Hodgepodge/issues/204
Fixes embers and NEI mixed flames not animating
2024-01-21 09:12:30 -08:00
makamys 0d79f5e193 Make NotFine's sky toggle more granular (#222)
Separated "Sky" toggle into "Sky", "Sun & Moon", and "Stars", like in OptiFine.
This also fixes NF's sky toggle turning off MCPF's skybox
2024-01-21 08:33:10 -08:00
Jason Mitchellandmakamys 9210cd3283 ArchaicFix compat (#220)
* ArchaicFix compat

Fixes https://github.com/GTNewHorizons/Angelica/issues/216

* Update src/main/java/com/gtnewhorizons/angelica/mixins/TargetedMod.java

Co-authored-by: makamys <[email protected]>

---------

Co-authored-by: makamys <[email protected]>
2024-01-20 17:19:57 -08:00
makamys 733ffff81f Redirect negative display list calls to VBOs globally (fixes Smart Moving) (#217)
* Redirect negative display list calls to VBOs globally

Fixes Smart Moving not rendering player models

* Remove now redundant glCallList redirects

* Make VertexBuffer keep track of its own draw mode
2024-01-20 12:21:33 -08:00
Michael Zhao 32e2efc1e5 fix hud caching vignette and crosshair color issues (#212) 2024-01-20 10:17:48 -08:00
bombcar d9a688f1d8 fix runclient17 (#211) 2024-01-19 16:43:15 +00:00
Jason Mitchell ba66a0602b Update README.MD - No BetterFPS 2024-01-18 20:00:41 -08:00
Jason Mitchell d53a85e013 Remove silly early initial implementation and fix star VBO (#206)
* Remove silly early initial implementation and fix star VBO
2024-01-18 22:55:52 +00:00
mist475 5f6c418315 disable sodium weather quality redirect if dynamic surroundings is present as it overwrites the entire method (#200) 2024-01-16 09:29:22 -08:00
jss2a98aj 15569aadc7 Enable NotFine leaf modes when enableNotFineFeatures is true (#194)
* Use NotFine leaf modes if enableNotFineFeatures

* Sync NotFine langs
2024-01-15 15:23:44 -08:00
Jason Mitchell 0f97c09fda Render all Wavefront objects as VBO (#192)
* Tris actually seem to work w/ thaumcraft
2024-01-14 14:57:47 -08:00
Jason Mitchell fd43fbd9c9 Update README.MD 2024-01-14 10:12:04 -08:00
embeddedt 2b4ea9fd96 Don't activate item textures if there is no client world (#189) 2024-01-13 21:30:36 -08:00
tth05andJason Mitchell 1837dcec72 Replace fastutil dependency with GTNHLib (#187)
* Replace fastutil dependency with GTNHLib

* Add gtnhlib to mod dependencies

---------

Co-authored-by: Jason Mitchell <[email protected]>
2024-01-14 01:48:32 +00:00
Cyl18 84e1fa284b fix some of iris problems (#183) 2024-01-13 16:29:25 -08:00
Jason Mitchell c211d90faf Off thread safe blocks (#177)
* Whitelist carpentersblocks for off main thread rendering

* Add bounds checking to WorldSlice,

* Add preliminary `IThreadSafeISBRH` support

* Update TODO

* Adjust min y

* remove unnecessary try/catch

* * Keep track of what should be rendered on the main thread
* Update AngelicaBlockSafetyRegistry to handle vanilla blocks, and ISBHR's

* of -> set
2024-01-12 18:31:01 -08:00
Jason Mitchell 537eb06b66 Respect animation speedup config (#180) 2024-01-11 08:05:26 -08:00
Darren Eberly 93b03847df Only use BatchedFontRenderer when not in a display list compilation (#174) 2024-01-09 09:28:31 -05:00
Darren EberlyandJason Mitchell 85e44369bb Handle state changes for display lists correctly in GLSM (#168)
* Handle state changes in display lists correctly in GLSM

* Add some documentation so it's slightly more clear as to what's happening

---------

Co-authored-by: Jason Mitchell <[email protected]>
2024-01-08 21:48:15 +00:00
Raven Szewczyk fbc1b1b440 [ci skip] upgraded build system 2024-01-08 21:23:33 +00:00
embeddedt 97152a6ace Clear event phase before reusing object (#170) 2024-01-08 16:11:35 -05:00
makamysandJason Mitchell 3cde764d33 Update BS (#165)
* Update BS

Ran `updateBuildscript` and manually copied in the new `settings.gradle`

* Update build.gradle

---------

Co-authored-by: Jason Mitchell <[email protected]>
2024-01-08 03:25:38 +00:00
Jason Mitchell 45b20efc45 Change where the offset is reset (#159)
* Change where the offset is reset
* Debug log and rm dead code
2024-01-07 18:58:48 -08:00
769 changed files with 23818 additions and 12088 deletions

No files matched your search

+42 -8
View File
@@ -18,6 +18,14 @@ body:
placeholder: "Example: 1.0.0-alpha1"
validations:
required: true
- type: textarea
id: report
attributes:
label: Bug Report
description: "Relevant information, as well as relevant logs attached such as `logs/fml-client-latest.log."
placeholder: "Example: https://mclo.gs/ OR submit the file to github by dragging it to this textbox."
validations:
required: true
- type: dropdown
id: java
attributes:
@@ -34,12 +42,39 @@ body:
- Other (Please Specify)
validations:
required: true
- type: textarea
id: report
- type: dropdown
id: graphics
attributes:
label: Bug Report
description: "Relevant information, as well as relevant logs attached such as `logs/fml-client-latest.log."
placeholder: "Example: https://mclo.gs/ OR submit the file to github by dragging it to this textbox."
label: Graphics Card Vendor
description: What graphics card vendor are you using?
options:
- Other (Please Specify)
- NVidia
- AMD/ATI
- Intel iGPU
- AMD iGPU
- Mesa/Software
validations:
required: true
- type: dropdown
id: shaders
attributes:
label: Shaders
description: Do you have a shaderpack enabled?
options:
- "No"
- "Yes: Please put relevant information about shaderpack in the report(what shaderpack, any special settings of note, etc)"
validations:
required: true
- type: dropdown
id: mcpf
attributes:
label: MCPF or other features disabled by default
description: Do you have MCPF or any other features that are disabled by default enabled?
options:
- "No: Go ahead and create an issue"
- "Yes: I will not create an issue"
- "Yes: I don't read and shouldn't be creating an issue"
validations:
required: true
- type: textarea
@@ -62,6 +97,5 @@ body:
required: true
- label: "I am running an officially released version. (Or, if I've compiled it myself I plan to fix the issue)"
required: true
- label: "This issue is not shader related (they aren't ready yet for testing)"
required: true
@@ -0,0 +1,33 @@
name: Feature Request
description: "Request a feature."
labels: ["enhancement"]
body:
- type: markdown
attributes:
value: "Please use this form to request features. We ask you check if it was already requested though"
- type: input
id: discord
attributes:
label: Your GTNH Discord Username
description: Leave empty if you don't have one, but this will make it harder to contact you if we need additional info.
placeholder: "Example: Wumpus#1234"
- type: textarea
id: request
attributes:
label: Feature Request
description: "Relevant information, as well as relevant images"
placeholder: "Example: https://mclo.gs/ OR submit the file to github by dragging it to this textbox."
validations:
required: true
- type: checkboxes
id: final
attributes:
label: Final Checklist
description: Certify that you read things
options:
- label: "I have searched the issues and haven't found a similar issue."
required: true
- label: "I have read the known incompatibilities and this is not related to one of those."
required: true
- label: "This issue is not related to a feature that is disabed by default - MCPF, etc. [They'll be enabled when they're ready for testing]"
required: true
+8
View File
@@ -1,6 +1,7 @@
.gradle
.settings
/.idea/
/.vs/
/.vscode/
/run/
/build/
@@ -30,3 +31,10 @@ src/main/resources/mixins.*([!.]).json
*.bat
*.DS_Store
!gradlew.bat
layout.json
addon.local.gradle
addon.local.gradle.kts
addon.late.local.gradle
addon.late.local.gradle.kts
/*.csv
!gl_functions.csv
+47 -15
View File
@@ -1,26 +1,46 @@
# Angelica
# Angelica<img src="img/logo-readme.png" align="right">
<sup>**[CurseForge](https://www.curseforge.com/minecraft/mc-mods/angelica) | [Modrinth](https://modrinth.com/mod/angelica)**</sup>
* The little Angle [sic] that supports shaders while saving your fps from a certain death -boubou
* Is it obtuse, or accute? -Caedis
* It's a cute angle -mitchej123
* It's the angel that pulls you out of OptiFine's hell -Roadhog360
**Alpha Quality - Here there be Dragons**
## **Beta Quality - Here there be Dragons**
* Shaders sneak preview - Please don't report issues yet, but please do submit fixes
* Complementary & BSL mostly function, but have some bugs
* Sildurs, Seus, and any other shader probably doesn't work
# Required Dependencies
* [UniMixins](https://github.com/LegacyModdingMC/UniMixins/releases) >= 0.1.14
* [GTNHLib](https://github.com/GTNewHorizons/GTNHLib/releases) >= 0.4.2
* NOTE: Some mods are not required, but a specific version is required if present - see: `Permanent Incompatibilities` below.
# Known (temporary) Incompatibilities
* Forge Relocation - Currently non Thread Safe; safe if not in use
* ProjectRed Frames - Currently non Thread Safe; safe if not in use
* EndlessIDs - Future compat planned
* FalseTweaks - Future compat planned
* SmoothFont - Future compat planned
* RPLE - Future compat planned
* ProjectRed Frames - Currently non Thread Safe; safe if not in use'
# Potential Incompatibilities
* EndlessIDs - Compat commits have been made, might work, might not - not fully tested
# Known Incompatibilities
* FalseTweaks - Not currently planned (Looking for volunteers) [Might work if you effectively disable most of the mod]
* SmoothFont - Not currently planned (Looking for volunteers)
* RPLE - Not currently planned (Looking for volunteers)
# Permanent Incompatibilities
* Optifine [Disabled, won't fix]
* Fastcraft [Disable, won't fix]
* LWJGL3ify 1.5.4 and below - Use the latest version available, 1.5.7+
* ArchaicFix 0.6.2 and below - Use 0.7.0 or above
* Hodgepodge 2.4.3 and below - [Use 2.4.4 or above](https://github.com/GTNewHorizons/Hodgepodge/releases)
* CodeChicken[Core](https://github.com/GTNewHorizons/CodeChickenCore/releases)/[Lib](https://github.com/GTNewHorizons/CodeChickenLib/releases) <1.2.0 - Threading issues, use 1.2.0+
* Neodymium - Untested, but unlikely to be compatible. (Chunk Meshing is definitely incompatible, other features might work depending on config)
* OptiFine [Disabled, won't fix]
* FastCraft [Disabled, won't fix]
* BetterFPS [Disabled, won't fix]
* OptimizationsAndTweaks [Disabled, won't fix]
* [Amazing Trophies 1.2.1 and below](https://github.com/GTNewHorizons/Amazing-Trophies/releases) - use 1.2.2+
* [LWJGL3ify 1.5.4 and below](https://github.com/GTNewHorizons/lwjgl3ify/releases/) - Use the latest version available, 1.5.7+
* [ArchaicFix 0.6.2 and below](https://www.curseforge.com/minecraft/mc-mods/archaicfix/files/all?page=1&pageSize=20) - Use 0.7.0 or above
* [Hodgepodge 2.4.3 and below](https://github.com/GTNewHorizons/Hodgepodge/releases) - Use 0.4.5 or above
* CodeChicken[Core](https://github.com/GTNewHorizons/CodeChickenCore/releases)/[Lib](https://github.com/GTNewHorizons/CodeChickenLib/releases) <1.2.0 - Threading issues, use 1.3.0+
* Neodymium - Untested, but unlikely to be compatible. (Chunk Meshing is definitely incompatible, other features might work depending on config)
# Credits
* ShadersMod
@@ -38,6 +58,8 @@
* Sodium
* JellySquid & the CaffeineMC team, for making Sodium in the first place
* Embeddedt for [Embeddium](https://github.com/embeddedt/embeddium/tree/dc59ca357c25beefd6288f0d1d40b4cd8e670ab8) under the [LGPL 3.0](https://github.com/embeddedt/embeddium/blob/16.x/forge/LICENSE)
* Reese's Sodium Options
* FlashyReese for [Reese's Sodium Options](https://github.com/FlashyReese/reeses-sodium-options/tree/aa4ea67047cf53e54976e93c6bb1ab5ba16b142b) under the [MIT license](https://github.com/FlashyReese/reeses-sodium-options/blob/aa4ea67047cf53e54976e93c6bb1ab5ba16b142b/LICENSE.txt)
* Neodymium
* Makamys for [Neodymium](https://github.com/makamys/Neodymium) - Various Tessellator -> Quad functionality taken under the LGPL 3
* MCPatcherForge
@@ -46,7 +68,17 @@
* HUDCaching
* Created by [Moulberry](https://github.com/Moulberry/MCHUDCaching), backported from [Patcher](https://github.com/Sk1erLLC/Patcher) mod by Alexdoru under the CC-BY-SA-NC 4.0 license
* Angelica
* mitchej123, Omni, Makamys, Embeddedt, NanoLive, Caedis, Cardinalstar, Alexdoru, Eigenraven, mist475, Clepto for helping get Angelica up and running!
* mitchej123, Omni, Makamys, Embeddedt, NanoLive, Caedis, Cardinalstar, Alexdoru, Eigenraven, mist475, Clepto, kurrycat for helping get Angelica up and running!
* IMS, jss2a98aj, || dbp ||, roadhog360 for advice and moral support
* Forge 1.12+
* Some files have been taken from Minecraft Forge under the LGPL 2.1 license and are marked as such
* FRAPI and Indigo
* Model building API heavily inspired by/copied from Fabric's; upstream may use it under the original Apache 2.0
license, see LICENSE in `com.gtnewhorizons.angelica.models`
* Dynamic Lights
* LambdAurora for [LambDynamicLights](https://github.com/LambdAurora/LambDynamicLights) under the MIT license, and the Forge port anthxnymc for [DynamicLightsReforged](https://github.com/anthxnymc/DynamicLightsReforged), also under the MIT license
* Embeddedt and Ferri_Arnus for [glsl-transformation-lib](https://github.com/TauMC/glsl-transformation-lib)
* Also for work on [Monocle](https://github.com/ferriarnus/Monocle) which was used as a reference for implementing glsl-transformation-lib
* Code from both glsl-transformation-lib and Monocle taken under their respective LGPL 3.0 licenses
* FalseTweaks
* FalsePattern for [FalseTweaks](https://github.com/falsepattern/falsetweaks) - Item Rendering Optimizations taken from FalseTweaks under the LGPL 3.0 license
-7
View File
@@ -1,7 +0,0 @@
allprojects {
gradle.projectsEvaluated {
tasks.withType(JavaCompile) {
options.compilerArgs << "-Xmaxerrs" << "2000"
}
}
}
-1605
View File
File diff suppressed because it is too large. Load diff
+33
View File
@@ -0,0 +1,33 @@
plugins {
id("com.gtnewhorizons.gtnhconvention")
}
minecraft {
extraRunJvmArguments.add("-Dangelica.enableTestBlocks=true")
}
tasks.test {
useJUnitPlatform()
testLogging {
events("passed", "skipped", "failed")
}
javaLauncher = javaToolchains.launcherFor {
languageVersion = JavaLanguageVersion.of(8)
}
dependsOn(tasks.extractNatives2)
jvmArgs("-Djava.library.path=${tasks.extractNatives2.get().destinationFolder.asFile.get().path}")
}
tasks.processResources {
inputs.property("version", project.version.toString())
filesMatching("META-INF/rfb-plugin/*") {
expand("version" to project.version.toString())
}
}
tasks.register<Copy>("copyDependencies") {
group = "Angelica"
description = "Collect dependencies into the testDependencies folder"
from(configurations.default)
into("testDependencies")
}
+44 -17
View File
@@ -49,47 +49,74 @@ configurations {
}
dependencies {
compileOnly("com.github.GTNewHorizons:Hodgepodge:2.4.4")
compileOnly("com.github.GTNewHorizons:Hodgepodge:2.5.78")
compileOnly("org.projectlombok:lombok:1.18.22") {transitive = false }
compileOnly("com.gtnewhorizons.retrofuturabootstrap:RetroFuturaBootstrap:0.4.0") { transitive = false }
compileOnly("org.projectlombok:lombok:1.18.22") { transitive = false }
annotationProcessor("org.projectlombok:lombok:1.18.22")
// Use modern models+textures to inject QuadProviders
devOnlyNonPublishable('com.github.GTNewHorizons:TX-Loader:1.7.2:dev')
// Iris Shaders
compileOnly('org.jetbrains:annotations:24.0.1')
shadowImplementation("it.unimi.dsi:fastutil:8.2.1") // Apache 2.0
shadowImplementation("org.joml:joml:1.10.5") // MIT
api("com.github.GTNewHorizons:GTNHLib:0.5.20:dev")
shadowImplementation("org.anarres:jcpp:1.4.14") // Apache 2.0
implementation("io.github.douira:glsl-transformer:1.0.0")
shadowImplementation("io.github.douira:glsl-transformer:1.0.0") { // glsl-transformer Noncommercial License 1.0.0
shadowImplementation("org.taumc:glsl-transformation-lib:0.2.0-4.g6b42bca") {
exclude module: "antlr4" // we only want to shadow the runtime module
}
shadowImplementation("org.antlr:antlr4-runtime:4.13.2")
compileOnly "org.apache.ant:ant:1.8.2"
// Because who doesn't want NEI
compileOnly('com.github.GTNewHorizons:NotEnoughItems:2.4.9-GTNH:dev')
compileOnly('com.github.GTNewHorizons:CodeChickenCore:1.2.0:dev')
devOnlyNonPublishable('com.github.GTNewHorizons:NotEnoughItems:2.6.45-GTNH:dev')
devOnlyNonPublishable('com.github.GTNewHorizons:CodeChickenCore:1.3.10:dev')
// Notfine Deps
compileOnly("thaumcraft:Thaumcraft:1.7.10-4.2.3.5:dev")
runtimeOnly("com.github.GTNewHorizons:Baubles:1.0.1.16:dev")
compileOnly("com.github.GTNewHorizons:twilightforest:2.5.1:dev") {transitive = false }
devOnlyNonPublishable("com.github.GTNewHorizons:Baubles:1.0.4:dev")
compileOnly("com.github.GTNewHorizons:twilightforest:2.6.35:dev") { transitive = false }
compileOnly(rfg.deobf('curse.maven:witchery-69673:2234410'))
compileOnly("com.github.GTNewHorizons:TinkersConstruct:1.12.14-GTNH:dev") { transitive = false }
compileOnly("com.github.GTNewHorizons:Natura:2.7.5:dev")
compileOnly("com.falsepattern:chunkapi-mc1.7.10:0.5.0:api")
compileOnly("com.falsepattern:endlessids-mc1.7.10:1.5-beta0002:dev")
compileOnly("com.github.GTNewHorizons:ThaumicHorizons:1.6.4:dev")
compileOnly("com.github.GTNewHorizons:Battlegear2:1.4.1:dev") { transitive = false }
compileOnly(rfg.deobf('maven.modrinth:backhand:1.4.1')) { transitive = false }
compileOnly("com.falsepattern:chunkapi-mc1.7.10:0.5.1:api") { transitive = false }
compileOnly("com.falsepattern:endlessids-mc1.7.10:1.5-beta0003:dev") { transitive = false }
compileOnly(rfg.deobf("curse.maven:extrautils-225561:2264383"))
compileOnly(rfg.deobf("curse.maven:dynamiclights-227874:2337326"))
compileOnly("com.github.GTNewHorizons:NotEnoughIds:1.5.3:dev") // Mixin Version
compileOnly("curse.maven:minefactory-reloaded-66672:2277486")
compileOnly("com.github.GTNewHorizons:NotEnoughIds:2.1.6:dev") // Mixin Version
compileOnly("com.github.GTNewHorizons:NotEnoughIds-Legacy:1.4.7:dev") // ASM Version
compileOnly("com.github.GTNewHorizons:Jabba:1.3.1:dev")
// HMMMMM
compileOnly(rfg.deobf("curse.maven:journeymap-32274:2367915"))
compileOnly(rfg.deobf("curse.maven:campfirebackport-387444:4611675"))
compileOnly(rfg.deobf("curse.maven:xaeros-minimap-263420:5060684"))
runtimeOnly(deobf("https://github.com/makamys/CoreTweaks/releases/download/0.3.3.2/CoreTweaks-1.7.10-0.3.3.2+nomixin.jar"))
compileOnly("com.github.GTNewHorizons:HoloInventory:2.4.13-GTNH:dev")
runtimeOnlyNonPublishable(rfg.deobf("CoreTweaks:CoreTweaks:0.3.3.2"))
// Hodgepodge
transformedMod("net.industrial-craft:industrialcraft-2:2.2.828-experimental:dev")
// Better Crashes
compileOnly("com.github.GTNewHorizons:BetterCrashes:1.4.0-GTNH:dev")
// Tests
testImplementation(platform('org.junit:junit-bom:5.9.2'))
testImplementation('org.junit.jupiter:junit-jupiter')
testImplementation("org.mockito:mockito-core:3.+")
testImplementation("org.lwjgl.lwjgl:lwjgl:2.9.4-nightly-20150209")
devOnlyNonPublishable("com.github.javaparser:javaparser-symbol-solver-core:3.26.2") {
exclude module: "guava"
}
}
+34
View File
@@ -0,0 +1,34 @@
# A specification for models
This is borrowed from [the unofficial Minecraft wiki](https://minecraft.wiki/w/Tutorials/Models) under the CC BY-NC-SA 3.0.
The folder `assets/<namespace>/models/block` holds the model files for all the specified variants. The names of the files can be changed, but must always correspond with the names used in the variant files.
* `[TAG_compound]` The root tag
* `[TAG_string]` **parent**: Loads a different model from the given path, in form of a [resource location](https://minecraft.wiki/w/Tutorials/Models#File_path). If both `"parent"` and `"elements"` are set, the `"elements"` tag overrides the `"elements"` tag from the previous model.
* Can be set to `"builtin/generated"` to use a model that is created out of the specified icon. Note that only the first layer is supported, and rotation can be achieved only by using block states files.
* `[TAG_byte]` **ambientocclusion**: Whether to use [ambient occlusion](http://en.wikipedia.org/wiki/Ambient_occlusion) (`true` - default), or not (`false`). Note:only works on Parent file
* `[TAG_object]` **display**: Holds the different places where item models are displayed.
* `[TAG_compound]` ***Position***: Named `thirdperson_righthand`, `thirdperson_lefthand`, `firstperson_righthand`, `firstperson_lefthand`, `gui`, `head`, `ground`, or `fixed`. Place where an item model is displayed. Holds its rotation, translation and scale for the specified situation. '''fixed''' refers to item frames, while the rest are as their name states. Note that translations are applied to the model before rotations.
* `[TAG_list]` **rotation**: Specifies the rotation of the model according to the scheme `[x, y, z]`.
* `[TAG_list]` **translation**: Specifies the position of the model according to the scheme `[x, y, z]`. The values are clamped between -80 and 80.
* `[TAG_list]` **scale**: Specifies the scale of the model according to the scheme `[x, y, z]`. If the value is greater than 4, it is displayed as 4.
* `[TAG_compound]` **textures**: Holds the textures of the model, in form of a [resource location](https://minecraft.wiki/w/Tutorials/Models#File_path) or can be another texture variable.
* `[TAG_string]` **particle**: What texture to load particles from. This texture is also used as an overlay if you are in a [nether portal](https://minecraft.wiki/w/Nether_portal), and used for [water](https://minecraft.wiki/w/water) and [lava](https://minecraft.wiki/w/Lava)'s still textures.<sup>[[1]](https://bugs.mojang.com/browse/MC-240042)</sup> This texture is also considered a texture variable that can be referenced as `"#particle"`. Note: All breaking particles from non-model blocks are hard-coded, such as for [barriers](https://minecraft.wiki/w/Barrier).
* `[TAG_string]` ***Texture variable***: Defines a texture variable with `name` and assigns it to a texture or another variable.
* `[TAG_list]` **elements**: Contains all the elements of the model. They can have only cubic forms. If both `"parent"` and `"elements"` are set, the `"elements"` tag overrides the `"elements"` tag from the previous model.
* `[TAG_compound]` An element.
* `[TAG_list]` **from**: Start point of a cuboid according to the scheme `[x, y, z]`. Values must be between -16 and 32.
* `[TAG_list]` **to**: Stop point of a cuboid according to the scheme `[x, y, z]`. Values must be between -16 and 32.
* `[TAG_compound]` **rotation**: Defines the rotation of an element.
* `[TAG_list]` **origin**: Sets the center of the rotation according to the scheme `[x, y, z]`.
* `[TAG_string]` **axis**: Specifies the direction of rotation, can be `"x"`, `"y"` or `"z"`.
* `[TAG_float]` **angle**: Specifies the angle of rotation. Can be 45 through -45 degrees in 22.5 degree increments.
* `[TAG_byte]` **rescale**: Specifies whether or not to scale the faces across the whole block. Can be true or false. Defaults to false.
* `[TAG_byte]` **shade**: Defines if shadows are rendered (`true` - default), not (`false`).
* `[TAG_compound]` **faces**: Holds all the faces of the cuboid. If a face is left out, it does not render.
* `[TAG_compound]` ***Face***: Named `down`, `up`, `north`, `south`, `west` or `east`. Contains the properties of the specified face.
* `[TAG_list]` **uv**: Defines the area of the texture to use according to the scheme `[x1, y1, x2, y2]`. The texture behavior is inconsistent if UV extends below 0 or above 16. If the numbers of `x1` and `x2` are swapped (e.g. from `0, 0, 16, 16` to `16, 0, 0, 16`), the texture flips. UV is optional, and if not supplied it automatically generates based on the element's position.
* `[TAG_string]` **texture**: Specifies the texture in form of the texture variable prepended with a `#`.
* `[TAG_string]` **cullface**: Specifies whether a face does not need to be rendered when there is a block touching it in the specified position. The position can be: `down`, `up`, `north`, `south`, `west`, or `east`. It also determines the side of the block to use the light level from for lighting the face, and if unset, defaults to the side.
* `[TAG_int]` **rotation**: Rotates the texture clockwise by the specified number of degrees. Can be 0, 90, 180, or 270. Defaults to 0. Rotation does not affect which part of the texture is used. Instead, it amounts to permutation of the selected texture vertexes (selected implicitly, or explicitly though `uv`).
* `[TAG_int]` **tintindex**: Determines whether to tint the texture using a hardcoded tint index. The default value, -1, indicates not to use the tint. Any other number is provided to BlockColors to get the tint value corresponding to that index. However, most blocks do not have a tint value defined (in which case white is used). Furthermore, no vanilla block currently uses multiple tint values, and thus the tint index value is ignored (as long as it is set to something other than -1); it could be used for modded blocks that need multiple distinct tint values in the same block though.
File diff suppressed because it is too large. Load diff
+2084
View File
File diff suppressed because it is too large. Load diff
+107 -52
View File
@@ -1,81 +1,109 @@
# ExampleMod tag to use as Blowdryer (Spotless, etc.) settings version, leave empty to disable.
# LOCAL to test local config updates.
gtnh.settings.blowdryerTag = 0.2.2
# Human-readable mod name, available for mcmod.info population.
modName = Angelica
# This is a case-sensitive string to identify your mod. Convention is to use lower case.
# Case-sensitive identifier string, available for mcmod.info population and used for automatic mixin JSON generation.
# Conventionally lowercase.
modId = angelica
# Root package of the mod, used to find various classes in other properties,
# mcmod.info substitution, enabling assertions in run tasks, etc.
modGroup = com.gtnewhorizons.angelica
# WHY is there no version field?
# The build script relies on git to provide a version via tags. It is super easy and will enable you to always know the
# code base or your binary. Check out this tutorial: https://blog.mattclemente.com/2017/10/13/versioning-with-git-tags/
# Whether to use modGroup as the maven publishing group.
# Due to a history of using JitPack, the default is com.github.GTNewHorizons for all mods.
useModGroupForPublishing = false
# Will update your build.gradle automatically whenever an update is available
# Updates your build.gradle and settings.gradle automatically whenever an update is available.
autoUpdateBuildScript = false
# Version of Minecraft to target
minecraftVersion = 1.7.10
# Version of Minecraft Forge to target
forgeVersion = 10.13.4.1614
# Specify a MCP channel and mappings version for dependency deobfuscation and the deobfParams task.
# Specify an MCP channel for dependency deobfuscation and the deobfParams task.
channel = stable
# Specify an MCP mappings version for dependency deobfuscation and the deobfParams task.
mappingsVersion = 12
# Define other MCP mappings for dependency deobfuscation
remoteMappings = https://raw.githubusercontent.com/MinecraftForge/FML/1.7.10/conf/
# Defines other MCP mappings for dependency deobfuscation.
remoteMappings = https\://raw.githubusercontent.com/MinecraftForge/FML/1.7.10/conf/
# Select a username for testing your mod with breakpoints. You may leave this empty for a random username each time you
# restart Minecraft in development. Choose this dependent on your mod:
# Do you need consistent player progressing (for example Thaumcraft)? -> Select a name
# Do you need to test how your custom blocks interacts with a player that is not the owner? -> leave name empty
# Select a default username for testing your mod. You can always override this per-run by running
# `./gradlew runClient --username=AnotherPlayer`, or configuring this command in your IDE.
developmentEnvironmentUserName = Developer
# Enables using modern java syntax (up to version 17) via Jabel, while still targetting JVM 8.
# Enables using modern Java syntax (up to version 17) via Jabel, while still targeting JVM 8.
# See https://github.com/bsideup/jabel for details on how this works.
enableModernJavaSyntax = true
# Enables injecting missing generics into the decompiled source code for a better coding experience
# Turns most publically visible List, Map, etc. into proper List<Type>, Map<K, V> types
# Enables injecting missing generics into the decompiled source code for a better coding experience.
# Turns most publicly visible List, Map, etc. into proper List<E>, Map<K, V> types.
enableGenericInjection = true
# Define a source file of your project with:
# public static final String VERSION = "GRADLETOKEN_VERSION";
# The string's content will be replaced with your mod's version when compiled. You should use this to specify your mod's
# version in @Mod([...], version = VERSION, [...])
# Leave these properties empty to skip individual token replacements
# Generate a class with a String field for the mod version named as defined below.
# If generateGradleTokenClass is empty or not missing, no such class will be generated.
# If gradleTokenVersion is empty or missing, the field will not be present in the class.
generateGradleTokenClass = com.gtnewhorizons.angelica.Tags
gradleTokenModId =
gradleTokenModName =
# Name of the token containing the project's current version to generate/replace.
gradleTokenVersion = VERSION
# [DEPRECATED] Mod ID replacement token.
gradleTokenModId =
# [DEPRECATED] Mod name replacement token.
gradleTokenModName =
# [DEPRECATED] Mod Group replacement token.
gradleTokenGroupName =
# [DEPRECATED]
# Multiple source files can be defined here by providing a comma-seperated list: Class1.java,Class2.java,Class3.java
# Multiple source files can be defined here by providing a comma-separated list: Class1.java,Class2.java,Class3.java
# public static final String VERSION = "GRADLETOKEN_VERSION";
# The string's content will be replaced with your mod's version when compiled. You should use this to specify your mod's
# version in @Mod([...], version = VERSION, [...])
# Leave these properties empty to skip individual token replacements
# version in @Mod([...], version = VERSION, [...]).
# Leave these properties empty to skip individual token replacements.
replaceGradleTokenInFile =
# In case your mod provides an API for other mods to implement you may declare its package here. Otherwise, you can
# leave this property empty.
# Example value: apiPackage = api + modGroup = com.myname.mymodid -> com.myname.mymodid.api
apiPackage =
# Example value: (apiPackage = api) + (modGroup = com.myname.mymodid) -> com.myname.mymodid.api
apiPackage = api
# Specify the configuration file for Forge's access transformers here. It must be placed into /src/main/resources/META-INF/
# There can be multiple files in a comma-separated list.
# Example value: mymodid_at.cfg,nei_at.cfg
# There can be multiple files in a space-separated list.
# Example value: mymodid_at.cfg nei_at.cfg
accessTransformersFile = angelica_at.cfg notfine_at.cfg archaicfix_at.cfg mcpatcherforge_at.cfg
# Provides setup for Mixins if enabled. If you don't know what mixins are: Keep it disabled!
usesMixins = true
# Adds some debug arguments like verbose output and export
# Set to a non-empty string to configure mixins in a separate source set under src/VALUE, instead of src/main.
# This can speed up compile times thanks to not running the mixin annotation processor on all input sources.
# Mixin classes will have access to "main" classes, but not the other way around.
separateMixinSourceSet = mixin
# Adds some debug arguments like verbose output and class export.
usesMixinDebug = false
# Specify the location of your implementation of IMixinConfigPlugin. Leave it empty otherwise.
mixinPlugin =
# Specify the package that contains all of your Mixins. You may only place Mixins in this package or the build will fail!
mixinsPackage = mixins
# Specify the core mod entry class if you use a core mod. This class must implement IFMLLoadingPlugin!
# This parameter is for legacy compatibility only
# Example value: coreModClass = asm.FMLPlugin + modGroup = com.myname.mymodid -> com.myname.mymodid.asm.FMLPlugin
# Example value: (coreModClass = asm.FMLPlugin) + (modGroup = com.myname.mymodid) -> com.myname.mymodid.asm.FMLPlugin
coreModClass = loading.AngelicaTweaker
# If your project is only a consolidation of mixins or a core mod and does NOT contain a 'normal' mod ( = some class
# that is annotated with @Mod) you want this to be true. When in doubt: leave it on false!
containsMixinsAndOrCoreModOnly = false
@@ -83,23 +111,39 @@ containsMixinsAndOrCoreModOnly = false
# Enables Mixins even if this mod doesn't use them, useful if one of the dependencies uses mixins.
forceEnableMixins = false
# If enabled, you may use 'shadowCompile' for dependencies. They will be integrated in your jar. It is your
# responsibility check the licence and request permission for distribution, if required.
# If enabled, you may use 'shadowCompile' for dependencies. They will be integrated into your jar. It is your
# responsibility to check the license and request permission for distribution if required.
usesShadowedDependencies = true
# If disabled, won't remove unused classes from shaded dependencies. Some libraries use reflection to access
# If disabled, won't remove unused classes from shadowed dependencies. Some libraries use reflection to access
# their own classes, making the minimization unreliable.
minimizeShadowedDependencies = true
# If disabled, won't rename the shadowed classes.
relocateShadowedDependencies = true
# Adds the GTNH maven, CurseMaven, IC2/Player maven, and some more well-known 1.7.10 repositories
# Adds CurseMaven, Modrinth, and some more well-known 1.7.10 repositories.
includeWellKnownRepositories = true
# Publishing to modrinth requires you to set the MODRINTH_TOKEN environment variable to your current modrinth API token.
# A list of repositories to exclude from the includeWellKnownRepositories setting. Should be a space separated
# list of strings, with the acceptable keys being(case does not matter):
# cursemaven
# modrinth
excludeWellKnownRepositories =
# Change these to your Maven coordinates if you want to publish to a custom Maven repository instead of the default GTNH Maven.
# Authenticate with the MAVEN_USER and MAVEN_PASSWORD environment variables.
# If you need a more complex setup disable maven publishing here and add a publishing repository to addon.gradle.
usesMavenPublishing = true
# Maven repository to publish the mod to.
# mavenPublishUrl = https\://nexus.gtnewhorizons.com/repository/releases/
# Publishing to Modrinth requires you to set the MODRINTH_TOKEN environment variable to your current Modrinth API token.
#
# The project's ID on Modrinth. Can be either the slug or the ID.
# Leave this empty if you don't want to publish on Modrinth.
modrinthProjectId =
# Leave this empty if you don't want to publish to Modrinth.
modrinthProjectId = angelica
# The project's relations on Modrinth. You can use this to refer to other projects on Modrinth.
# Syntax: scope1-type1:name1;scope2-type2:name2;...
@@ -108,41 +152,52 @@ modrinthProjectId =
# and the name is the Modrinth project or version slug/id of the other mod.
# Example: required-project:fplib;optional-project:gasstation;incompatible-project:gregtech
# Note: GTNH Mixins is automatically set as a required dependency if usesMixins = true
modrinthRelations =
modrinthRelations = required-project\:gtnhlib
# Publishing to CurseForge requires you to set the CURSEFORGE_TOKEN environment variable to one of your CurseForge API tokens.
#
# The project's numeric ID on CurseForge. You can find this in the About Project box.
# Leave this empty if you don't want to publish on CurseForge.
curseForgeProjectId =
curseForgeProjectId = 988067
# The project's relations on CurseForge. You can use this to refer to other projects on CurseForge.
# Syntax: type1:name1;type2:name2;...
# Where type can be one of [requiredDependency, embeddedLibrary, optionalDependency, tool, incompatible],
# and the name is the CurseForge project slug of the other mod.
# Example: requiredDependency:railcraft;embeddedLibrary:cofhlib;incompatible:buildcraft
# Note: GTNH Mixins is automatically set as a required dependency if usesMixins = true
curseForgeRelations =
# Note: UniMixins is automatically set as a required dependency if usesMixins = true.
curseForgeRelations = requiredDependency\:gtnhlib
# Optional parameter to customize the produced artifacts. Use this to preserver artifact naming when migrating older
# Optional parameter to customize the produced artifacts. Use this to preserve artifact naming when migrating older
# projects. New projects should not use this parameter.
# customArchiveBaseName =
# Optional parameter to prevent the source code from being published
# noPublishedSources =
# Optional parameter to have the build automatically fail if an illegal version is used.
# This can be useful if you e.g. only want to allow versions in the form of '1.1.xxx'.
# The check is ONLY performed if the version is a git tag.
# Note: the specified string must be escaped, so e.g. 1\\.1\\.\\d+ instead of 1\.1\.\d+
# versionPattern =
# Uncomment this to disable spotless checks
# Uncomment to prevent the source code from being published.
# noPublishedSources = true
# Uncomment this to disable Spotless checks.
# This should only be uncommented to keep it easier to sync with upstream/other forks.
# That is, if there is no other active fork/upstream, NEVER change this.
# Disabling to make easier to sync if some of the additional mods get any changes upstream
disableSpotless = true
# Override the IDEA build type. Valid value is "" (leave blank, do not override), "idea" (force use native IDEA build), "gradle"
# Uncomment this to disable Checkstyle checks (currently wildcard import check).
# disableCheckstyle = true
# Override the IDEA build type. Valid values are: "" (leave blank, do not override), "idea" (force use native IDEA build), "gradle"
# (force use delegated build).
# This is meant to be set in $HOME/.gradle/gradle.properties.
# e.g. add "systemProp.org.gradle.project.ideaOverrideBuildType=idea" will override the build type to be always native build.
# e.g. add "systemProp.org.gradle.project.ideaOverrideBuildType=idea" will override the build type to be native build.
# WARNING: If you do use this option, it will overwrite whatever you have in your existing projects. This might not be what you want!
# Usually there is no need to uncomment this here as other developers do not necessarily use the same build type as you.
# ideaOverrideBuildType = idea
# Whether IDEA should run spotless checks when pressing the Build button.
# This is meant to be set in $HOME/.gradle/gradle.properties.
# ideaCheckSpotlessOnBuild = true
Binary file not shown.
+2 -1
View File
@@ -1,6 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Vendored
+17 -10
View File
@@ -15,6 +15,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
#
##############################################################################
#
@@ -55,7 +57,7 @@
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
@@ -83,7 +85,9 @@ done
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
' "$PWD" ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
@@ -130,10 +134,13 @@ location of your Java installation."
fi
else
JAVACMD=java
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
if ! command -v java >/dev/null 2>&1
then
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
fi
# Increase the maximum file descriptors if we can.
@@ -141,7 +148,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045
# shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
@@ -149,7 +156,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045
# shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
@@ -198,11 +205,11 @@ fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded.
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
Vendored
+12 -10
View File
@@ -13,6 +13,8 @@
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@rem SPDX-License-Identifier: Apache-2.0
@rem
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@@ -43,11 +45,11 @@ set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
@@ -57,11 +59,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

+2
View File
@@ -0,0 +1,2 @@
#!/bin/bash
magick convert logo-1x.png -scale 200% \( +clone -background black -shadow 60x6+0+0 \) +swap -background none -layers merge logo-readme.png
+25 -1
View File
@@ -5,7 +5,31 @@ repositories {
name = 'mavenpattern'
url = 'https://mvn.falsepattern.com/releases'
content {
includeGroup "com.falsepattern"
includeGroup 'com.falsepattern'
}
}
exclusiveContent {
forRepository {
ivy {
name = 'CoreTweaks releases'
url = 'https://github.com/makamys/CoreTweaks/releases/download/'
patternLayout {
artifact '[revision]/[module]-1.7.10-[revision]+nomixin(-[classifier])(.[ext])'
}
metadataSources {
artifact()
}
}
}
filter {
includeGroup('CoreTweaks')
}
}
maven {
name = 'taumc'
url = 'https://maven.taumc.org/releases'
content {
includeGroup 'org.taumc'
}
}
mavenLocal()
+4 -12
View File
@@ -1,13 +1,12 @@
pluginManagement {
repositories {
maven {
// RetroFuturaGradle
name "GTNH Maven"
url "http://jenkins.usrv.eu:8081/nexus/content/groups/public/"
allowInsecureProtocol = true
url "https://nexus.gtnewhorizons.com/repository/public/"
mavenContent {
includeGroup("com.gtnewhorizons.retrofuturagradle")
includeGroup("com.gtnewhorizons")
includeGroupByRegex("com\\.gtnewhorizons\\..+")
}
}
gradlePluginPortal()
@@ -17,12 +16,5 @@ pluginManagement {
}
plugins {
id 'com.diffplug.blowdryerSetup' version '1.6.0'
id 'org.gradle.toolchains.foojay-resolver-convention' version '0.4.0' // Provides java toolchains
}
blowdryerSetup {
repoSubfolder 'gtnhShared'
github('GTNewHorizons/ExampleMod1.7.10', 'tag', '0.2.0')
//devLocal '.' // Use this when testing config updates locally
id 'com.gtnewhorizons.gtnhsettingsconvention' version '1.0.29'
}
+120
View File
@@ -0,0 +1,120 @@
import com.github.javaparser.StaticJavaParser;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.Node;
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import com.github.javaparser.ast.body.MethodDeclaration;
import com.github.javaparser.ast.body.Parameter;
import com.github.javaparser.ast.visitor.VoidVisitorWithDefaults;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* Used to generate gl_functions.csv. Which contains a mapping of OpenGL functions provided by LWJGL
* corresponding to the earliest GL version they appear in.
*/
public class GLFunctionParser {
final static String glPath = "util/gl"; // Path to LWJGL OpenGL bindings source code
public static void main(String[] args) throws FileNotFoundException {
HashMap<String, Set<String>> byFunction = new HashMap<>();
File dir = new File(glPath);
for (File file : dir.listFiles()) {
final String filename = file.getName();
if (filename.endsWith(".java") && filename.startsWith("GL") && Character.isDigit(filename.charAt(2))) {
Path p = Paths.get(filename);
String parsedFile = removeFileExtension(p.getFileName().toString());
CompilationUnit cu = StaticJavaParser.parse(file);
cu.accept(new VoidVisitorWithDefaults<>() {
@Override
public void defaultAction(Node n, Object arg) {
for( Node child : n.getChildNodes()) {
if(child instanceof ClassOrInterfaceDeclaration cd) {
for (MethodDeclaration md : cd.getMethods()) {
String methodName = md.getNameAsString() + "(";
for (Parameter p : md.getParameters()) {
methodName = methodName + p.getTypeAsString();
}
methodName = methodName + ")";
if(methodName.startsWith("n")) continue;
Set<String> functionSet = byFunction.computeIfAbsent(methodName, k -> new HashSet<>());
functionSet.add(parsedFile);
}
}
}
}
}, null);
}
}
Map<String, String> functionVersionMap = new HashMap<>();
for(String function : byFunction.keySet()) {
Set<String> versionsForFunction = byFunction.get(function);
int lowestInt = 46;
String lowestString = "GL46";
for(String version : versionsForFunction) {
int i = Integer.parseInt(version.substring(2, 4));
if (i < lowestInt) {
lowestInt = i;
lowestString = version;
}
}
functionVersionMap.put(function, lowestString);
}
List<String[]> outputLines = new ArrayList<>();
for (Map.Entry<String, String> entry : functionVersionMap.entrySet()) {
outputLines.add(new String[] {entry.getKey(), entry.getValue()});
}
File output = new File("output.csv");
try (PrintWriter writer = new PrintWriter(output)) {
outputLines.stream().map(GLSMFunctionComparison::convertToCSV).forEach(writer::println);
}
}
public static String convertToCSV(String[] data) {
return Stream.of(data).map(GLSMFunctionComparison::escapeSpecialCharacters).collect(Collectors.joining(","));
}
public static String escapeSpecialCharacters(String data) {
if (data == null) {
throw new IllegalArgumentException("Input data cannot be null");
}
String escapedData = data.replaceAll("\\R", " ");
if (data.contains(",") || data.contains("\"") || data.contains("'")) {
data = data.replace("\"", "\"\"");
escapedData = "\"" + data + "\"";
}
return escapedData;
}
public static String removeFileExtension(String filename) {
if (filename == null || filename.isEmpty()) {
return filename;
}
String extPattern = "(?<!^)[.]" + "[^.]*$";
return filename.replaceAll(extPattern, "");
}
}
+135
View File
@@ -0,0 +1,135 @@
import com.github.javaparser.ParserConfiguration;
import com.github.javaparser.StaticJavaParser;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.Node;
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import com.github.javaparser.ast.body.MethodDeclaration;
import com.github.javaparser.ast.body.Parameter;
import com.github.javaparser.ast.visitor.VoidVisitorWithDefaults;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* Used to compare OpenGL functions from gl_functions.csv to current GLStateManager
* source code to determine what functions have an implementation in GLSM, and what ones don't.
* Only considers functions which appear in GL 2.1 and lower
*/
public class GLSMFunctionComparison {
/**
* If set to true, then the outputted CSV will show functions which do have an implementation in GLSM
*/
final static boolean INCLUDE_TRUE = false;
final static String glFunctionsCsvPath = "gl_functions.csv";
final static String glsmPath = "src/main/java/com/gtnewhorizons/angelica/glsm/GLStateManager.java";
public static Map<String, String> parseGLFunctions() {
Map<String, String> map = new HashMap<>();
try (BufferedReader br = new BufferedReader(new FileReader(glFunctionsCsvPath))) {
String line;
while ((line = br.readLine()) != null) {
String[] values = line.split(",");
if (values.length == 2) {
String key = values[0].trim();
String value = values[1].trim();
int versionInt = Integer.parseInt(value.substring(2, 4));
if (versionInt < 30) map.put(key, value);
}
}
} catch (IOException e) {
e.printStackTrace();
}
return map;
}
public static void main(String[] args) throws FileNotFoundException {
//GLSM will fail to parse without increasing language level
StaticJavaParser.getParserConfiguration().setLanguageLevel(ParserConfiguration.LanguageLevel.JAVA_17);
Map<String, String> functionMap = parseGLFunctions();
Set<String> glsmFunctions = new HashSet<>();
File glsmFile = new File(glsmPath);
CompilationUnit cu = StaticJavaParser.parse(glsmFile);
cu.accept(new VoidVisitorWithDefaults<>() {
@Override
public void defaultAction(Node n, Object arg) {
for (Node child : n.getChildNodes()) {
if (child instanceof ClassOrInterfaceDeclaration cd) {
for (MethodDeclaration md : cd.getMethods()) {
String methodName = md.getNameAsString() + "(";
for (Parameter p : md.getParameters()) {
methodName = methodName + p.getTypeAsString();
}
methodName = methodName + ")";
glsmFunctions.add(methodName);
}
}
}
}
}, null);
Map<String, String> functionGLSMMap = new HashMap<>();
for(String function : functionMap.keySet()) {
if (!glsmFunctions.contains(function)) {
functionGLSMMap.put(function, "false");
} else if (INCLUDE_TRUE) {
functionGLSMMap.put(function, "true");
}
}
List<String[]> outputLines = new ArrayList<>();
for (Map.Entry<String, String> entry : functionGLSMMap.entrySet()) {
outputLines.add(new String[] {entry.getKey(), functionMap.get(entry.getKey()), entry.getValue()});
}
File output = new File("glsm_function_comparison.csv");
try (PrintWriter writer = new PrintWriter(output)) {
outputLines.stream().map(GLSMFunctionComparison::convertToCSV).forEach(writer::println);
}
}
public static String convertToCSV(String[] data) {
return Stream.of(data).map(GLSMFunctionComparison::escapeSpecialCharacters).collect(Collectors.joining(","));
}
public static String escapeSpecialCharacters(String data) {
if (data == null) {
throw new IllegalArgumentException("Input data cannot be null");
}
String escapedData = data.replaceAll("\\R", " ");
if (data.contains(",") || data.contains("\"") || data.contains("'")) {
data = data.replace("\"", "\"\"");
escapedData = "\"" + data + "\"";
}
return escapedData;
}
public static String removeFileExtension(String filename) {
if (filename == null || filename.isEmpty()) {
return filename;
}
String extPattern = "(?<!^)[.]" + "[^.]*$";
return filename.replaceAll(extPattern, "");
}
}
@@ -1,5 +1,6 @@
package com.gtnewhorizons.angelica;
import com.gtnewhorizons.angelica.common.BlockError;
import com.gtnewhorizons.angelica.compat.ModStatus;
import com.gtnewhorizons.angelica.proxy.CommonProxy;
import com.gtnewhorizons.angelica.utils.AnimationMode;
@@ -15,9 +16,10 @@ import cpw.mods.fml.common.event.FMLPreInitializationEvent;
name = "Angelica",
version = Tags.VERSION,
dependencies = " before:lwjgl3ify@[1.5.3,);" + " after:hodgepodge@[2.4.4,);" + " after:CodeChickenCore@[1.2.0,);"
+ " after:archaicfix@[0.7.0,);",
+ " after:archaicfix@[0.7.0,);" + " required-after:gtnhlib@[0.4.2,);",
acceptedMinecraftVersions = "[1.7.10]",
acceptableRemoteVersions = "*")
acceptableRemoteVersions = "*",
guiFactory = "com.gtnewhorizons.angelica.config.AngelicaGuiConfigFactory")
public class AngelicaMod {
@SidedProxy(clientSide = "com.gtnewhorizons.angelica.proxy.ClientProxy", serverSide = "com.gtnewhorizons.angelica.proxy.CommonProxy")
public static CommonProxy proxy;
@@ -26,10 +28,13 @@ public class AngelicaMod {
public static final ManagedEnum<AnimationMode> animationsMode = new ManagedEnum<>(AnimationMode.VISIBLE_ONLY);
public static BlockError blockError;
@Mod.EventHandler
public void preInit(FMLPreInitializationEvent event) {
ModStatus.preInit();
proxy.preInit(event);
blockError = new BlockError();
}
@Mod.EventHandler
@@ -1,10 +0,0 @@
- [x] Frustum (Seems related to Frustrum)
- [X] NativeImage
- [ ] PoseStack
- [ ] RenderType
- [ ] MultiBufferSource.BufferSource
- [ ] VertexBuffer
- [ ] VertexConsumer
- [ ] VertextFormat
- [ ] TextureAtlas (Seems related to TextureManager) - PBR related
- [ ] GUI
@@ -0,0 +1,8 @@
package com.gtnewhorizons.angelica.api;
/**
* To be used for modded items that don't have blocks. Baubles for example.
*/
public interface IDynamicLightProducer {
int getLuminance();
}
@@ -0,0 +1,35 @@
package com.gtnewhorizons.angelica.api;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* Marks an ISBRH as thread-safe, allowing Angelica to run it off-thread.
*
* <p>Note: Any tessellator access <i>must</i> be done within the methods of the ISBRH and not cached in the class.</p>
*/
@Documented
@Target({ TYPE })
@Retention(RUNTIME)
public @interface ThreadSafeISBRH {
/**
* Specifies whether Angelica should create a thread local instance of the class for each thread.
* <ul>
* <li>If this is set to <tt>true</tt>, a new instance will be created using the default constructor on each thread.</li>
* <ul>
* <li>Note: If your renderer requires arguments to the constructor, do <i>not</i> use this annotation;
* instead use the {@link ThreadSafeISBRHFactory} interface and implement the {@link ThreadSafeISBRHFactory#newInstance} method. </li>
* </ul>
* <li>If this is set to <tt>false</tt>, the main thread instance will be used on all threads.
* Use this option if your renderer class has no state, and can be safely used from multiple threads as is.</li>
* <ul>
* <li>No state/non final variables should be stored in the ISBRH as it is not guaranteed to be thread safe.</li>
* </ul>
* </ul>
*/
boolean perThread();
}
@@ -0,0 +1,22 @@
package com.gtnewhorizons.angelica.api;
import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler;
/**
* Marks an ISBRH as thread-safe using a thread local instance, allowing Angelica to run it off-thread.
* Use this when your ISBRH uses a non-default constructor.
* <p>To avoid a hard dependency on Angelica, you will likely want to mark this as an optional interface using:</p>
* <pre>
* @Optional.Interface(modid = "angelica", iface = "com.gtnewhorizons.angelica.api.ThreadSafeISBRHFactory")
* </pre>
*
* <p><b>Notes</b></p>
* <ul>
* <li>Any tessellator access <i>must</i> be done within the methods of the ISBRH and not cached in the class.</li>
* <li>If your class uses a default constructor or is thread-safe by default, consider using the simpler {@link ThreadSafeISBRH}
* annotation instead.
* </ul>
*/
public interface ThreadSafeISBRHFactory extends ISimpleBlockRenderingHandler {
ThreadSafeISBRHFactory newInstance();
}
@@ -11,6 +11,7 @@ import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.util.MathHelper;
import net.minecraft.util.ResourceLocation;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
@@ -19,8 +20,6 @@ import java.util.Arrays;
import java.util.Comparator;
import java.util.Objects;
import static org.lwjgl.opengl.GL11.*;
/**
* A batching replacement for {@code FontRenderer}
*
@@ -246,21 +245,24 @@ public class BatchingFontRenderer {
// Sort&Draw
batchCommands.sort(FontDrawCmd.DRAW_ORDER_COMPARATOR);
final boolean isTextureEnabledBefore = GLStateManager.glIsEnabled(GL11.GL_TEXTURE_2D);
final int boundTextureBefore = GLStateManager.glGetInteger(GL11.GL_TEXTURE_BINDING_2D);
boolean textureChanged = false;
ResourceLocation lastTexture = DUMMY_RESOURCE_LOCATION;
GLStateManager.enableTexture();
GLStateManager.enableAlphaTest();
GLStateManager.enableBlend();
GLStateManager.tryBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);
GLStateManager.glShadeModel(GL_FLAT);
GLStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ZERO);
GLStateManager.glShadeModel(GL11.GL_FLAT);
glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
glTexCoordPointer(2, 0, batchVtxTexCoords);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glColorPointer(4, GL_UNSIGNED_BYTE, 0, batchVtxColors);
glEnableClientState(GL_COLOR_ARRAY);
glVertexPointer(2, 0, batchVtxPositions);
glEnableClientState(GL_VERTEX_ARRAY);
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
GL11.glTexCoordPointer(2, 0, batchVtxTexCoords);
GL11.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
GL11.glColorPointer(4, GL11.GL_UNSIGNED_BYTE, 0, batchVtxColors);
GL11.glEnableClientState(GL11.GL_COLOR_ARRAY);
GL11.glVertexPointer(2, 0, batchVtxPositions);
GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY);
GLStateManager.glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
// Use plain for loop to avoid allocations
final FontDrawCmd[] cmdsData = batchCommands.elements();
@@ -269,21 +271,31 @@ public class BatchingFontRenderer {
final FontDrawCmd cmd = cmdsData[i];
if (!Objects.equals(lastTexture, cmd.texture)) {
if (lastTexture == null) {
GLStateManager.enableTexture();
GLStateManager.glEnable(GL11.GL_TEXTURE_2D);
} else if (cmd.texture == null) {
GLStateManager.disableTexture();
GLStateManager.glDisable(GL11.GL_TEXTURE_2D);
}
if (cmd.texture != null) {
((FontRendererAccessor) (Object) underlying).angelica$bindTexture(cmd.texture);
((FontRendererAccessor) underlying).angelica$bindTexture(cmd.texture);
textureChanged = true;
}
lastTexture = cmd.texture;
}
batchIndices.limit(cmd.startVtx + cmd.idxCount);
batchIndices.position(cmd.startVtx);
glDrawElements(GL_TRIANGLES, batchIndices);
GL11.glDrawElements(GL11.GL_TRIANGLES, batchIndices);
}
glPopClientAttrib();
GL11.glDisableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
GL11.glDisableClientState(GL11.GL_COLOR_ARRAY);
GL11.glDisableClientState(GL11.GL_VERTEX_ARRAY);
if (isTextureEnabledBefore) {
GLStateManager.glEnable(GL11.GL_TEXTURE_2D);
}
if (textureChanged) {
GLStateManager.glBindTexture(GL11.GL_TEXTURE_2D, boundTextureBefore);
}
// Clear for the next batch
batchCommandPool.addAll(batchCommands);
@@ -345,7 +357,7 @@ public class BatchingFontRenderer {
final float underlineY = anchorY + underlying.FONT_HEIGHT - 1.0f;
float underlineStartX = 0.0f;
float underlineEndX = 0.0f;
final float strikethroughY = anchorY + (float) (underlying.FONT_HEIGHT / 2);
final float strikethroughY = anchorY + (float) (underlying.FONT_HEIGHT / 2) - 1.0F;
float strikethroughStartX = 0.0f;
float strikethroughEndX = 0.0f;
@@ -0,0 +1,29 @@
package com.gtnewhorizons.angelica.client.gui;
import com.gtnewhorizons.angelica.compat.mojang.Element;
import net.minecraft.client.gui.GuiScreen;
import org.lwjgl.input.Mouse;
import java.util.List;
public abstract class ScrollableGuiScreen extends GuiScreen {
@Override
public void drawScreen(int mouseX, int mouseY, float partialTicks) {
super.drawScreen(mouseX, mouseY, partialTicks);
handleMouseScroll(mouseX, mouseY, partialTicks);
}
public abstract List<? extends Element> children();
protected void handleMouseScroll(int mouseX, int mouseY, float partialTicks) {
for (; !this.mc.gameSettings.touchscreen && Mouse.next(); this.mc.currentScreen.handleMouseInput()) {
int dWheel = Mouse.getEventDWheel();
if (dWheel != 0) {
for(Element child : children()) {
child.mouseScrolled(mouseX, mouseY, dWheel);
}
}
}
}
}
@@ -1,235 +0,0 @@
package com.gtnewhorizons.angelica.client.renderer;
import com.gtnewhorizons.angelica.compat.mojang.BlockPos;
import com.gtnewhorizons.angelica.compat.mojang.VertexFormat;
import com.gtnewhorizons.angelica.compat.nd.Quad;
import com.gtnewhorizons.angelica.mixins.interfaces.ITessellatorInstance;
import com.gtnewhorizons.angelica.utils.ObjectPooler;
import cpw.mods.fml.relauncher.ReflectionHelper;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import me.jellysquid.mods.sodium.client.render.pipeline.BlockRenderer;
import net.minecraft.client.renderer.Tessellator;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.reflect.Field;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Arrays;
import java.util.List;
import static net.minecraft.util.MathHelper.clamp_int;
/*
* To be used in conjunction with the TessellatorManager
*
* Used to capture the quads generated by the Tessellator across multiple draw calls and make the quad
* list available for usage.
*
* NOTE: This will _not_ (currently) capture, integrate, or stop any GL calls made around the tessellator draw calls.
*
*/
@SuppressWarnings("unused")
public class CapturingTessellator extends Tessellator implements ITessellatorInstance {
// Access Transformers don't work on Forge Fields :rage:
private static final MethodHandle sRawBufferSize;
private static final MethodHandle gRawBufferSize;
private final BlockRenderer.Flags FLAGS = new BlockRenderer.Flags(true, true, true, true);
private final ObjectPooler<Quad> quadBuf = new ObjectPooler<>(Quad::new);
private final List<Quad> collectedQuads = new ObjectArrayList<>();
// Any offset we need to the Tesselator's offset!
private final BlockPos offset = new BlockPos();
public void setOffset(BlockPos pos) {
this.offset.set(pos);
}
static {
Field rbs = ReflectionHelper.findField(Tessellator.class, "rawBufferSize");
rbs.setAccessible(true);
try {
sRawBufferSize = MethodHandles.lookup().unreflectSetter(rbs);
gRawBufferSize = MethodHandles.lookup().unreflectGetter(rbs);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
public void setRawBufferSize(int size) {
try {
sRawBufferSize.invokeExact((Tessellator)this, size);
} catch (Throwable throwable) {
throw new RuntimeException(throwable);
}
}
public int getRawBufferSize() {
try {
return (int) gRawBufferSize.invokeExact((Tessellator)this);
} catch (Throwable throwable) {
throw new RuntimeException(throwable);
}
}
@Override
public int draw() {
// Adapted from Neodymium
FLAGS.hasBrightness = this.hasBrightness;
FLAGS.hasColor = this.hasColor;
FLAGS.hasNormals = this.hasNormals;
// TODO: Support GL_TRIANGLES
if(this.drawMode != GL11.GL_QUADS) {
throw new IllegalStateException("Currently only supports GL_QUADS");
}
final int verticesPerPrimitive = this.drawMode == GL11.GL_QUADS ? 4 : 3;
for(int quadI = 0; quadI < this.vertexCount / verticesPerPrimitive; quadI++) {
final Quad quad = quadBuf.getInstance();
quad.setState(this.rawBuffer, quadI * (verticesPerPrimitive * 8), FLAGS, this.drawMode, -offset.x, -offset.y, -offset.z);
if(quad.deleted) {
quadBuf.releaseInstance(quad);
} else {
this.collectedQuads.add(quad);
}
}
final int i = this.rawBufferIndex * 4;
this.discard();
return i;
}
@Override
public void reset() {
super.reset();
this.offset.zero();
}
@Override
public void discard() {
isDrawing = false;
reset();
}
public List<Quad> getQuads() {
return collectedQuads;
}
public void clearQuads() {
//noinspection ForLoopReplaceableByForEach
for(int i = 0; i < this.collectedQuads.size(); i++) {
this.quadBuf.releaseInstance(this.collectedQuads.get(i));
}
this.collectedQuads.clear();
}
public static ByteBuffer quadsToBuffer(List<Quad> quads, VertexFormat format) {
if(!format.canWriteQuads()) {
throw new IllegalStateException("Vertex format has no quad writer: " + format);
}
final ByteBuffer byteBuffer = BufferUtils.createByteBuffer(format.getVertexSize() * quads.size() * 4);
// noinspection ForLoopReplaceableByForEach
for (int i = 0, quadsSize = quads.size(); i < quadsSize; i++) {
format.writeQuad(quads.get(i), byteBuffer);
}
byteBuffer.rewind();
return byteBuffer;
}
public static int createBrightness(int sky, int block) {
return sky << 20 | block << 4;
}
// API from newer MC
public CapturingTessellator pos(double x, double y, double z) {
ensureBuffer();
this.rawBuffer[this.rawBufferIndex + 0] = Float.floatToRawIntBits((float)(x + this.xOffset));
this.rawBuffer[this.rawBufferIndex + 1] = Float.floatToRawIntBits((float)(y + this.yOffset));
this.rawBuffer[this.rawBufferIndex + 2] = Float.floatToRawIntBits((float)(z + this.zOffset));
return this;
}
public CapturingTessellator tex(double u, double v) {
this.rawBuffer[this.rawBufferIndex + 3] = Float.floatToRawIntBits((float)u);
this.rawBuffer[this.rawBufferIndex + 4] = Float.floatToRawIntBits((float)v);
this.hasTexture = true;
return this;
}
public CapturingTessellator color(float red, float green, float blue, float alpha) {
return this.color((int)(red * 255.0F), (int)(green * 255.0F), (int)(blue * 255.0F), (int)(alpha * 255.0F));
}
public CapturingTessellator color(int red, int green, int blue, int alpha) {
if(this.isColorDisabled) return this;
red = clamp_int(red, 0, 255);
green = clamp_int(green, 0, 255);
blue = clamp_int(blue, 0, 255);
alpha = clamp_int(alpha, 0, 255);
final int color;
if (ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN) {
color = alpha << 24 | blue << 16 | green << 8 | red;
} else {
color = red << 24 | green << 16 | blue << 8 | alpha;
}
this.rawBuffer[this.rawBufferIndex + 5] = color;
this.hasColor = true;
return this;
}
public CapturingTessellator normal(float x, float y, float z) {
final byte b0 = (byte)((int)(x * 127.0F));
final byte b1 = (byte)((int)(y * 127.0F));
final byte b2 = (byte)((int)(z * 127.0F));
this.rawBuffer[this.rawBufferIndex + 6] = b0 & 255 | (b1 & 255) << 8 | (b2 & 255) << 16;
this.hasNormals = true;
return this;
}
public CapturingTessellator lightmap(int skyLight, int blockLight) {
return brightness(createBrightness(skyLight, blockLight));
}
public CapturingTessellator brightness(int brightness) {
this.rawBuffer[this.rawBufferIndex + 7] = brightness;
this.hasBrightness = true;
return this;
}
public CapturingTessellator endVertex() {
this.rawBufferIndex += 8;
++this.vertexCount;
return this;
}
public void ensureBuffer() {
int rawBufferSize = getRawBufferSize();
if (rawBufferIndex >= rawBufferSize - 32) {
if (rawBufferSize == 0) {
rawBufferSize = 0x10000;
setRawBufferSize(rawBufferSize);
rawBuffer = new int[rawBufferSize];
} else {
rawBufferSize *= 2;
setRawBufferSize(rawBufferSize);
rawBuffer = Arrays.copyOf(rawBuffer, rawBufferSize);
}
}
}
}
@@ -0,0 +1,48 @@
package com.gtnewhorizons.angelica.common;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.util.IIcon;
import net.minecraftforge.client.event.TextureStitchEvent;
import net.minecraftforge.common.MinecraftForge;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
/**
* This Block is not actually getting registered. A static instance is created in AngelicaMod.
* Actually registering the block on the client but not the server can cause block IDs to
* different between client/server, which is not good.
* We're essentially injecting the block's texture, so that we may use this block as if it were
* any normal block for rendering purposes with RenderBlocks and such, but not have to actually
* register it as a block.
*/
public class BlockError extends Block {
public static final IIcon[] icons = new IIcon[2];
public BlockError() {
super(Material.rock);
MinecraftForge.EVENT_BUS.register(this);
}
@SubscribeEvent
@SideOnly(Side.CLIENT)
public void onTextureStitch(TextureStitchEvent.Pre event) {
if (event.map.getTextureType() == 0) {
for (int i = 0; i < icons.length; i++) {
icons[i] = event.map.registerIcon("angelica:error_block_" + i);
}
}
}
@Override
@SideOnly(Side.CLIENT)
public IIcon getIcon(int side, int meta) {
return meta >= 0 && meta < icons.length ? icons[meta] : null;
}
}
@@ -0,0 +1,60 @@
package com.gtnewhorizons.angelica.common;
import com.gtnewhorizon.gtnhlib.client.renderer.quad.QuadProvider;
import com.gtnewhorizon.gtnhlib.client.renderer.util.DirectionUtil;
import com.gtnewhorizons.angelica.mixins.interfaces.ModeledBlock;
import com.gtnewhorizons.angelica.utils.AssetLoader;
import lombok.Getter;
import lombok.Setter;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.client.renderer.texture.IIconRegister;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
import org.jetbrains.annotations.NotNull;
import static com.gtnewhorizons.angelica.models.VanillaModels.LECTERN;
public class BlockTest extends Block implements ModeledBlock {
@Getter
@Setter
private QuadProvider model;
public BlockTest() {
super(Material.rock);
this.setBlockTextureName("missingno");
this.setModel((world, pos, block, meta, dir, random, color, quadPool) -> {
if (meta < 2 || meta > 5) meta = 2;
return LECTERN.models[meta - 2].getQuads(world, pos, block, meta, dir, random, color, quadPool);
});
}
@Override
public boolean isOpaqueCube() {
return false;
}
@Override
public void registerBlockIcons(IIconRegister reg) {
for (String s : AssetLoader.testTexs) {
reg.registerIcon(s);
}
}
/**
* Called when a block is placed using its ItemBlock. Args: World, X, Y, Z, side, hitX, hitY, hitZ, block metadata
*/
@Override
public int onBlockPlaced(@NotNull World worldIn, int x, int y, int z, int side, float subX, float subY, float subZ, int meta) {
// Face NORTH if placed up or down
final ForgeDirection s = DirectionUtil.ALL_DIRECTIONS[side];
if (s == ForgeDirection.UP || s == ForgeDirection.DOWN)
return 2;
// Face the placed side
return side;
}
}
@@ -1,7 +1,7 @@
package com.gtnewhorizons.angelica.compat;
import com.falsepattern.chunk.api.DataRegistry;
import com.gtnewhorizons.angelica.mixins.early.sodium.MixinExtendedBlockStorage;
import com.gtnewhorizons.angelica.mixins.interfaces.ExtendedBlockStorageAccessor;
import com.gtnewhorizons.angelica.mixins.interfaces.ExtendedNibbleArray;
import com.gtnewhorizons.neid.mixins.interfaces.IExtendedBlockStorageMixin;
@@ -19,7 +19,7 @@ public class ExtendedBlockStorageExt extends ExtendedBlockStorage {
}
public ExtendedBlockStorageExt(Chunk chunk, ExtendedBlockStorage storage) {
super(((MixinExtendedBlockStorage) storage).getYBase(), storage.getSkylightArray() != null);
super(((ExtendedBlockStorageAccessor) storage).getYBase(), storage.getSkylightArray() != null);
if (ModStatus.isChunkAPILoaded) {
if (storage.getSkylightArray() != null) {
@@ -36,6 +36,10 @@ public class ExtendedBlockStorageExt extends ExtendedBlockStorage {
copyNibbleArray((ExtendedNibbleArray) storage.getBlockMSBArray(), (ExtendedNibbleArray) this.getBlockMSBArray());
}
arrayLen = block16BArray.length;
if (ModStatus.isNEIDMetadataExtended) {
final short[] block16BMetaArray = ((IExtendedBlockStorageMixin)(Object)this).getBlock16BMetaArray();
System.arraycopy(((IExtendedBlockStorageMixin)(Object)storage).getBlock16BMetaArray(), 0, block16BMetaArray, 0, block16BMetaArray.length);
}
}
else if (ModStatus.isOldNEIDLoaded){
final short[] blockLSBArray = Hooks.get(this);
@@ -54,7 +58,7 @@ public class ExtendedBlockStorageExt extends ExtendedBlockStorage {
}
copyNibbleArray((ExtendedNibbleArray) storage.getMetadataArray(), (ExtendedNibbleArray)this.getMetadataArray());
if (!ModStatus.isNEIDMetadataExtended) copyNibbleArray((ExtendedNibbleArray) storage.getMetadataArray(), (ExtendedNibbleArray)this.getMetadataArray());
copyNibbleArray((ExtendedNibbleArray) storage.getBlocklightArray(), (ExtendedNibbleArray)this.getBlocklightArray());
if(storage.getSkylightArray() != null) {
hasSky = true;
@@ -64,7 +68,7 @@ public class ExtendedBlockStorageExt extends ExtendedBlockStorage {
copyNibbleArray((ExtendedNibbleArray) storage.getSkylightArray(), (ExtendedNibbleArray) this.getSkylightArray());
}
}
((MixinExtendedBlockStorage) this).setBlockRefCount(((MixinExtendedBlockStorage) storage).getBlockRefCount());
((ExtendedBlockStorageAccessor) this).setBlockRefCount(((ExtendedBlockStorageAccessor) storage).getBlockRefCount());
}
@@ -1,6 +1,12 @@
package com.gtnewhorizons.angelica.compat;
import com.gtnewhorizons.angelica.helpers.LoadControllerHelper;
import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.versioning.ArtifactVersion;
import cpw.mods.fml.common.versioning.DefaultArtifactVersion;
import mods.battlegear2.Battlegear;
import net.dries007.holoInventory.HoloInventory;
import xonin.backhand.Backhand;
public class ModStatus {
/**
@@ -11,15 +17,64 @@ public class ModStatus {
* ASM Version
*/
public static boolean isOldNEIDLoaded;
public static boolean isBetterCrashesLoaded;
public static boolean isNEIDMetadataExtended;
public static boolean isLotrLoaded;
public static boolean isChunkAPILoaded;
public static boolean isEIDBiomeLoaded;
public static boolean isXaerosMinimapLoaded;
public static boolean isHoloInventoryLoaded;
public static boolean isBattlegearLoaded;
public static boolean isBackhandLoaded;
public static boolean isThaumcraftLoaded;
public static boolean isThaumicHorizonsLoaded;
public static boolean isBaublesLoaded;
public static void preInit(){
isBetterCrashesLoaded = Loader.isModLoaded("bettercrashes");
isNEIDLoaded = Loader.isModLoaded("neid");
isOldNEIDLoaded = Loader.isModLoaded("notenoughIDs");
isLotrLoaded = Loader.isModLoaded("lotr");
isChunkAPILoaded = Loader.isModLoaded("chunkapi");
isEIDBiomeLoaded = Loader.isModLoaded("endlessids_biome");
isXaerosMinimapLoaded = Loader.isModLoaded("XaeroMinimap");
isHoloInventoryLoaded = Loader.isModLoaded("holoinventory");
isBattlegearLoaded = Loader.isModLoaded("battlegear2");
isBackhandLoaded = Loader.isModLoaded("backhand");
isThaumcraftLoaded = Loader.isModLoaded("Thaumcraft");
isThaumicHorizonsLoaded = Loader.isModLoaded("ThaumicHorizons");
isBaublesLoaded = Loader.isModLoaded("Baubles");
if (isHoloInventoryLoaded){
isHoloInventoryLoaded = new DefaultArtifactVersion("2.4.4-GTNH")
.compareTo(
LoadControllerHelper.getOwningMod(HoloInventory.class).getProcessedVersion()
) <= 0;
}
// remove compat with original release of BG2
if (isBattlegearLoaded){
isBattlegearLoaded = new DefaultArtifactVersion("1.2.0")
.compareTo(
LoadControllerHelper.getOwningMod(Battlegear.class).getProcessedVersion()
) <= 0;
}
if (isBackhandLoaded){
isBackhandLoaded = new DefaultArtifactVersion("1.4.1")
.compareTo(
LoadControllerHelper.getOwningMod(Backhand.class).getProcessedVersion()
) <= 0;
}
isNEIDMetadataExtended = false;
if (isNEIDLoaded) {
int majorVersion = Integer.parseInt(Loader.instance().getIndexedModList().get("neid").getVersion().split("\\.")[0]);
if (majorVersion >= 2) {
isNEIDMetadataExtended = true;
}
}
}
}
@@ -0,0 +1,34 @@
package com.gtnewhorizons.angelica.compat.bettercrashes;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.mixins.interfaces.IRenderGlobalExt;
import cpw.mods.fml.common.Optional;
import net.minecraft.client.Minecraft;
import vfyjxf.bettercrashes.utils.StateManager;
import static com.gtnewhorizons.angelica.loading.AngelicaTweaker.LOGGER;
@Optional.Interface(modid = "angelica", iface = "vfyjxf.bettercrashes.utils.StateManager.IResettable")
public class BetterCrashesCompat implements StateManager.IResettable {
private static BetterCrashesCompat INSTANCE;
public static void init() {
if (INSTANCE == null) {
INSTANCE = new BetterCrashesCompat();
}
}
public BetterCrashesCompat() {
LOGGER.info("BetterCrashesCompat initialized");
this.register();
}
@Override
public void resetState() {
LOGGER.info("Reloading SodiumRenderer");
((IRenderGlobalExt) Minecraft.getMinecraft().renderGlobal).reload();
LOGGER.info("Resetting GLStateManager");
GLStateManager.reset();
}
}
@@ -0,0 +1,37 @@
package com.gtnewhorizons.angelica.compat.endlessids;
import com.falsepattern.endlessids.mixin.helpers.ChunkBiomeHook;
import lombok.val;
import net.minecraft.world.chunk.Chunk;
import static com.falsepattern.endlessids.constants.ExtendedConstants.biomeIDMask;
import static com.falsepattern.endlessids.constants.ExtendedConstants.biomeIDNull;
public class EndlessIDsCompat {
public static void sodium$populateBiomes(Chunk chunk) {
if (!(chunk instanceof ChunkBiomeHook hook))
return;
val biomes = hook.getBiomeShortArray();
if (biomes == null)
return;
val cX = chunk.xPosition << 4;
val cZ = chunk.zPosition << 4;
val manager = chunk.worldObj.getWorldChunkManager();
for(var z = 0; z < 16; z++) {
for(var x = 0; x < 16; x++) {
val idx = (z << 4) + x;
val biome = biomes[idx] & biomeIDMask;
if(biome == biomeIDNull) {
val generated = manager.getBiomeGenAt(cX + x, cZ + z);
if (generated == null)
continue;
biomes[idx] = (short)(generated.biomeID & biomeIDMask);
}
}
}
}
}
@@ -1,12 +1,58 @@
package com.gtnewhorizons.angelica.compat.lwjgl;
import org.lwjgl.BufferUtils;
import static com.gtnewhorizons.angelica.compat.lwjgl.Pointer.BITS64;
import it.unimi.dsi.fastutil.longs.LongPredicate;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import org.lwjgl.BufferUtils;
/**
* Backported from LWJGL3 under the BSD 3-Clause "New" or "Revised" License license
*
* <p>This class provides functionality for managing native memory.
*
* <p>All methods in this class will make use of {@link sun.misc.Unsafe} if it's available, for performance. If Unsafe is not available, the fallback
* implementations make use of reflection and, in the worst-case, JNI.</p>
*
* <p>Method names in this class are prefixed with {@code mem} to avoid ambiguities when used with static imports.</p>
*/
public class CompatMemoryUtil {
public static final long NULL = 0;
static final sun.misc.Unsafe UNSAFE;
private static final Class<? extends ByteBuffer> BUFFER_BYTE;
private static final Class<? extends IntBuffer> BUFFER_INT;
private static final Class<? extends FloatBuffer> BUFFER_FLOAT;
private static final long MARK;
private static final long POSITION;
private static final long LIMIT;
private static final long CAPACITY;
private static final long ADDRESS;
static {
ByteBuffer bb = ByteBuffer.allocateDirect(0).order(ByteOrder.nativeOrder());
BUFFER_BYTE = bb.getClass();
BUFFER_INT = bb.asIntBuffer().getClass();
BUFFER_FLOAT = bb.asFloatBuffer().getClass();
UNSAFE = getUnsafeInstance();
MARK = getMarkOffset();
POSITION = getPositionOffset();
LIMIT = getLimitOffset();
CAPACITY = getCapacityOffset();
ADDRESS = getAddressOffset();
}
public static ByteBuffer memReallocDirect(ByteBuffer old, int capacity) {
ByteBuffer newBuf = BufferUtils.createByteBuffer(capacity);
int oldPos = old.position();
@@ -34,22 +80,100 @@ public class CompatMemoryUtil {
return newBuf;
}
/* -------------------------------------
-------------------------------------
UNSAFE MEMORY ACCESS API
-------------------------------------
------------------------------------- */
private static final int FILL_PATTERN_32 = Integer.divideUnsigned(-1, 255);
private static final long FILL_PATTERN_64 = Long.divideUnsigned(-1L, 255L);
/**
* Backported from LWJGL3 under the BSD 3-Clause "New" or "Revised" License license
* Sets all bytes in a specified block of memory to a fixed value (usually zero).
*
* <p>This class provides functionality for managing native memory.
*
* <p>All methods in this class will make use of {@link sun.misc.Unsafe} if it's available, for performance. If Unsafe is not available, the fallback
* implementations make use of reflection and, in the worst-case, JNI.</p>
*
* <p>Method names in this class are prefixed with {@code mem} to avoid ambiguities when used with static imports.</p>
* @param ptr the starting memory address
* @param value the value to set (memSet will convert it to unsigned byte)
* @param bytes the number of bytes to set
*/
public static void memSet(long ptr, int value, long bytes) {
if (/*DEBUG*/ false && (ptr == NULL || bytes < 0)) {
throw new IllegalArgumentException();
}
static final sun.misc.Unsafe UNSAFE;
/*
- Unsafe.setMemory is very slow.
- A custom Java loop is fastest at small sizes, approximately up to 256 bytes.
- The native memset becomes fastest at bigger sizes, when the JNI overhead becomes negligible.
TODO: verify this
*/
static {
UNSAFE = getUnsafeInstance();
//UNSAFE.setMemory(ptr, bytes, (byte)(value & 0xFF));
//if (bytes < 256L) {
int p = (int)ptr;
if (BITS64) {
if ((p & 7) == 0) {
memSet64(ptr, value, (int)bytes & 0xFF);
return;
}
} else {
if ((p & 3) == 0) {
memSet32(p, value, (int)bytes & 0xFF);
return;
}
}
//}
//nmemset(ptr, value, bytes);
}
private static void memSet64(long ptr, int value, int bytes) {
int aligned = bytes & ~7;
// Aligned body
long valuel = (value & 0xFF) * FILL_PATTERN_64;
for (int i = 0; i < aligned; i += 8) {
UNSAFE.putLong(null, ptr + i, valuel);
}
// Unaligned tail
byte valueb = (byte)(value & 0xFF);
for (int i = aligned; i < bytes; i++) {
UNSAFE.putByte(null, ptr + i, valueb);
}
}
private static void memSet32(int ptr, int value, int bytes) {
int aligned = bytes & ~3;
// Aligned body
int vi = (value & 0xFF) * FILL_PATTERN_32;
for (int i = 0; i < aligned; i += 4) {
UNSAFE.putInt(null, (ptr + i) & 0xFFFF_FFFFL, vi);
}
// Unaligned tail
byte vb = (byte)(value & 0xFF);
for (int i = aligned; i < bytes; i++) {
UNSAFE.putByte(null, (ptr + i) & 0xFFFF_FFFFL, vb);
}
}
public static boolean memGetBoolean(long ptr) { return UNSAFE.getByte(null, ptr) != 0; }
public static byte memGetByte(long ptr) { return UNSAFE.getByte(null, ptr); }
public static short memGetShort(long ptr) { return UNSAFE.getShort(null, ptr); }
public static int memGetInt(long ptr) { return UNSAFE.getInt(null, ptr); }
public static long memGetLong(long ptr) { return UNSAFE.getLong(null, ptr); }
public static float memGetFloat(long ptr) { return UNSAFE.getFloat(null, ptr); }
public static double memGetDouble(long ptr) { return UNSAFE.getDouble(null, ptr); }
public static void memPutByte(long ptr, byte value) { UNSAFE.putByte(null, ptr, value); }
public static void memPutShort(long ptr, short value) { UNSAFE.putShort(null, ptr, value); }
public static void memPutInt(long ptr, int value) { UNSAFE.putInt(null, ptr, value); }
public static void memPutLong(long ptr, long value) { UNSAFE.putLong(null, ptr, value); }
public static void memPutFloat(long ptr, float value) { UNSAFE.putFloat(null, ptr, value); }
public static void memPutDouble(long ptr, double value) { UNSAFE.putDouble(null, ptr, value); }
// -------------------------------------------------
// -------------------------------------------------
// -------------------------------------------------
private static sun.misc.Unsafe getUnsafeInstance() {
java.lang.reflect.Field[] fields = sun.misc.Unsafe.class.getDeclaredFields();
@@ -83,20 +207,121 @@ public class CompatMemoryUtil {
throw new UnsupportedOperationException("LWJGL requires sun.misc.Unsafe to be available.");
}
/**
* Recursively searches an object and its superclasses for a field with the same name and type. If the field isn't
* public, it may not be stable across library/JVM versions, and these calls are likely not portable. You have been
* warned!
*/
private static long getFieldOffset(Class<?> containerType, Class<?> fieldType, String name) {
Class<?> c = containerType;
while (c != Object.class) {
Field[] fields = c.getDeclaredFields();
for (Field field : fields) {
if (!field.getType().isAssignableFrom(fieldType) || Modifier.isStatic(field.getModifiers()) || field.isSynthetic()) {
continue;
}
public static void memPutByte(long ptr, byte value) { UNSAFE.putByte(null, ptr, value); }
public static void memPutShort(long ptr, short value) { UNSAFE.putShort(null, ptr, value); }
public static void memPutInt(long ptr, int value) { UNSAFE.putInt(null, ptr, value); }
public static void memPutLong(long ptr, long value) { UNSAFE.putLong(null, ptr, value); }
public static void memPutFloat(long ptr, float value) { UNSAFE.putFloat(null, ptr, value); }
public static void memPutDouble(long ptr, double value) { UNSAFE.putDouble(null, ptr, value); }
long offset = UNSAFE.objectFieldOffset(field);
if (field.getName().equals(name)) {
return offset;
}
}
c = c.getSuperclass();
}
throw new UnsupportedOperationException("Failed to find field offset in class.");
}
public static boolean memGetBoolean(long ptr) { return UNSAFE.getByte(null, ptr) != 0; }
public static byte memGetByte(long ptr) { return UNSAFE.getByte(null, ptr); }
public static short memGetShort(long ptr) { return UNSAFE.getShort(null, ptr); }
public static int memGetInt(long ptr) { return UNSAFE.getInt(null, ptr); }
public static long memGetLong(long ptr) { return UNSAFE.getLong(null, ptr); }
public static float memGetFloat(long ptr) { return UNSAFE.getFloat(null, ptr); }
public static double memGetDouble(long ptr) { return UNSAFE.getDouble(null, ptr); }
private static long getFieldOffset(Class<?> containerType, Class<?> fieldType, LongPredicate predicate) {
Class<?> c = containerType;
while (c != Object.class) {
Field[] fields = c.getDeclaredFields();
for (Field field : fields) {
if (!field.getType().isAssignableFrom(fieldType) || Modifier.isStatic(field.getModifiers()) || field.isSynthetic()) {
continue;
}
long offset = UNSAFE.objectFieldOffset(field);
if (predicate.test(offset)) {
return offset;
}
}
c = c.getSuperclass();
}
throw new UnsupportedOperationException("Failed to find field offset in class.");
}
private static long getFieldOffsetInt(Object container, int value) {
return getFieldOffset(container.getClass(), int.class, offset -> UNSAFE.getInt(container, offset) == value);
}
private static long getAddressOffset() {
final ByteBuffer bb = ByteBuffer.allocateDirect(0);
return getFieldOffset(bb.getClass(), long.class, "address");
// TODO: do this portably
// long MAGIC_ADDRESS = 0xDEADBEEF8BADF00DL & (BITS32 ? 0xFFFF_FFFFL : 0xFFFF_FFFF_FFFF_FFFFL);
// ByteBuffer bb = Objects.requireNonNull(NewDirectByteBuffer(MAGIC_ADDRESS, 0));
//return getFieldOffset(bb.getClass(), long.class, offset -> UNSAFE.getLong(bb, offset) == MAGIC_ADDRESS);
}
private static final int MAGIC_CAPACITY = 0x0D15EA5E;
private static final int MAGIC_POSITION = 0x00FACADE;
private static long getMarkOffset() {
// TODO: is this actually reliable without NewDirectByteBuffer?
ByteBuffer bb = ByteBuffer.allocateDirect(0);
return getFieldOffsetInt(bb, -1);
// ByteBuffer bb = Objects.requireNonNull(NewDirectByteBuffer(1L, 0));
// return getFieldOffsetInt(bb, -1);
}
private static long getPositionOffset() {
ByteBuffer bb = ByteBuffer.allocateDirect(MAGIC_CAPACITY);
bb.position(MAGIC_POSITION);
return getFieldOffsetInt(bb, MAGIC_POSITION);
}
private static long getLimitOffset() {
ByteBuffer bb = ByteBuffer.allocateDirect(MAGIC_CAPACITY);
bb.limit(MAGIC_POSITION);
return getFieldOffsetInt(bb, MAGIC_POSITION);
}
private static long getCapacityOffset() {
ByteBuffer bb = ByteBuffer.allocateDirect(MAGIC_CAPACITY);
bb.limit(0);
return getFieldOffsetInt(bb, MAGIC_CAPACITY);
}
static IntBuffer wrapBufferInt(long address, int capacity) {
IntBuffer buffer;
try {
buffer = (IntBuffer)UNSAFE.allocateInstance(BUFFER_INT);
} catch (InstantiationException e) {
throw new UnsupportedOperationException(e);
}
UNSAFE.putLong(buffer, ADDRESS, address);
UNSAFE.putInt(buffer, MARK, -1);
UNSAFE.putInt(buffer, LIMIT, capacity);
UNSAFE.putInt(buffer, CAPACITY, capacity);
return buffer;
}
static FloatBuffer wrapBufferFloat(long address, int capacity) {
FloatBuffer buffer;
try {
buffer = (FloatBuffer)UNSAFE.allocateInstance(BUFFER_FLOAT);
} catch (InstantiationException e) {
throw new UnsupportedOperationException(e);
}
UNSAFE.putLong(buffer, ADDRESS, address);
UNSAFE.putInt(buffer, MARK, -1);
UNSAFE.putInt(buffer, LIMIT, capacity);
UNSAFE.putInt(buffer, CAPACITY, capacity);
return buffer;
}
}
@@ -0,0 +1,382 @@
/*
* This class is backported from LWJGL3 under the BSD 3-clause "New" or "Revised" License
*/
package com.gtnewhorizons.angelica.compat.lwjgl;
import static com.gtnewhorizons.angelica.compat.lwjgl.CompatMemoryUtil.memPutDouble;
import static com.gtnewhorizons.angelica.compat.lwjgl.CompatMemoryUtil.memPutFloat;
import static com.gtnewhorizons.angelica.compat.lwjgl.CompatMemoryUtil.memPutInt;
import static com.gtnewhorizons.angelica.compat.lwjgl.CompatMemoryUtil.memPutLong;
import static com.gtnewhorizons.angelica.compat.lwjgl.CompatMemoryUtil.memPutShort;
import static com.gtnewhorizons.angelica.compat.lwjgl.CompatMemoryUtil.memSet;
import static com.gtnewhorizons.angelica.compat.lwjgl.CompatMemoryUtil.wrapBufferFloat;
import static com.gtnewhorizons.angelica.compat.lwjgl.CompatMemoryUtil.wrapBufferInt;
import com.gtnewhorizons.angelica.loading.AngelicaTweaker;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.util.Arrays;
import org.jetbrains.annotations.Nullable;
import org.lwjgl.BufferUtils;
import org.lwjgl.MemoryUtil;
/**
* An off-heap memory stack.
*
* <p>This class should be used in a thread-local manner for stack allocations.</p>
*
* @ see Configuration#STACK_SIZE
* @ see Configuration#DEBUG_STACK
*/
@SuppressWarnings("LombokGetterMayBeUsed")
public class MemoryStack extends Pointer.Default implements AutoCloseable {
private static final int DEFAULT_STACK_SIZE = /*Configuration.STACK_SIZE.get(64)*/ 64 * 1024;
private static final int DEFAULT_STACK_FRAMES = 8;
private static final ThreadLocal<MemoryStack> TLS = ThreadLocal.withInitial(MemoryStack::create);
static {
if (DEFAULT_STACK_SIZE < 0) {
throw new IllegalStateException("Invalid stack size.");
}
}
@SuppressWarnings({"FieldCanBeLocal", "unused"})
private final @Nullable ByteBuffer container;
private final int size;
private int pointer;
private int[] frames;
protected int frameIndex;
/**
* Creates a new {@code MemoryStack} backed by the specified memory region.
*
* <p>In the initial state, there is no active stack frame. The {@link #push} method must be used before any allocations.</p>
*
* @param container the backing memory buffer, may be null
* @param address the backing memory address
* @param size the backing memory size
*/
protected MemoryStack(@Nullable ByteBuffer container, long address, int size) {
super(address);
this.container = container;
this.size = size;
this.pointer = size;
this.frames = new int[DEFAULT_STACK_FRAMES];
}
/**
* Creates a new {@code MemoryStack} with the default size.
*
* <p>In the initial state, there is no active stack frame. The {@link #push} method must be used before any allocations.</p>
*/
public static MemoryStack create() {
return create(DEFAULT_STACK_SIZE);
}
/**
* Creates a new {@code MemoryStack} with the specified size.
*
* <p>In the initial state, there is no active stack frame. The {@link #push} method must be used before any allocations.</p>
*
* @param capacity the maximum number of bytes that may be allocated on the stack
*/
public static MemoryStack create(int capacity) {
return create(BufferUtils.createByteBuffer(capacity));
}
/**
* Creates a new {@code MemoryStack} backed by the specified memory buffer.
*
* <p>In the initial state, there is no active stack frame. The {@link #push} method must be used before any allocations.</p>
*
* @param buffer the backing memory buffer
*/
public static MemoryStack create(ByteBuffer buffer) {
long address = MemoryUtil.getAddress(buffer);
int size = buffer.remaining();
return new MemoryStack(buffer, address, size);
}
/**
* Creates a new {@code MemoryStack} backed by the specified memory region.
*
* <p>In the initial state, there is no active stack frame. The {@link #push} method must be used before any allocations.</p>
*
* @param address the backing memory address
* @param size the backing memory size
*/
public static MemoryStack ncreate(long address, int size) {
return new MemoryStack(null, address, size);
}
/**
* Stores the current stack pointer and pushes a new frame to the stack.
*
* <p>This method should be called when entering a method, before doing any stack allocations. When exiting a method, call the {@link #pop} method to
* restore the previous stack frame.</p>
*
* <p>Pairs of push/pop calls may be nested. Care must be taken to:</p>
* <ul>
* <li>match every push with a pop</li>
* <li>not call pop before push has been called at least once</li>
* <li>not nest push calls to more than the maximum supported depth</li>
* </ul>
*
* @return this stack
*/
public MemoryStack push() {
if (frameIndex == frames.length) {
frameOverflow();
}
frames[frameIndex++] = pointer;
return this;
}
private void frameOverflow() {
if (/*DEBUG*/ false) {
AngelicaTweaker.LOGGER.warn("[WARNING] Out of frame stack space (" + frames.length + ") in thread: " + Thread.currentThread());
}
frames = Arrays.copyOf(frames, frames.length * 3 / 2);
}
/**
* Pops the current stack frame and moves the stack pointer to the end of the previous stack frame.
*
* @return this stack
*/
public MemoryStack pop() {
pointer = frames[--frameIndex];
return this;
}
/**
* Calls {@link #pop} on this {@code MemoryStack}.
*
* <p>This method should not be used directly. It is called automatically when the {@code MemoryStack} is used as a resource in a try-with-resources
* statement.</p>
*/
@Override
public void close() {
//noinspection resource
pop();
}
/**
* Returns the address of the backing off-heap memory.
*
* <p>The stack grows "downwards", so the bottom of the stack is at {@code address + size}, while the top is at {@code address}.</p>
*/
public long getAddress() {
return address;
}
/**
* Returns the size of the backing off-heap memory.
*
* <p>This is the maximum number of bytes that may be allocated on the stack.</p>
*/
public int getSize() {
return size;
}
/**
* Returns the current frame index.
*
* <p>This is the current number of nested {@link #push} calls.</p>
*/
public int getFrameIndex() {
return frameIndex;
}
/** Returns the memory address at the current stack pointer. */
public long getPointerAddress() {
return address + (pointer & 0xFFFF_FFFFL);
}
/**
* Returns the current stack pointer.
*
* <p>The stack grows "downwards", so when the stack is empty {@code pointer} is equal to {@code size}. On every allocation {@code pointer} is reduced by
* the allocated size (after alignment) and {@code address + pointer} points to the first byte of the last allocation.</p>
*
* <p>Effectively, this methods returns how many more bytes may be allocated on the stack.</p>
*/
public int getPointer() {
return pointer;
}
/**
* Sets the current stack pointer.
*
* <p>This method directly manipulates the stack pointer. Using it irresponsibly may break the internal state of the stack. It should only be used in rare
* cases or in auto-generated code.</p>
*/
public void setPointer(int pointer) {
if (/*CHECKS*/ false) {
checkPointer(pointer);
}
this.pointer = pointer;
}
private void checkPointer(int pointer) {
if (pointer < 0 || size < pointer) {
throw new IndexOutOfBoundsException("Invalid stack pointer");
}
}
private static void checkAlignment(int alignment) {
if (Integer.bitCount(alignment) != 1) {
throw new IllegalArgumentException("Alignment must be a power-of-two value.");
}
}
/**
* Calls {@link #nmalloc(int, int)} with {@code alignment} equal to {@link Pointer#POINTER_SIZE POINTER_SIZE}.
*
* @param size the allocation size
*
* @return the memory address on the stack for the requested allocation
*/
public long nmalloc(int size) {
return nmalloc(POINTER_SIZE, size);
}
/**
* Allocates a block of {@code size} bytes of memory on the stack. The content of the newly allocated block of memory is not initialized, remaining with
* indeterminate values.
*
* @param alignment the required alignment
* @param size the allocation size
*
* @return the memory address on the stack for the requested allocation
*/
public long nmalloc(int alignment, int size) {
// Align address to the specified alignment
long address = (this.address + pointer - size) & ~Integer.toUnsignedLong(alignment - 1);
pointer = (int)(address - this.address);
if (/*CHECKS*/ false && pointer < 0) {
throw new OutOfMemoryError("Out of stack space.");
}
return address;
}
/**
* Allocates a block of memory on the stack for an array of {@code num} elements, each of them {@code size} bytes long, and initializes all its bits to
* zero.
*
* @param alignment the required element alignment
* @param num num the number of elements to allocate
* @param size the size of each element
*
* @return the memory address on the stack for the requested allocation
*/
public long ncalloc(int alignment, int num, int size) {
int bytes = num * size;
long address = nmalloc(alignment, bytes);
memSet(address, 0, bytes);
return address;
}
// -------------------------------------------------
/** Unsafe version of {@link #shorts(short)}. */
public long nshort(short value) {
long a = nmalloc(2, 2);
memPutShort(a, value);
return a;
}
// -------------------------------------------------
/** Int version of {@link #malloc(int)}. */
public IntBuffer mallocInt(int size) { return wrapBufferInt(nmalloc(4, size << 2), size); }
/** Unsafe version of {@link #ints(int)}. */
public long nint(int value) {
long a = nmalloc(4, 4);
memPutInt(a, value);
return a;
}
// -------------------------------------------------
/** Unsafe version of {@link #longs(long)}. */
public long nlong(long value) {
long a = nmalloc(8, 8);
memPutLong(a, value);
return a;
}
// -------------------------------------------------
/** Float version of {@link #malloc(int)}. */
public FloatBuffer mallocFloat(int size) { return wrapBufferFloat(nmalloc(4, size << 2), size); }
/** Unsafe version of {@link #floats(float)}. */
public long nfloat(float value) {
long a = nmalloc(4, 4);
memPutFloat(a, value);
return a;
}
// -------------------------------------------------
/** Unsafe version of {@link #doubles(double)}. */
public long ndouble(double value) {
long a = nmalloc(8, 8);
memPutDouble(a, value);
return a;
}
// -------------------------------------------------
// -------------------------------------------------
// -------------------------------------------------
/** Returns the stack of the current thread. */
public static MemoryStack stackGet() {
return TLS.get();
}
/**
* Calls {@link #push} on the stack of the current thread.
*
* @return the stack of the current thread.
*/
public static MemoryStack stackPush() {
return stackGet().push();
}
/**
* Calls {@link #pop} on the stack of the current thread.
*
* @return the stack of the current thread.
*/
public static MemoryStack stackPop() {
return stackGet().pop();
}
/** Thread-local version of {@link #nmalloc(int)}. */
public static long nstackMalloc(int size) { return stackGet().nmalloc(size); }
/** Thread-local version of {@link #nmalloc(int, int)}. */
public static long nstackMalloc(int alignment, int size) { return stackGet().nmalloc(alignment, size); }
/** Thread-local version of {@link #ncalloc}. */
public static long nstackCalloc(int alignment, int num, int size) { return stackGet().ncalloc(alignment, num, size); }
// -------------------------------------------------
}
@@ -0,0 +1,93 @@
/*
* This class is backported from LWJGL3 under the BSD 3-clause "New" or "Revised" License
*/
package com.gtnewhorizons.angelica.compat.lwjgl;
import static com.gtnewhorizons.angelica.compat.lwjgl.CompatMemoryUtil.NULL;
import static com.gtnewhorizons.angelica.compat.lwjgl.CompatMemoryUtil.UNSAFE;
import static org.lwjgl.LWJGLUtil.CHECKS;
import net.minecraft.util.Util;
import org.jetbrains.annotations.Nullable;
/**
* Pointer interface.
*
* <p>LWJGL can run on both 32bit and 64bit architectures. Since LWJGL applications deal with native memory directly, this interface provides necessary
* information about the underlying architecture of the running JVM process.</p>
*
* <p>When interacting with native functions, pointer values are mapped to Java {@code long}. LWJGL automatically converts long values to the correct pointer
* addresses when used in native code. Native functions sometimes require arrays of pointer values; the {@link PointerBuffer} class may be used for that
* purpose. It has an API similar to a {@link java.nio.LongBuffer} but handles pointer casts automatically.</p>
*/
public interface Pointer {
/** The pointer size in bytes. Will be 4 on a 32bit JVM and 8 on a 64bit one. */
int POINTER_SIZE = UNSAFE.addressSize();
/** The pointer size power-of-two. Will be 2 on a 32bit JVM and 3 on a 64bit one. */
int POINTER_SHIFT = POINTER_SIZE == 8 ? 3 : 2;
/** The value of {@code sizeof(long)} for the current platform. */
int CLONG_SIZE = POINTER_SIZE == 8 && Util.getOSType() == Util.EnumOS.WINDOWS ? 4 : POINTER_SIZE;
/** The value of {@code sizeof(long)} as a power-of-two. */
int CLONG_SHIFT = CLONG_SIZE == 8 ? 3 : 2;
/** Will be true on a 32bit JVM. */
boolean BITS32 = POINTER_SIZE * 8 == 32;
/** Will be true on a 64bit JVM. */
boolean BITS64 = POINTER_SIZE * 8 == 64;
/**
* Returns the raw pointer address as a {@code long} value.
*
* @return the pointer address
*/
long address();
/** Default {@link Pointer} implementation. */
abstract class Default implements Pointer {
// Removed final due to JDK-8139758. TODO: Restore if the fix is backported to JDK 8.
protected long address;
protected Default(long address) {
if (CHECKS && address == NULL) {
throw new NullPointerException();
}
this.address = address;
}
@Override
public long address() {
return address;
}
public boolean equals(@Nullable Object o) {
if (this == o) {
return true;
}
if (!(o instanceof Pointer)) {
return false;
}
Pointer that = (Pointer)o;
return address == that.address();
}
public int hashCode() {
return (int)(address ^ (address >>> 32));
}
@Override
public String toString() {
return String.format("%s pointer [0x%X]", getClass().getSimpleName(), address);
}
}
}
@@ -1,19 +0,0 @@
package com.gtnewhorizons.angelica.compat.mojang;
import me.jellysquid.mods.sodium.client.model.quad.properties.ModelQuadFacing;
public enum Axis {
X,
Y,
Z;
public static Axis fromDirection(ModelQuadFacing dir) {
return switch (dir) {
case DOWN, UP -> Y;
case NORTH, SOUTH -> Z;
case WEST, EAST -> X;
default -> null;
};
}
}
@@ -1,99 +0,0 @@
package com.gtnewhorizons.angelica.compat.mojang;
import net.minecraft.util.MathHelper;
import net.minecraft.world.ChunkPosition;
import net.minecraftforge.common.util.ForgeDirection;
import org.joml.Vector3i;
import java.math.RoundingMode;
import static com.google.common.math.IntMath.log2;
// Should we keep this?
public class BlockPos extends Vector3i {
private static final int SIZE_BITS_X = 1 + log2(MathHelper.roundUpToPowerOfTwo(30000000), RoundingMode.UNNECESSARY);
private static final int SIZE_BITS_Z = SIZE_BITS_X;
private static final int SIZE_BITS_Y = 64 - SIZE_BITS_X - SIZE_BITS_Z;
private static final long BITS_X = (1L << SIZE_BITS_X) - 1L;
private static final long BITS_Y = (1L << SIZE_BITS_Y) - 1L;
private static final long BITS_Z = (1L << SIZE_BITS_Z) - 1L;
private static final int BIT_SHIFT_Z = SIZE_BITS_Y;
private static final int BIT_SHIFT_X = SIZE_BITS_Y + SIZE_BITS_Z;
public BlockPos() {
super();
}
public BlockPos(int x, int y, int z) {
super(x, y, z);
}
public BlockPos(ChunkPosition chunkPosition) {
super(chunkPosition.chunkPosX, chunkPosition.chunkPosY, chunkPosition.chunkPosZ);
}
public int getX() {
return this.x;
}
public int getY() {
return this.y;
}
public int getZ() {
return this.z;
}
public BlockPos set(int x, int y, int z) {
super.set(x, y, z);
return this;
}
/**
* This method does NOT mutate the BlockPos
*/
public BlockPos offset(ForgeDirection d) {
return new BlockPos(this.x + d.offsetX, this.y + d.offsetY, this.z + d.offsetZ);
}
/**
* This method does NOT mutate the BlockPos
*/
public BlockPos down() {
return offset(ForgeDirection.DOWN);
}
/**
* This method does NOT mutate the BlockPos
*/
public BlockPos up() {
return offset(ForgeDirection.UP);
}
public long asLong() {
return asLong(this.x, this.y, this.z);
}
public static long asLong(int x, int y, int z) {
long l = 0L;
l |= ((long)x & BITS_X) << BIT_SHIFT_X;
l |= ((long)y & BITS_Y) << 0;
l |= ((long)z & BITS_Z) << BIT_SHIFT_Z;
return l;
}
public static int unpackLongX(long packedPos) {
return (int)(packedPos << 64 - BIT_SHIFT_X - SIZE_BITS_X >> 64 - SIZE_BITS_X);
}
public static int unpackLongY(long packedPos) {
return (int)(packedPos << 64 - SIZE_BITS_Y >> 64 - SIZE_BITS_Y);
}
public static int unpackLongZ(long packedPos) {
return (int)(packedPos << 64 - BIT_SHIFT_Z - SIZE_BITS_Z >> 64 - SIZE_BITS_Z);
}
public static class Mutable extends BlockPos {
}
}
@@ -1,5 +1,6 @@
package com.gtnewhorizons.angelica.compat.mojang;
import com.gtnewhorizon.gtnhlib.blockpos.BlockPos;
import com.gtnewhorizons.angelica.rendering.RenderingState;
import lombok.Getter;
import net.minecraft.client.Minecraft;
@@ -13,7 +14,7 @@ import org.joml.Vector4f;
@Getter
public class Camera {
final Vector3d pos = new Vector3d();
final BlockPos.Mutable blockPos = new BlockPos.Mutable();
final BlockPos blockPos = new BlockPos();
float pitch;
float yaw;
EntityLivingBase entity;
@@ -1,8 +1,8 @@
package com.gtnewhorizons.angelica.compat.mojang;
import com.gtnewhorizon.gtnhlib.blockpos.BlockPos;
import it.unimi.dsi.fastutil.ints.IntArrayFIFOQueue;
import it.unimi.dsi.fastutil.ints.IntPriorityQueue;
import me.jellysquid.mods.sodium.common.util.DirectionUtil;
import net.minecraftforge.common.util.ForgeDirection;
import java.util.BitSet;
@@ -17,7 +17,7 @@ public class ChunkOcclusionDataBuilder {
private static final int STEP_X = (int)Math.pow(16.0, 0.0);
private static final int STEP_Z = (int)Math.pow(16.0, 1.0);
private static final int STEP_Y = (int)Math.pow(16.0, 2.0);
private static final ForgeDirection[] DIRECTIONS = DirectionUtil.ALL_DIRECTIONS;
private static final ForgeDirection[] DIRECTIONS = ForgeDirection.VALID_DIRECTIONS;
private final BitSet closed = new BitSet(4096);
private static final int[] EDGE_POINTS = new int[1352];
@@ -1,5 +1,7 @@
package com.gtnewhorizons.angelica.compat.mojang;
import com.gtnewhorizon.gtnhlib.blockpos.BlockPos;
// See if we can merge/mixin/extend ChunkCoordIntPair?
public class ChunkPos {
public static long INT_MASK = (1L << Integer.SIZE) - 1;
@@ -1,5 +1,6 @@
package com.gtnewhorizons.angelica.compat.mojang;
import com.gtnewhorizon.gtnhlib.blockpos.BlockPos;
import org.joml.Vector3i;
// See if we can merge/mixin/extend ChunkPosition maybe?
@@ -35,10 +36,10 @@ public class ChunkSectionPos extends Vector3i {
return coord & 15;
}
public static short packLocal(BlockPos pos) {
int i = getLocalCoord(pos.x);
int j = getLocalCoord(pos.y);
int k = getLocalCoord(pos.z);
public static short packLocal(int x, int y, int z) {
final int i = getLocalCoord(x);
final int j = getLocalCoord(y);
final int k = getLocalCoord(z);
return (short)(i << 8 | k << 4 | j << 0);
}
@@ -1,37 +0,0 @@
package com.gtnewhorizons.angelica.compat.mojang;
import com.google.common.collect.ImmutableList;
import com.gtnewhorizons.angelica.compat.mojang.VertexFormatElement.Type;
import com.gtnewhorizons.angelica.compat.mojang.VertexFormatElement.Usage;
import com.gtnewhorizons.angelica.compat.nd.writers.ItemVBOQuadWriter;
import com.gtnewhorizons.angelica.compat.nd.writers.PositionColorTextureQuadWriter;
import com.gtnewhorizons.angelica.compat.nd.writers.PositionQuadWriter;
import com.gtnewhorizons.angelica.compat.nd.writers.PositionTextureColorQuadWriter;
import com.gtnewhorizons.angelica.compat.nd.writers.PositionTextureQuadWriter;
public class DefaultVertexFormat {
public static final VertexFormatElement POSITION_ELEMENT = new VertexFormatElement(0, Type.FLOAT, Usage.POSITION, 3);
public static final VertexFormatElement COLOR_ELEMENT = new VertexFormatElement(0, Type.UBYTE, Usage.COLOR, 4);
public static final VertexFormatElement TEXTURE_ELEMENT = new VertexFormatElement(0, Type.FLOAT, Usage.UV, 2);
public static final VertexFormatElement LIGHT_ELEMENT = new VertexFormatElement(1, Type.SHORT, Usage.UV, 2);
// TODO: The overlay element index is wrong, need to find a 1.7.10 equivalent
public static final VertexFormatElement OVERLAY_ELEMENT = new VertexFormatElement(1, Type.SHORT, Usage.UV, 2);
public static final VertexFormatElement NORMAL_ELEMENT = new VertexFormatElement(0, Type.BYTE, Usage.NORMAL, 3);
public static final VertexFormatElement PADDING_ELEMENT = new VertexFormatElement(0, Type.BYTE, Usage.PADDING, 1);
public static final VertexFormat POSITION_TEXTURE_NORMAL = new VertexFormat(new ImmutableList.Builder<VertexFormatElement>().add(POSITION_ELEMENT).add(TEXTURE_ELEMENT).add(NORMAL_ELEMENT).add(PADDING_ELEMENT).build(), new ItemVBOQuadWriter());
public static final VertexFormat POSITION_COLOR_TEXTURE_LIGHT_NORMAL = new VertexFormat(new ImmutableList.Builder<VertexFormatElement>().add(POSITION_ELEMENT).add(COLOR_ELEMENT).add(TEXTURE_ELEMENT).add(LIGHT_ELEMENT).add(NORMAL_ELEMENT).add(PADDING_ELEMENT).build());
public static final VertexFormat POSITION_COLOR_TEXTURE_OVERLAY_LIGHT_NORMAL = new VertexFormat(new ImmutableList.Builder<VertexFormatElement>().add(POSITION_ELEMENT).add(COLOR_ELEMENT).add(TEXTURE_ELEMENT).add(OVERLAY_ELEMENT).add(LIGHT_ELEMENT).add(NORMAL_ELEMENT).add(PADDING_ELEMENT).build());
public static final VertexFormat POSITION_TEXTURE_COLOR_LIGHT = new VertexFormat(new ImmutableList.Builder<VertexFormatElement>().add(POSITION_ELEMENT).add(TEXTURE_ELEMENT).add(COLOR_ELEMENT).add(LIGHT_ELEMENT).build());
public static final VertexFormat POSITION = new VertexFormat(new ImmutableList.Builder<VertexFormatElement>().add(POSITION_ELEMENT).build(), new PositionQuadWriter());
public static final VertexFormat POSITION_COLOR = new VertexFormat(new ImmutableList.Builder<VertexFormatElement>().add(POSITION_ELEMENT).add(COLOR_ELEMENT).build());
public static final VertexFormat POSITION_COLOR_LIGHT = new VertexFormat(new ImmutableList.Builder<VertexFormatElement>().add(POSITION_ELEMENT).add(COLOR_ELEMENT).add(LIGHT_ELEMENT).build());
public static final VertexFormat POSITION_TEXTURE = new VertexFormat(new ImmutableList.Builder<VertexFormatElement>().add(POSITION_ELEMENT).add(TEXTURE_ELEMENT).build(), new PositionTextureQuadWriter());
public static final VertexFormat POSITION_COLOR_TEXTURE = new VertexFormat(new ImmutableList.Builder<VertexFormatElement>().add(POSITION_ELEMENT).add(COLOR_ELEMENT).add(TEXTURE_ELEMENT).build(), new PositionColorTextureQuadWriter());
public static final VertexFormat POSITION_TEXTURE_COLOR = new VertexFormat(new ImmutableList.Builder<VertexFormatElement>().add(POSITION_ELEMENT).add(TEXTURE_ELEMENT).add(COLOR_ELEMENT).build(), new PositionTextureColorQuadWriter());
public static final VertexFormat POSITION_COLOR_TEX_LIGHTMAP = new VertexFormat(new ImmutableList.Builder<VertexFormatElement>().add(POSITION_ELEMENT).add(COLOR_ELEMENT).add(TEXTURE_ELEMENT).add(LIGHT_ELEMENT).build());
public static final VertexFormat POSITION_TEXTURE_LIGHT_COLOR = new VertexFormat(new ImmutableList.Builder<VertexFormatElement>().add(POSITION_ELEMENT).add(TEXTURE_ELEMENT).add(LIGHT_ELEMENT).add(COLOR_ELEMENT).build());
public static final VertexFormat POSITION_TEXTURE_COLOR_NORMAL = new VertexFormat(new ImmutableList.Builder<VertexFormatElement>().add(POSITION_ELEMENT).add(TEXTURE_ELEMENT).add(COLOR_ELEMENT).add(NORMAL_ELEMENT).add(PADDING_ELEMENT).build());
}
@@ -0,0 +1,5 @@
package com.gtnewhorizons.angelica.compat.mojang;
public interface Drawable {
default void render(int mouseX, int mouseY, float delta) {}
}
@@ -0,0 +1,29 @@
package com.gtnewhorizons.angelica.compat.mojang;
public interface Element {
default boolean mouseClicked(double mouseX, double mouseY, int button) {
return false;
}
default boolean mouseDragged(double mouseX, double mouseY, int button) {
return false;
}
default boolean mouseReleased(double mouseX, double mouseY, int button) {
return false;
}
default boolean mouseScrolled(double mouseX, double mouseY, double amount) {
return false;
}
default boolean keyTyped(char typedChar, int keyCode) { return false; }
default boolean isMouseOver(double mouseX, double mouseY) {
return false;
}
default boolean changeFocus(boolean lookForwards) {
return false;
}
}
@@ -1,18 +1,17 @@
package com.gtnewhorizons.angelica.compat.mojang;
import lombok.Getter;
import net.coderbot.iris.Iris;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;
import javax.imageio.ImageIO;
import com.gtnewhorizons.angelica.compat.lwjgl.MemoryStack;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import javax.imageio.ImageIO;
import lombok.Getter;
import net.coderbot.iris.Iris;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;
// TBD
public class NativeImage extends BufferedImage {
@@ -59,12 +58,14 @@ public class NativeImage extends BufferedImage {
// final int width = GL11.glGetTexLevelParameteri(GL11.GL_TEXTURE_2D, level, GL11.GL_TEXTURE_WIDTH);
// final int height = GL11.glGetTexLevelParameteri(GL11.GL_TEXTURE_2D, level, GL11.GL_TEXTURE_HEIGHT);
IntBuffer buffer = BufferUtils.createIntBuffer(size);
int[] data = new int[size];
try (final MemoryStack stack = MemoryStack.stackPush()) {
final IntBuffer buffer = stack.mallocInt(size);
GL11.glGetTexImage(GL11.GL_TEXTURE_2D, level, format.glFormat, GL12.GL_UNSIGNED_INT_8_8_8_8_REV, buffer);
GL11.glGetTexImage(GL11.GL_TEXTURE_2D, level, format.glFormat, GL12.GL_UNSIGNED_INT_8_8_8_8_REV, buffer);
buffer.get(data);
setRGB(0, 0, width, height, data, 0, width);
int[] data = new int[size];
buffer.get(data);
setRGB(0, 0, width, height, data, 0, width);
}
}
public void writeToFile(File file) throws IOException{
try {
@@ -0,0 +1,97 @@
package com.gtnewhorizons.angelica.compat.mojang;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.ListIterator;
import java.util.Optional;
import java.util.function.BooleanSupplier;
import java.util.function.Supplier;
public interface ParentElement extends Element {
List<? extends Element> children();
default Optional<Element> hoveredElement(double mouseX, double mouseY) {
for(Element element : this.children()) {
if (element.isMouseOver(mouseX, mouseY)) {
return Optional.of(element);
}
}
return Optional.empty();
}
default boolean mouseClicked(double mouseX, double mouseY, int button) {
for(Element element : this.children()) {
if (element.mouseClicked(mouseX, mouseY, button)) {
this.setFocused(element);
if (button == 0) {
this.setDragging(true);
}
return true;
}
}
return false;
}
default boolean mouseReleased(double mouseX, double mouseY, int button) {
this.setDragging(false);
return this.hoveredElement(mouseX, mouseY).filter((element) -> element.mouseReleased(mouseX, mouseY, button)).isPresent();
}
default boolean mouseDragged(double mouseX, double mouseY, int button) {
return this.getFocused() != null && this.isDragging() && button == 0 && this.getFocused().mouseDragged(mouseX, mouseY, button);
}
boolean isDragging();
void setDragging(boolean dragging);
default boolean mouseScrolled(double mouseX, double mouseY, double amount) {
return this.hoveredElement(mouseX, mouseY).filter((element) -> element.mouseScrolled(mouseX, mouseY, amount)).isPresent();
}
default boolean keyTyped(char typedChar, int keyCode) {
return this.getFocused() != null && this.getFocused().keyTyped(typedChar, keyCode);
}
@Nullable
Element getFocused();
void setFocused(@Nullable Element focused);
default boolean changeFocus(boolean lookForwards) {
final Element element = this.getFocused();
if (element != null && element.changeFocus(lookForwards)) {
return true;
} else {
final List<? extends Element> list = this.children();
final int i = list.indexOf(element);
final int j;
if (element != null && i >= 0) {
j = i + (lookForwards ? 1 : 0);
} else if (lookForwards) {
j = 0;
} else {
j = list.size();
}
final ListIterator<? extends Element> listIterator = list.listIterator(j);
final BooleanSupplier booleanSupplier = lookForwards ? listIterator::hasNext : listIterator::hasPrevious;
final Supplier<? extends Element> supplier = lookForwards ? listIterator::next : listIterator::previous;
Element element2;
do {
if (!booleanSupplier.getAsBoolean()) {
this.setFocused(null);
return false;
}
element2 = supplier.get();
} while(!element2.changeFocus(lookForwards));
this.setFocused(element2);
return true;
}
}
}
@@ -1,83 +0,0 @@
package com.gtnewhorizons.angelica.compat.mojang;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL15;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
public class VertexBuffer implements AutoCloseable {
private int id;
private int vertexCount;
private VertexFormat format;
public VertexBuffer() {
this.id = GL15.glGenBuffers();
}
public VertexBuffer(VertexFormat format) {
this();
this.format = format;
}
public void bind() {
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, this.id);
}
public void unbind() {
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
}
public void upload(ByteBuffer buffer, int vertexCount) {
if (this.id == -1) return;
this.vertexCount = vertexCount;
this.bind();
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, buffer, GL15.GL_STATIC_DRAW);
this.unbind();
}
public VertexBuffer upload(ByteBuffer buffer) {
if(format == null) throw new IllegalStateException("No format specified for VBO upload");
upload(buffer, buffer.capacity() / format.getVertexSize());
return this;
}
public void close() {
if (this.id >= 0) {
GL15.glDeleteBuffers(this.id);
this.id = -1;
}
}
public void draw(FloatBuffer floatBuffer, int mode) {
GL11.glPushMatrix();
GL11.glLoadIdentity();
GL11.glMultMatrix(floatBuffer);
draw(mode);
GL11.glPopMatrix();
}
public void draw(int mode) {
GL11.glDrawArrays(mode, 0, this.vertexCount);
}
public void setupState() {
if(format == null) throw new IllegalStateException("No format specified for VBO setup");
bind();
format.setupBufferState(0L);
}
public void cleanupState() {
format.clearBufferState();
unbind();
}
public void render(int mode) {
if(format == null) throw new IllegalStateException("No format specified for VBO render");
bind();
format.setupBufferState(0L);
draw(mode);
format.clearBufferState();
unbind();
}
}
@@ -1,84 +0,0 @@
package com.gtnewhorizons.angelica.compat.mojang;
import com.google.common.collect.ImmutableList;
import com.gtnewhorizons.angelica.compat.nd.IWriteQuads;
import com.gtnewhorizons.angelica.compat.nd.Quad;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntList;
import lombok.Getter;
import net.coderbot.iris.block_rendering.BlockRenderingSettings;
import net.coderbot.iris.vertices.ImmediateState;
import net.coderbot.iris.vertices.IrisVertexFormats;
import java.nio.ByteBuffer;
import java.util.List;
public class VertexFormat {
@Getter
protected final ImmutableList<VertexFormatElement> elements;
protected final IntList offsets = new IntArrayList();
@Getter
protected final int vertexSize;
protected IWriteQuads quadWriter;
public VertexFormat(ImmutableList<VertexFormatElement> elements) {
this(elements, null);
}
public VertexFormat(ImmutableList<VertexFormatElement> elements, IWriteQuads quadWriter) {
this.elements = elements;
int i = 0;
for (VertexFormatElement element : elements) {
offsets.add(i);
i += element.getByteSize();
}
vertexSize = i;
this.quadWriter = quadWriter;
}
public void setupBufferState(long l) {
if (BlockRenderingSettings.INSTANCE.shouldUseExtendedVertexFormat() && ImmediateState.renderWithExtendedVertexFormat) {
if (this == DefaultVertexFormat.POSITION_COLOR_TEXTURE_LIGHT_NORMAL || this == DefaultVertexFormat.POSITION_COLOR_TEX_LIGHTMAP) {
IrisVertexFormats.TERRAIN.setupBufferState(l);
return;
} else if (this == DefaultVertexFormat.POSITION_COLOR_TEXTURE_OVERLAY_LIGHT_NORMAL) {
IrisVertexFormats.ENTITY.setupBufferState(l);
return;
}
}
final int i = this.getVertexSize();
final List<VertexFormatElement> list = this.getElements();
for(int j = 0; j < list.size(); ++j) {
list.get(j).setupBufferState(l + this.offsets.getInt(j), i);
}
}
public void clearBufferState() {
if (BlockRenderingSettings.INSTANCE.shouldUseExtendedVertexFormat() && ImmediateState.renderWithExtendedVertexFormat) {
if (this == DefaultVertexFormat.POSITION_COLOR_TEXTURE_LIGHT_NORMAL || this == DefaultVertexFormat.POSITION_COLOR_TEX_LIGHTMAP) {
IrisVertexFormats.TERRAIN.clearBufferState();
return;
} else if ( this == DefaultVertexFormat.POSITION_COLOR_TEXTURE_OVERLAY_LIGHT_NORMAL) {
IrisVertexFormats.ENTITY.clearBufferState();
return;
}
}
for (VertexFormatElement vertexformatelement : this.getElements()) {
vertexformatelement.clearBufferState();
}
}
public boolean canWriteQuads() {
return quadWriter != null;
}
public void writeQuad(Quad quad, ByteBuffer byteBuffer) {
if(quadWriter == null) {
throw new IllegalStateException("No quad writer set");
}
quadWriter.writeQuad(quad, byteBuffer);
}
}
@@ -1,107 +0,0 @@
package com.gtnewhorizons.angelica.compat.mojang;
import lombok.Getter;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL13;
import org.lwjgl.opengl.GL20;
import java.util.function.IntConsumer;
@Getter
public class VertexFormatElement {
protected final Type type;
protected final Usage usage;
protected final int index;
protected final int count;
protected final int byteSize;
public VertexFormatElement(int index, Type type, Usage usage, int count) {
this.index = index;
this.type = type;
this.usage = usage;
this.count = count;
this.byteSize = type.getSize() * count;
}
public void setupBufferState(long l, int i) {
this.usage.setupBufferState(this.count, this.type.getGlType(), i, l, this.index);
}
public void clearBufferState() {
this.usage.clearBufferState(this.index);
}
public enum Usage {
POSITION("Position", (i, j, k, l, m) -> {
GL11.glVertexPointer(i, j, k, l);
GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY);
}, (i) -> GL11.glDisableClientState(GL11.GL_VERTEX_ARRAY)),
NORMAL("Normal", (i, j, k, l, m) -> {
GL11.glNormalPointer(j, k, l);
GL11.glEnableClientState(GL11.GL_NORMAL_ARRAY);
}, (i) -> GL11.glDisableClientState(GL11.GL_NORMAL_ARRAY)),
COLOR("Vertex Color", (i, j, k, l, m) -> {
GL11.glColorPointer(i, j, k, l);
GL11.glEnableClientState(GL11.GL_COLOR_ARRAY);
}, i -> GL11.glDisableClientState(GL11.GL_COLOR_ARRAY)),
UV("UV", (i, j, k, l, m) -> {
GL13.glClientActiveTexture(GL13.GL_TEXTURE0 + m);
GL11.glTexCoordPointer(i, j, k, l);
GL11.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
GL13.glClientActiveTexture(GL13.GL_TEXTURE0);
}, i -> {
GL13.glClientActiveTexture(GL13.GL_TEXTURE0 + i);
GL11.glDisableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
GL13.glClientActiveTexture(GL13.GL_TEXTURE0);
}),
PADDING("Padding", (i, j, k, l, m) -> {}, i-> {}),
GENERIC("Generic", (i, j, k, l, m) -> {
GL20.glEnableVertexAttribArray(m);
GL20.glVertexAttribPointer(m, i, j, false, k, l);
}, GL20::glDisableVertexAttribArray);
@Getter private final String name;
private final SetupState setupState;
private final IntConsumer clearState;
Usage(String name, SetupState setupState, IntConsumer clearState) {
this.name = name;
this.setupState = setupState;
this.clearState = clearState;
}
private void setupBufferState(int i, int j, int k, long l, int m) {
this.setupState.setupBufferState(i, j, k, l, m);
}
public void clearBufferState(int i) {
this.clearState.accept(i);
}
interface SetupState {
void setupBufferState(int i, int j, int k, long l, int m);
}
}
@Getter
public enum Type {
FLOAT(4, "Float", GL11.GL_FLOAT),
UBYTE(1, "Unsigned Byte", GL11.GL_UNSIGNED_BYTE),
BYTE(1, "Byte", GL11.GL_BYTE),
USHORT(2, "Unsigned Short", GL11.GL_UNSIGNED_SHORT),
SHORT(2, "Short", GL11.GL_SHORT),
UINT(4, "Unsigned Int", GL11.GL_UNSIGNED_INT),
INT(4, "Int", GL11.GL_INT);
private final int size;
private final String name;
private final int glType;
Type(int size, String name, int glType) {
this.size = size;
this.name = name;
this.glType = glType;
}
}
}
@@ -1,7 +0,0 @@
package com.gtnewhorizons.angelica.compat.nd;
import java.nio.ByteBuffer;
public interface IWriteQuads {
void writeQuad(Quad quad, ByteBuffer buf);
}
@@ -1,179 +0,0 @@
package com.gtnewhorizons.angelica.compat.nd;
import me.jellysquid.mods.sodium.client.model.quad.ModelQuadView;
import me.jellysquid.mods.sodium.client.model.quad.properties.ModelQuadFacing;
import me.jellysquid.mods.sodium.client.render.pipeline.BlockRenderer;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraftforge.common.util.ForgeDirection;
import org.joml.Vector3f;
import org.lwjgl.opengl.GL11;
import java.util.Locale;
public class Quad implements ModelQuadView {
// Adapted from Neodymium
private final static int DEFAULT_BRIGHTNESS = 15 << 20 | 15 << 4;
private final static int DEFAULT_COLOR = 0xFFFFFFFF;
public float[] xs = new float[4];
public float[] ys = new float[4];
public float[] zs = new float[4];
public float[] us = new float[4];
public float[] vs = new float[4];
public int[] cs = new int[4];
public int[] ns = new int[4];
public int[] bs = new int[4];
public boolean deleted;
public ModelQuadFacing normal;
private final Vector3f vectorA = new Vector3f(), vectorB = new Vector3f(), vectorC = new Vector3f();
private boolean hasColor;
private boolean hasShade;
private boolean hasNormals;
public boolean hasColor() {
return this.hasColor;
}
public int[] getColors() {
return this.cs;
}
public boolean hasShade() {
return this.hasShade;
}
public boolean hasNormals() {
return this.hasNormals;
}
public ForgeDirection getFace() {
// TODO: Sodium/Quad Facing
return ForgeDirection.UP;
}
@Override
public float getX(int idx) {
return xs[idx];
}
@Override
public float getY(int idx) {
return ys[idx];
}
@Override
public float getZ(int idx) {
return zs[idx];
}
@Override
public int getColor(int idx) {
return cs[idx];
}
@Override
public float getTexU(int idx) {
return us[idx];
}
@Override
public float getTexV(int idx) {
return vs[idx];
}
@Override
public int getFlags() {
return 0;
}
@Override
public int getLight(int idx) {
return bs[idx];
}
@Override
public int getNormal(int idx) {
return ns[idx];
}
@Override
public int getColorIndex() {
return 0;
}
@Override
public TextureAtlasSprite rubidium$getSprite() {
return null;
}
private void read(int[] rawBuffer, int offset, float offsetX, float offsetY, float offsetZ, int drawMode, BlockRenderer.Flags flags) {
int vertices = drawMode == GL11.GL_TRIANGLES ? 3 : 4;
for(int vi = 0; vi < vertices; vi++) {
int i = offset + vi * 8;
xs[vi] = Float.intBitsToFloat(rawBuffer[i + 0]) + offsetX;
ys[vi] = Float.intBitsToFloat(rawBuffer[i + 1]) + offsetY;
zs[vi] = Float.intBitsToFloat(rawBuffer[i + 2]) + offsetZ;
us[vi] = Float.intBitsToFloat(rawBuffer[i + 3]);
vs[vi] = Float.intBitsToFloat(rawBuffer[i + 4]);
cs[vi] = flags.hasColor ? rawBuffer[i + 5] : DEFAULT_COLOR;
ns[vi] = flags.hasNormals ? rawBuffer[i + 6] : 0;
bs[vi] = flags.hasBrightness ? rawBuffer[i + 7] : DEFAULT_BRIGHTNESS;
this.hasColor = flags.hasColor;
this.hasShade = flags.hasBrightness;
this.hasNormals = flags.hasNormals;
i += 8;
}
if(vertices == 3) {
// Quadrangulate!
xs[3] = xs[2];
ys[3] = ys[2];
zs[3] = zs[2];
us[3] = us[2];
vs[3] = vs[2];
bs[3] = bs[2];
cs[3] = cs[2];
ns[3] = ns[2];
}
}
public void setState(int[] rawBuffer, int offset, BlockRenderer.Flags flags, int drawMode, float offsetX, float offsetY, float offsetZ) {
deleted = false;
read(rawBuffer, offset, offsetX, offsetY, offsetZ, drawMode, flags);
if(xs[0] == xs[1] && xs[1] == xs[2] && xs[2] == xs[3] && ys[0] == ys[1] && ys[1] == ys[2] && ys[2] == ys[3]) {
// ignore empty quads (e.g. alpha pass of EnderIO item conduits)
deleted = true;
return;
}
vectorA.set(xs[1] - xs[0], ys[1] - ys[0], zs[1] - zs[0]);
vectorB.set(xs[2] - xs[1], ys[2] - ys[1], zs[2] - zs[1]);
vectorA.cross(vectorB, vectorC);
normal = ModelQuadFacing.fromVector(vectorC);
}
public static boolean isValid(Quad q) {
return q != null && !q.deleted;
}
@Override
public String toString() {
return String.format(Locale.ENGLISH, "%s[(%.1f, %.1f, %.1f), (%.1f, %.1f, %.1f), (%.1f, %.1f, %.1f), (%.1f, %.1f, %.1f)]", deleted ? "XXX " : "", xs[0], ys[0], zs[0], xs[1], ys[1], zs[1], xs[2], ys[2], zs[2], xs[3], ys[3], zs[3]);
}
}
@@ -1,7 +1,7 @@
package com.gtnewhorizons.angelica.compat.nd.writers;
import com.gtnewhorizons.angelica.compat.nd.IWriteQuads;
import com.gtnewhorizons.angelica.compat.nd.Quad;
import com.gtnewhorizon.gtnhlib.client.renderer.quad.QuadView;
import com.gtnewhorizon.gtnhlib.client.renderer.quad.writers.IWriteQuads;
import java.nio.ByteBuffer;
@@ -17,7 +17,7 @@ public class ItemVBOQuadWriter implements IWriteQuads {
this.direct = direct;
}
@Override
public void writeQuad(Quad quad, ByteBuffer buf) {
public void writeQuad(QuadView quad, ByteBuffer buf) {
if(direct) {
writeQuadDirect(quad, buf);
} else {
@@ -25,11 +25,11 @@ public class ItemVBOQuadWriter implements IWriteQuads {
}
}
protected void writeQuadDirect(Quad quad, ByteBuffer buf) {
protected void writeQuadDirect(QuadView quad, ByteBuffer buf) {
throw new UnsupportedOperationException("Direct mode not supported yet");
}
protected void writeQuadIndirect(Quad quad, ByteBuffer buf) {
protected void writeQuadIndirect(QuadView quad, ByteBuffer buf) {
for(int idx = 0; idx < 4; ++idx) {
// Position
buf.putFloat(quad.getX(idx));
@@ -1,7 +1,7 @@
package com.gtnewhorizons.angelica.compat.nd.writers;
import com.gtnewhorizons.angelica.compat.nd.IWriteQuads;
import com.gtnewhorizons.angelica.compat.nd.Quad;
import com.gtnewhorizon.gtnhlib.client.renderer.quad.QuadView;
import com.gtnewhorizon.gtnhlib.client.renderer.quad.writers.IWriteQuads;
import java.nio.ByteBuffer;
@@ -17,7 +17,7 @@ public class PositionColorTextureQuadWriter implements IWriteQuads {
this.direct = direct;
}
@Override
public void writeQuad(Quad quad, ByteBuffer buf) {
public void writeQuad(QuadView quad, ByteBuffer buf) {
if(direct) {
writeQuadDirect(quad, buf);
} else {
@@ -25,11 +25,11 @@ public class PositionColorTextureQuadWriter implements IWriteQuads {
}
}
protected void writeQuadDirect(Quad quad, ByteBuffer buf) {
protected void writeQuadDirect(QuadView quad, ByteBuffer buf) {
throw new UnsupportedOperationException("Direct mode not supported yet");
}
protected void writeQuadIndirect(Quad quad, ByteBuffer buf) {
protected void writeQuadIndirect(QuadView quad, ByteBuffer buf) {
for(int idx = 0; idx < 4; ++idx) {
// Position
buf.putFloat(quad.getX(idx));
@@ -1,7 +1,7 @@
package com.gtnewhorizons.angelica.compat.nd.writers;
import com.gtnewhorizons.angelica.compat.nd.IWriteQuads;
import com.gtnewhorizons.angelica.compat.nd.Quad;
import com.gtnewhorizon.gtnhlib.client.renderer.quad.QuadView;
import com.gtnewhorizon.gtnhlib.client.renderer.quad.writers.IWriteQuads;
import java.nio.ByteBuffer;
@@ -17,7 +17,7 @@ public class PositionQuadWriter implements IWriteQuads {
this.direct = direct;
}
@Override
public void writeQuad(Quad quad, ByteBuffer buf) {
public void writeQuad(QuadView quad, ByteBuffer buf) {
if(direct) {
writeQuadDirect(quad, buf);
} else {
@@ -25,11 +25,11 @@ public class PositionQuadWriter implements IWriteQuads {
}
}
protected void writeQuadDirect(Quad quad, ByteBuffer buf) {
protected void writeQuadDirect(QuadView quad, ByteBuffer buf) {
throw new UnsupportedOperationException("Direct mode not supported yet");
}
protected void writeQuadIndirect(Quad quad, ByteBuffer buf) {
protected void writeQuadIndirect(QuadView quad, ByteBuffer buf) {
for(int idx = 0; idx < 4; ++idx) {
// Position
buf.putFloat(quad.getX(idx));
@@ -1,7 +1,8 @@
package com.gtnewhorizons.angelica.compat.nd.writers;
import com.gtnewhorizons.angelica.compat.nd.IWriteQuads;
import com.gtnewhorizons.angelica.compat.nd.Quad;
import com.gtnewhorizon.gtnhlib.client.renderer.quad.QuadView;
import com.gtnewhorizon.gtnhlib.client.renderer.quad.writers.IWriteQuads;
import java.nio.ByteBuffer;
@@ -17,7 +18,7 @@ public class PositionTextureColorQuadWriter implements IWriteQuads {
this.direct = direct;
}
@Override
public void writeQuad(Quad quad, ByteBuffer buf) {
public void writeQuad(QuadView quad, ByteBuffer buf) {
if(direct) {
writeQuadDirect(quad, buf);
} else {
@@ -25,11 +26,11 @@ public class PositionTextureColorQuadWriter implements IWriteQuads {
}
}
protected void writeQuadDirect(Quad quad, ByteBuffer buf) {
protected void writeQuadDirect(QuadView quad, ByteBuffer buf) {
throw new UnsupportedOperationException("Direct mode not supported yet");
}
protected void writeQuadIndirect(Quad quad, ByteBuffer buf) {
protected void writeQuadIndirect(QuadView quad, ByteBuffer buf) {
for(int idx = 0; idx < 4; ++idx) {
// Position
buf.putFloat(quad.getX(idx));
@@ -1,7 +1,7 @@
package com.gtnewhorizons.angelica.compat.nd.writers;
import com.gtnewhorizons.angelica.compat.nd.IWriteQuads;
import com.gtnewhorizons.angelica.compat.nd.Quad;
import com.gtnewhorizon.gtnhlib.client.renderer.quad.QuadView;
import com.gtnewhorizon.gtnhlib.client.renderer.quad.writers.IWriteQuads;
import java.nio.ByteBuffer;
@@ -17,7 +17,7 @@ public class PositionTextureQuadWriter implements IWriteQuads {
this.direct = direct;
}
@Override
public void writeQuad(Quad quad, ByteBuffer buf) {
public void writeQuad(QuadView quad, ByteBuffer buf) {
if(direct) {
writeQuadDirect(quad, buf);
} else {
@@ -25,11 +25,11 @@ public class PositionTextureQuadWriter implements IWriteQuads {
}
}
protected void writeQuadDirect(Quad quad, ByteBuffer buf) {
protected void writeQuadDirect(QuadView quad, ByteBuffer buf) {
throw new UnsupportedOperationException("Direct mode not supported yet");
}
protected void writeQuadIndirect(Quad quad, ByteBuffer buf) {
protected void writeQuadIndirect(QuadView quad, ByteBuffer buf) {
for(int idx = 0; idx < 4; ++idx) {
// Position
buf.putFloat(quad.getX(idx));
@@ -1,21 +0,0 @@
package com.gtnewhorizons.angelica.compat.toremove;
import com.gtnewhorizons.angelica.compat.mojang.VertexFormat;
import lombok.Getter;
@Deprecated
public class DrawState {
@Getter
private final VertexFormat format;
@Getter
private final int vertexCount;
@Getter
private final int mode;
public DrawState(VertexFormat format, int vertexCount, int mode) {
this.format = format;
this.vertexCount = vertexCount;
this.mode = mode;
}
}
@@ -3,6 +3,7 @@ package com.gtnewhorizons.angelica.compat.toremove;
import com.google.common.collect.Queues;
import org.joml.Matrix3f;
import org.joml.Matrix4f;
import org.joml.Quaternionf;
import java.util.Deque;
@@ -79,6 +80,27 @@ public class MatrixStack {
}
public void multiply(Quaternionf quaternion) {
MatrixStack.Entry entry = this.matrixStack.getLast();
entry.model.rotate(quaternion);
entry.normal.rotate(quaternion);
}
public void multiply(Quaternionf quaternion, float originX, float originY, float originZ) {
MatrixStack.Entry entry = this.matrixStack.getLast();
entry.model.rotateAround(quaternion, originX, originY, originZ);
entry.normal.rotate(quaternion);
}
public void loadIdentity() {
MatrixStack.Entry entry = this.matrixStack.getLast();
entry.model.identity();
entry.normal.identity();
}
public void multiplyPositionMatrix(Matrix4f matrix) {
this.matrixStack.getLast().model.mul(matrix);
}
private static float invSqrt(float x) {
float xhalf = 0.5f * x;
@@ -1,8 +0,0 @@
package com.gtnewhorizons.angelica.compat.toremove;
@Deprecated
public class OverlayTexture {
// This is definitely wrong
public static final int NO_OVERLAY = 0;
}
@@ -1,8 +1,10 @@
package com.gtnewhorizons.angelica.compat.toremove;
import com.google.common.collect.ImmutableList;
import com.gtnewhorizons.angelica.compat.mojang.DefaultVertexFormat;
import com.gtnewhorizons.angelica.compat.mojang.VertexFormat;
import com.gtnewhorizon.gtnhlib.client.renderer.vertex.DefaultVertexFormat;
import com.gtnewhorizon.gtnhlib.client.renderer.vertex.VertexFormat;
import it.unimi.dsi.fastutil.Hash;
import it.unimi.dsi.fastutil.objects.ObjectOpenCustomHashSet;
import lombok.Getter;
@@ -58,7 +60,7 @@ public abstract class RenderLayer extends RenderPhase { // Aka: RenderType (Iris
}
public static RenderLayer getOutline(ResourceLocation texture, RenderPhase.Cull cull) {
return of("outline", DefaultVertexFormat.POSITION_COLOR_TEXTURE, 7, 256, RenderLayer.MultiPhaseParameters.builder().texture(new RenderPhase.Texture(texture, false, false)).cull(cull).depthTest(ALWAYS_DEPTH_TEST).alpha(ONE_TENTH_ALPHA).texturing(OUTLINE_TEXTURING).fog(NO_FOG).target(OUTLINE_TARGET).build(RenderLayer.OutlineMode.IS_OUTLINE));
return of("outline", DefaultVertexFormat.POSITION_COLOR_TEXTURE, 7, 256, RenderLayer.MultiPhaseParameters.builder().texture(new RenderPhase.Texture(texture, false, false)).cull(cull).depthTest(ALWAYS_DEPTH_TEST).alpha(ONE_TENTH_ALPHA).fog(NO_FOG).target(OUTLINE_TARGET).build(RenderLayer.OutlineMode.IS_OUTLINE));
}
public int mode() {
@@ -140,17 +142,15 @@ public abstract class RenderLayer extends RenderPhase { // Aka: RenderType (Iris
private final RenderPhase.DepthTest depthTest;
private final RenderPhase.Cull cull;
private final RenderPhase.Lightmap lightmap;
private final RenderPhase.Overlay overlay;
private final RenderPhase.Fog fog;
private final RenderPhase.Layering layering;
private final RenderPhase.Target target;
private final RenderPhase.Texturing texturing;
private final RenderPhase.WriteMaskState writeMaskState;
private final RenderPhase.LineWidth lineWidth;
private final OutlineMode outlineMode;
private final ImmutableList<RenderPhase> phases;
private MultiPhaseParameters(RenderPhase.Texture texture, RenderPhase.Transparency transparency, RenderPhase.DiffuseLighting diffuseLighting, RenderPhase.ShadeModel shadeModel, RenderPhase.Alpha alpha, RenderPhase.DepthTest depthTest, RenderPhase.Cull cull, RenderPhase.Lightmap lightmap, RenderPhase.Overlay overlay, RenderPhase.Fog fog, RenderPhase.Layering layering, RenderPhase.Target target, RenderPhase.Texturing texturing, RenderPhase.WriteMaskState writeMaskState, RenderPhase.LineWidth lineWidth, OutlineMode outlineMode) {
private MultiPhaseParameters(RenderPhase.Texture texture, RenderPhase.Transparency transparency, RenderPhase.DiffuseLighting diffuseLighting, RenderPhase.ShadeModel shadeModel, RenderPhase.Alpha alpha, RenderPhase.DepthTest depthTest, RenderPhase.Cull cull, RenderPhase.Lightmap lightmap, RenderPhase.Fog fog, RenderPhase.Layering layering, RenderPhase.Target target, RenderPhase.Texturing texturing, RenderPhase.WriteMaskState writeMaskState, OutlineMode outlineMode) {
this.texture = texture;
this.transparency = transparency;
this.diffuseLighting = diffuseLighting;
@@ -159,15 +159,13 @@ public abstract class RenderLayer extends RenderPhase { // Aka: RenderType (Iris
this.depthTest = depthTest;
this.cull = cull;
this.lightmap = lightmap;
this.overlay = overlay;
this.fog = fog;
this.layering = layering;
this.target = target;
this.texturing = texturing;
this.writeMaskState = writeMaskState;
this.lineWidth = lineWidth;
this.outlineMode = outlineMode;
this.phases = ImmutableList.of(this.texture, this.transparency, this.diffuseLighting, this.shadeModel, this.alpha, this.depthTest, this.cull, this.lightmap, this.overlay, this.fog, this.layering, this.target, new RenderPhase[]{this.texturing, this.writeMaskState, this.lineWidth});
this.phases = ImmutableList.of(this.texture, this.transparency, this.diffuseLighting, this.shadeModel, this.alpha, this.depthTest, this.cull, this.lightmap, this.fog, this.layering, this.target, this.texturing, this.writeMaskState);
}
public boolean equals(Object object) {
@@ -202,13 +200,11 @@ public abstract class RenderLayer extends RenderPhase { // Aka: RenderType (Iris
private RenderPhase.DepthTest depthTest;
private RenderPhase.Cull cull;
private RenderPhase.Lightmap lightmap;
private RenderPhase.Overlay overlay;
private RenderPhase.Fog fog;
private RenderPhase.Layering layering;
private RenderPhase.Target target;
private RenderPhase.Texturing texturing;
private RenderPhase.WriteMaskState writeMaskState;
private RenderPhase.LineWidth lineWidth;
private Builder() {
this.texture = RenderPhase.NO_TEXTURE ;
@@ -219,13 +215,11 @@ public abstract class RenderLayer extends RenderPhase { // Aka: RenderType (Iris
this.depthTest = RenderPhase.LEQUAL_DEPTH_TEST;
this.cull = RenderPhase.ENABLE_CULLING;
this.lightmap = RenderPhase.DISABLE_LIGHTMAP;
this.overlay = RenderPhase.DISABLE_OVERLAY_COLOR;
this.fog = RenderPhase.FOG;
this.layering = RenderPhase.NO_LAYERING;
this.target = RenderPhase.MAIN_TARGET;
this.texturing = RenderPhase.DEFAULT_TEXTURING;
this.writeMaskState = RenderPhase.ALL_MASK;
this.lineWidth = RenderPhase.FULL_LINE_WIDTH;
}
public Builder texture(RenderPhase.Texture texture) {
@@ -263,11 +257,6 @@ public abstract class RenderLayer extends RenderPhase { // Aka: RenderType (Iris
return this;
}
public Builder overlay(RenderPhase.Overlay overlay) {
this.overlay = overlay;
return this;
}
public Builder fog(RenderPhase.Fog fog) {
this.fog = fog;
return this;
@@ -288,7 +277,7 @@ public abstract class RenderLayer extends RenderPhase { // Aka: RenderType (Iris
}
public MultiPhaseParameters build(OutlineMode outlineMode) {
return new MultiPhaseParameters(this.texture, this.transparency, this.diffuseLighting, this.shadeModel, this.alpha, this.depthTest, this.cull, this.lightmap, this.overlay, this.fog, this.layering, this.target, this.texturing, this.writeMaskState, this.lineWidth, outlineMode);
return new MultiPhaseParameters(this.texture, this.transparency, this.diffuseLighting, this.shadeModel, this.alpha, this.depthTest, this.cull, this.lightmap, this.fog, this.layering, this.target, this.texturing, this.writeMaskState, outlineMode);
}
}
}
@@ -64,13 +64,8 @@ public abstract class RenderPhase {
protected static final Texture BLOCK_ATLAS_TEXTURE;
protected static final Texture NO_TEXTURE;
protected static final Texturing DEFAULT_TEXTURING;
protected static final Texturing OUTLINE_TEXTURING;
protected static final Texturing GLINT_TEXTURING;
protected static final Texturing ENTITY_GLINT_TEXTURING;
protected static final Lightmap ENABLE_LIGHTMAP;
protected static final Lightmap DISABLE_LIGHTMAP;
protected static final Overlay ENABLE_OVERLAY_COLOR;
protected static final Overlay DISABLE_OVERLAY_COLOR;
protected static final DiffuseLighting ENABLE_DIFFUSE_LIGHTING;
protected static final DiffuseLighting DISABLE_DIFFUSE_LIGHTING;
protected static final Cull ENABLE_CULLING;
@@ -82,19 +77,12 @@ public abstract class RenderPhase {
protected static final WriteMaskState COLOR_MASK;
protected static final WriteMaskState DEPTH_MASK;
protected static final Layering NO_LAYERING;
protected static final Layering POLYGON_OFFSET_LAYERING;
protected static final Layering VIEW_OFFSET_Z_LAYERING;
protected static final Fog NO_FOG;
protected static final Fog FOG;
protected static final Fog BLACK_FOG;
protected static final Target MAIN_TARGET;
protected static final Target OUTLINE_TARGET;
protected static final Target TRANSLUCENT_TARGET;
protected static final Target PARTICLES_TARGET;
protected static final Target WEATHER_TARGET;
protected static final Target CLOUDS_TARGET;
protected static final Target ITEM_TARGET;
protected static final LineWidth FULL_LINE_WIDTH;
public RenderPhase(String name, Runnable beginAction, Runnable endAction) {
this.name = name;
@@ -129,20 +117,6 @@ public abstract class RenderPhase {
return this.name;
}
private static void setupGlintTexturing(float scale) {
throw new RuntimeException("Not Implemented Yet");
// RenderSystem.matrixMode(5890);
// RenderSystem.pushMatrix();
// RenderSystem.loadIdentity();
// long l = Util.getMeasuringTimeMs() * 8L;
// float g = (float)(l % 110000L) / 110000.0F;
// float h = (float)(l % 30000L) / 30000.0F;
// RenderSystem.translatef(-g, h, 0.0F);
// RenderSystem.rotatef(10.0F, 0.0F, 0.0F, 1.0F);
// RenderSystem.scalef(scale, scale, scale);
// RenderSystem.matrixMode(5888);
}
private static ResourceLocation ATLAS = TextureMap.locationBlocksTexture;
static {
// TODO: Sodium - SpriteAtlasTexture
@@ -151,34 +125,9 @@ public abstract class RenderPhase {
NO_TEXTURE = new Texture();
DEFAULT_TEXTURING = new Texturing("default_texturing", () -> {
}, () -> {
});
OUTLINE_TEXTURING = new Texturing("outline_texturing", () -> {
throw new RuntimeException("Not Implemented Yet");
// RenderSystem.setupOutline();
}, () -> {
throw new RuntimeException("Not Implemented Yet");
// RenderSystem.teardownOutline();
});
GLINT_TEXTURING = new Texturing("glint_texturing", () -> {
setupGlintTexturing(8.0F);
}, () -> {
throw new RuntimeException("Not Implemented Yet");
// RenderSystem.matrixMode(5890);
// RenderSystem.popMatrix();
// RenderSystem.matrixMode(5888);
});
ENTITY_GLINT_TEXTURING = new Texturing("entity_glint_texturing", () -> {
setupGlintTexturing(0.16F);
}, () -> {
throw new RuntimeException("Not Implemented Yet");
// RenderSystem.matrixMode(5890);
// RenderSystem.popMatrix();
// RenderSystem.matrixMode(5888);
});
ENABLE_LIGHTMAP = new Lightmap(true);
DISABLE_LIGHTMAP = new Lightmap(false);
ENABLE_OVERLAY_COLOR = new Overlay(true);
DISABLE_OVERLAY_COLOR = new Overlay(false);
ENABLE_DIFFUSE_LIGHTING = new DiffuseLighting(true);
DISABLE_DIFFUSE_LIGHTING = new DiffuseLighting(false);
ENABLE_CULLING = new Cull(true);
@@ -189,26 +138,7 @@ public abstract class RenderPhase {
ALL_MASK = new WriteMaskState(true, true);
COLOR_MASK = new WriteMaskState(true, false);
DEPTH_MASK = new WriteMaskState(false, true);
NO_LAYERING = new Layering("no_layering", () -> {
}, () -> {
});
POLYGON_OFFSET_LAYERING = new Layering("polygon_offset_layering", () -> {
throw new RuntimeException("Not Implemented Yet");
// RenderSystem.polygonOffset(-1.0F, -10.0F);
// RenderSystem.enablePolygonOffset();
}, () -> {
throw new RuntimeException("Not Implemented Yet");
// RenderSystem.polygonOffset(0.0F, 0.0F);
// RenderSystem.disablePolygonOffset();
});
VIEW_OFFSET_Z_LAYERING = new Layering("view_offset_z_layering", () -> {
throw new RuntimeException("Not Implemented Yet");
// RenderSystem.pushMatrix();
// RenderSystem.scalef(0.99975586F, 0.99975586F, 0.99975586F);
}, () -> {
throw new RuntimeException("Not Implemented Yet");
// RenderSystem::popMatrix();
});
NO_LAYERING = new Layering("no_layering", () -> {}, () -> {});
NO_FOG = new Fog("no_fog", () -> {
}, () -> {
});
@@ -250,103 +180,6 @@ public abstract class RenderPhase {
}
});
PARTICLES_TARGET = new Target("particles_target", () -> {
if (Minecraft.isFancyGraphicsEnabled()) {
throw new RuntimeException("Not Implemented Yet");
// MinecraftClient.getInstance().worldRenderer.getParticlesFramebuffer().beginWrite(false);
}
}, () -> {
if (Minecraft.isFancyGraphicsEnabled()) {
Minecraft.getMinecraft().getFramebuffer().bindFramebuffer(false);
}
});
WEATHER_TARGET = new Target("weather_target", () -> {
if (Minecraft.isFancyGraphicsEnabled()) {
throw new RuntimeException("Not Implemented Yet");
// MinecraftClient.getInstance().worldRenderer.getWeatherFramebuffer().beginWrite(false);
}
}, () -> {
if (Minecraft.isFancyGraphicsEnabled()) {
Minecraft.getMinecraft().getFramebuffer().bindFramebuffer(false);
}
});
CLOUDS_TARGET = new Target("clouds_target", () -> {
if (Minecraft.isFancyGraphicsEnabled()) {
throw new RuntimeException("Not Implemented Yet");
// MinecraftClient.getInstance().worldRenderer.getCloudsFramebuffer().beginWrite(false);
}
}, () -> {
if (Minecraft.isFancyGraphicsEnabled()) {
Minecraft.getMinecraft().getFramebuffer().bindFramebuffer(false);
}
});
ITEM_TARGET = new Target("item_entity_target", () -> {
if (Minecraft.isFancyGraphicsEnabled()) {
throw new RuntimeException("Not Implemented Yet");
// MinecraftClient.getInstance().worldRenderer.getEntityFramebuffer().beginWrite(false);
}
}, () -> {
if (Minecraft.isFancyGraphicsEnabled()) {
Minecraft.getMinecraft().getFramebuffer().bindFramebuffer(false);
}
});
FULL_LINE_WIDTH = new LineWidth(OptionalDouble.of(1.0));
}
public static class LineWidth extends RenderPhase {
private final OptionalDouble width;
public LineWidth(OptionalDouble optionalDouble) {
super("line_width", () -> {
if (!Objects.equals(optionalDouble, OptionalDouble.of(1.0))) {
if (optionalDouble.isPresent()) {
throw new RuntimeException("Not Implemented Yet");
// RenderSystem.lineWidth((float)optionalDouble.getAsDouble());
} else {
throw new RuntimeException("Not Implemented Yet");
// RenderSystem.lineWidth(Math.max(2.5F, (float)MinecraftClient.getInstance().getWindow().getFramebufferWidth() / 1920.0F * 2.5F));
}
}
}, () -> {
if (!Objects.equals(optionalDouble, OptionalDouble.of(1.0))) {
throw new RuntimeException("Not Implemented Yet");
// RenderSystem.lineWidth(1.0F);
}
});
this.width = optionalDouble;
}
@Override
public boolean equals(@Nullable Object object) {
if (this == object) {
return true;
} else if (object != null && this.getClass() == object.getClass()) {
return !super.equals(object) ? false : Objects.equals(this.width, ((LineWidth)object).width);
} else {
return false;
}
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), this.width);
}
@Override
public String toString() {
return this.name + '[' + (this.width.isPresent() ? this.width.getAsDouble() : "window_scale") + ']';
}
}
@@ -505,25 +338,6 @@ public abstract class RenderPhase {
}
public static class Overlay extends Toggleable {
public Overlay(boolean overlayColor) {
super("overlay", () -> {
if (overlayColor) {
throw new RuntimeException("Not Implemented Yet");
// MinecraftClient.getInstance().gameRenderer.getOverlayTexture().setupOverlayColor();
}
}, () -> {
if (overlayColor) {
throw new RuntimeException("Not Implemented Yet");
// MinecraftClient.getInstance().gameRenderer.getOverlayTexture().teardownOverlayColor();
}
}, overlayColor);
}
}
public static class Lightmap extends Toggleable {
public Lightmap(boolean lightmap) {
super("lightmap", () -> {
@@ -580,93 +394,6 @@ public abstract class RenderPhase {
}
public static final class PortalTexturing extends Texturing {
private final int layer;
public PortalTexturing(int layer) {
super("portal_texturing", () -> {
throw new RuntimeException("Not Implemented Yet");
// RenderSystem.matrixMode(5890);
// RenderSystem.pushMatrix();
// RenderSystem.loadIdentity();
// RenderSystem.translatef(0.5F, 0.5F, 0.0F);
// RenderSystem.scalef(0.5F, 0.5F, 1.0F);
// RenderSystem.translatef(17.0F / (float)layer, (2.0F + (float)layer / 1.5F) * ((float)(Util.getMeasuringTimeMs() % 800000L) / 800000.0F), 0.0F);
// RenderSystem.rotatef(((float)(layer * layer) * 4321.0F + (float)layer * 9.0F) * 2.0F, 0.0F, 0.0F, 1.0F);
// RenderSystem.scalef(4.5F - (float)layer / 4.0F, 4.5F - (float)layer / 4.0F, 1.0F);
// RenderSystem.mulTextureByProjModelView();
// RenderSystem.matrixMode(5888);
// RenderSystem.setupEndPortalTexGen();
}, () -> {
throw new RuntimeException("Not Implemented Yet");
// RenderSystem.matrixMode(5890);
// RenderSystem.popMatrix();
// RenderSystem.matrixMode(5888);
// RenderSystem.clearTexGen();
});
this.layer = layer;
}
@Override
public boolean equals(Object object) {
if (this == object) {
return true;
} else if (object != null && this.getClass() == object.getClass()) {
PortalTexturing lv = (PortalTexturing)object;
return this.layer == lv.layer;
} else {
return false;
}
}
@Override
public int hashCode() {
return Integer.hashCode(this.layer);
}
}
public static final class OffsetTexturing extends Texturing {
private final float x;
private final float y;
public OffsetTexturing(float x, float y) {
super("offset_texturing", () -> {
throw new RuntimeException("Not Implemented Yet");
// RenderSystem.matrixMode(5890);
// RenderSystem.pushMatrix();
// RenderSystem.loadIdentity();
// RenderSystem.translatef(x, y, 0.0F);
// RenderSystem.matrixMode(5888);
}, () -> {
throw new RuntimeException("Not Implemented Yet");
// RenderSystem.matrixMode(5890);
// RenderSystem.popMatrix();
// RenderSystem.matrixMode(5888);
});
this.x = x;
this.y = y;
}
@Override
public boolean equals(Object object) {
if (this == object) {
return true;
} else if (object != null && this.getClass() == object.getClass()) {
OffsetTexturing lv = (OffsetTexturing)object;
return Float.compare(lv.x, this.x) == 0 && Float.compare(lv.y, this.y) == 0;
} else {
return false;
}
}
@Override
public int hashCode() {
return Objects.hash(this.x, this.y);
}
}
public static class Texturing extends RenderPhase {
public Texturing(String string, Runnable runnable, Runnable runnable2) {
super(string, runnable, runnable2);
@@ -1,20 +1,40 @@
package com.gtnewhorizons.angelica.config;
@Config(modid = "angelica")
import com.gtnewhorizon.gtnhlib.config.Config;
@Config(modid = "angelica", filename = "angelica-modules")
public class AngelicaConfig {
@Config.Comment("Enable Sodium rendering")
@Config.DefaultBoolean(true)
@Config.RequiresMcRestart
public static boolean enableSodium;
@Config.Comment("Enable NotFine Options")
@Config.DefaultBoolean(false)
public static boolean enableNotFineOptions;
@Config.Comment("Enable Reese's Sodium Options")
@Config.DefaultBoolean(true)
public static boolean enableReesesSodiumOptions;
@Config.Comment("Enable Sodium fluid rendering")
@Config.DefaultBoolean(false)
@Config.RequiresMcRestart
public static boolean enableSodiumFluidRendering;
@Config.Comment("Enable Iris Shaders [Requires Sodium]")
@Config.Comment("Inject QuadProvider rendering into some vanilla blocks")
@Config.DefaultBoolean(false)
@Config.RequiresMcRestart
public static boolean injectQPRendering;
@Config.Comment("Enable Angelica's test blocks")
@Config.DefaultBoolean(false)
@Config.Ignore()
public static boolean enableTestBlocks;
@Config.Comment("Enable Iris Shaders [Requires Sodium]")
@Config.DefaultBoolean(true)
@Config.RequiresMcRestart
public static boolean enableIris;
@Config.Comment("Enable MCPatcherForge features, still in Alpha. Individual features are toggled in mcpatcher.json")
@@ -22,11 +42,6 @@ public class AngelicaConfig {
@Config.RequiresMcRestart
public static boolean enableMCPatcherForgeFeatures;
@Config.Comment("Enable NotFine optimizations")
@Config.DefaultBoolean(true)
@Config.RequiresMcRestart
public static boolean enableNotFineOptimizations;
@Config.Comment("Replace some vanilla render paths with more optimized versions. Disable if you encounter mixin conflicts.")
@Config.DefaultBoolean(true)
@Config.RequiresMcRestart
@@ -53,17 +68,30 @@ public class AngelicaConfig {
@Config.DefaultBoolean(true)
public static boolean showSplashMemoryBar;
@Config.Comment("Renders the HUD elements once per tick and reuses the pixels to improve performance. [Experimental]")
@Config.Comment("Renders the HUD elements once per 20 frames (by default) and reuses the pixels to improve performance. [Experimental]")
@Config.DefaultBoolean(true)
@Config.RequiresMcRestart
public static boolean enableHudCaching;
@Config.Comment("Inject a conditional early return into all RenderGameOverlayEvent receivers; Requires enableHudCaching")
@Config.DefaultBoolean(true)
@Config.RequiresMcRestart
public static boolean enableHudCachingEventTransformer;
@Config.Comment("The amount of frames to wait before updating the HUD elements. [Experimental]")
@Config.DefaultInt(20)
@Config.RangeInt(min = 1, max = 60)
public static int hudCachingFPS = 20;
@Config.Comment("Batch drawScreen fonts [Experimental]")
@Config.DefaultBoolean(true)
@Config.RequiresMcRestart
public static boolean enableFontRenderer;
@Config.Comment("Enable Dynamic Lights")
@Config.DefaultBoolean(true)
@Config.RequiresMcRestart
public static boolean enableDynamicLights;
@Config.Comment("Optimize world update light. [From Hodgepodge]")
@Config.DefaultBoolean(true)
@Config.RequiresMcRestart
@@ -79,18 +107,45 @@ public class AngelicaConfig {
@Config.RequiresMcRestart
public static boolean optimizeTextureLoading;
@Config.Comment("Optimize slow glGetInteger in Jabba w/ Nvidia Drivers")
@Config.Comment("Fix RenderBlockFluid reading the block type from the world access multiple times")
@Config.DefaultBoolean(true)
@Config.RequiresMcRestart
public static boolean optimizeJabbaGetInteger;
public static boolean fixFluidRendererCheckingBlockAgain;
@Config.Comment("Fix thread-safety in lotrs rendering")
@Config.Comment("Dynamically modifies the render distance of dropped items entities to preserve performance."
+ " It starts reducing the render distance when exceeding the threshold set below.")
@Config.DefaultBoolean(true)
@Config.RequiresMcRestart
public static boolean fixLotrSodiumCompat;
public static boolean dynamicItemRenderDistance;
@Config.Comment("Max amount of dropped item rendered")
@Config.DefaultInt(256)
@Config.RangeInt(min = 32, max = 2048)
public static int droppedItemLimit;
@Config.Comment("Use total world time instead of normal world time. Allows most shader animations to play when "
+ "doDaylightCycle is off, but causes shader animations to desync from time of day.")
@Config.DefaultBoolean(false)
public static boolean useTotalWorldTime;
@Config.Comment("Enable Debug Logging")
@Config.DefaultBoolean(false)
@Config.RequiresMcRestart
public static boolean enableDebugLogging;
@Config.Comment("Enable Zoom")
@Config.DefaultBoolean(true)
@Config.RequiresMcRestart
public static boolean enableZoom;
@Config.Comment("Optimizes in-world item rendering")
@Config.DefaultBoolean(true)
@Config.RequiresMcRestart
public static boolean optimizeInWorldItemRendering;
@Config.Comment("Max amount of display lists to cache for optimized item rendering. Higher number will use more VRAM")
@Config.DefaultInt(256)
@Config.RangeInt(min = 64, max = 1024)
public static int itemRendererDisplayListCacheSize;
}
@@ -1,9 +1,11 @@
package com.gtnewhorizons.angelica.config;
import com.gtnewhorizon.gtnhlib.config.ConfigException;
import com.gtnewhorizon.gtnhlib.config.SimpleGuiConfig;
import net.minecraft.client.gui.GuiScreen;
public class AngelicaGuiConfig extends SimpleGuiConfig {
public AngelicaGuiConfig(GuiScreen parent) throws ConfigException {
super(parent, AngelicaConfig.class, "archaicfix", "ArchaicFix");
super(parent, AngelicaConfig.class, "angelica", "Angelica");
}
}
@@ -1,5 +1,6 @@
package com.gtnewhorizons.angelica.config;
import com.gtnewhorizon.gtnhlib.config.SimpleGuiFactory;
import net.minecraft.client.gui.GuiScreen;
public class AngelicaGuiConfigFactory implements SimpleGuiFactory {
@@ -0,0 +1,42 @@
package com.gtnewhorizons.angelica.config;
import com.gtnewhorizon.gtnhlib.config.Config;
@Config(modid = "angelica", filename = "angelica-compat")
public class CompatConfig {
@Config.Comment("Apply fixes to the LOTR mod")
@Config.DefaultBoolean(true)
@Config.RequiresMcRestart
public static boolean fixLotr;
@Config.Comment("Apply fixes to Extra Utilities")
@Config.DefaultBoolean(true)
@Config.RequiresMcRestart
public static boolean fixExtraUtils;
@Config.Comment("Apply fixes to Stacks on Stacks")
@Config.DefaultBoolean(true)
@Config.RequiresMcRestart
public static boolean fixStacksOnStacks;
@Config.Comment("Apply fixes to Minefactory Reloaded")
@Config.DefaultBoolean(true)
@Config.RequiresMcRestart
public static boolean fixMinefactoryReloaded;
@Config.Comment("Apply fixes to Thaumcraft")
@Config.DefaultBoolean(true)
@Config.RequiresMcRestart
public static boolean fixThaumcraft;
@Config.Comment("Apply fixes to ThaumicHorizons")
@Config.DefaultBoolean(true)
@Config.RequiresMcRestart
public static boolean fixThaumicHorizons;
@Config.Comment("Apply fixes to Immersive Engineering")
@Config.DefaultBoolean(true)
@Config.RequiresMcRestart
public static boolean fixImmersiveEngineering;
}
@@ -1,113 +0,0 @@
package com.gtnewhorizons.angelica.config;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Config {
/**
* The mod id that this configuration is associated with.
*/
String modid();
/**
* Root element category, defaults to "general". You must not specify an empty string.
*/
String category() default "general";
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.TYPE})
@interface LangKey {
String value();
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@interface Comment {
String[] value();
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@interface Ignore {
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@interface DefaultBoolean {
boolean value();
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@interface RangeInt {
int min() default Integer.MIN_VALUE;
int max() default Integer.MAX_VALUE;
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@interface DefaultInt {
int value();
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@interface RangeFloat {
float min() default Float.MIN_VALUE;
float max() default Float.MAX_VALUE;
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@interface DefaultFloat {
float value();
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@interface DefaultString {
String value();
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@interface Pattern {
String value();
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@interface DefaultEnum {
String value();
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@interface DefaultStringList {
String[] value();
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@interface Name {
String value();
}
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.TYPE})
@interface RequiresMcRestart {
}
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.TYPE})
@interface RequiresWorldRestart {
}
}
@@ -1,15 +0,0 @@
package com.gtnewhorizons.angelica.config;
/**
* A really basic wrapper for config to simplify handling them in external code.
*/
public class ConfigException extends Exception {
public ConfigException(String message) {
super(message);
}
public ConfigException(Throwable cause) {
super(cause);
}
}
@@ -0,0 +1,35 @@
package com.gtnewhorizons.angelica.config;
import net.minecraft.client.Minecraft;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
public class ConfigMigrator {
public static Logger LOGGER = LogManager.getLogger("Angelica");
/**
* Tries to migrate the equivalent config file from Rubidium to the Angelica name if possible.
*/
public static Path handleConfigMigration(String fileName) {
final Path configDir = Minecraft.getMinecraft().mcDataDir.toPath().resolve("config");
final Path mainPath = configDir.resolve(fileName);
try {
if(Files.notExists(mainPath)) {
final String legacyName = fileName.replace("angelica", "rubidium");
final Path legacyPath = configDir.resolve(legacyName);
if(Files.exists(legacyPath)) {
Files.move(legacyPath, mainPath);
LOGGER.warn("Migrated {} config file to {}", legacyName, fileName);
}
}
} catch(IOException | RuntimeException e) {
LOGGER.error("Exception encountered while attempting config migration", e);
}
return mainPath;
}
}
@@ -1,267 +0,0 @@
package com.gtnewhorizons.angelica.config;
import cpw.mods.fml.client.config.IConfigElement;
import cpw.mods.fml.client.event.ConfigChangedEvent;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.SneakyThrows;
import lombok.val;
import net.minecraft.launchwrapper.Launch;
import net.minecraftforge.common.config.ConfigElement;
import net.minecraftforge.common.config.Configuration;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
/**
* Class for controlling the loading of configuration files.
*/
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class ConfigurationManager {
private static final Logger LOGGER = LogManager.getLogger("ArchaicConfig");
private static final Map<String, Configuration> configs = new HashMap<>();
private static final Map<Configuration, Set<Class<?>>> configToClassMap = new HashMap<>();
private static final ConfigurationManager instance = new ConfigurationManager();
private static boolean initialized = false;
private static Path configDir;
/**
* Registers a configuration class to be loaded. This should be done in preInit.
*
* @param configClass The class to register.
*/
public static void registerConfig(Class<?> configClass) throws ConfigException {
init();
val cfg = Optional.ofNullable(configClass.getAnnotation(Config.class))
.orElseThrow(() -> new ConfigException(
"Class " + configClass.getName() + " does not have a @Config annotation!"));
val category = Optional.of(cfg.category().trim())
.map((cat) -> cat.length() == 0 ? null : cat)
.orElseThrow(() -> new ConfigException(
"Config class " + configClass.getName() + " has an empty category!"));
val rawConfig = configs.computeIfAbsent(cfg.modid(), (ignored) -> {
val c = new Configuration(configDir.resolve(cfg.modid() + ".cfg").toFile());
c.load();
return c;
});
configToClassMap.computeIfAbsent(rawConfig, (ignored) -> new HashSet<>()).add(configClass);
try {
processConfigInternal(configClass, category, rawConfig);
rawConfig.save();
} catch (IllegalAccessException | NoSuchMethodException | InvocationTargetException | NoSuchFieldException e) {
throw new ConfigException(e);
}
}
private static void processConfigInternal(Class<?> configClass, String category, Configuration rawConfig)
throws IllegalAccessException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException,
ConfigException {
val cat = rawConfig.getCategory(category);
for (val field : configClass.getDeclaredFields()) {
if (field.getAnnotation(Config.Ignore.class) != null) {
continue;
}
field.setAccessible(true);
val comment = Optional.ofNullable(field.getAnnotation(Config.Comment.class))
.map(Config.Comment::value)
.map((lines) -> String.join("\n", lines))
.orElse("");
val name = Optional.ofNullable(field.getAnnotation(Config.Name.class))
.map(Config.Name::value)
.orElse(field.getName());
val langKey = Optional.ofNullable(field.getAnnotation(Config.LangKey.class))
.map(Config.LangKey::value)
.orElse(name);
val fieldClass = field.getType();
var boxed = false;
if ((boxed = fieldClass.equals(Boolean.class)) || fieldClass.equals(boolean.class)) {
val defaultValue = Optional.ofNullable(field.getAnnotation(Config.DefaultBoolean.class))
.map(Config.DefaultBoolean::value)
.orElse(boxed ? (Boolean) field.get(null) : field.getBoolean(null));
field.setBoolean(null, rawConfig.getBoolean(name, category, defaultValue, comment, langKey));
} else if ((boxed = fieldClass.equals(Integer.class)) || fieldClass.equals(int.class)) {
val range = Optional.ofNullable(field.getAnnotation(Config.RangeInt.class));
val min = range.map(Config.RangeInt::min).orElse(Integer.MIN_VALUE);
val max = range.map(Config.RangeInt::max).orElse(Integer.MAX_VALUE);
val defaultValue = Optional.ofNullable(field.getAnnotation(Config.DefaultInt.class))
.map(Config.DefaultInt::value)
.orElse(boxed ? (Integer) field.get(null) : field.getInt(null));
field.setInt(null, rawConfig.getInt(name, category, defaultValue, min, max, comment, langKey));
} else if ((boxed = fieldClass.equals(Float.class)) || fieldClass.equals(float.class)) {
val range = Optional.ofNullable(field.getAnnotation(Config.RangeFloat.class));
val min = range.map(Config.RangeFloat::min).orElse(Float.MIN_VALUE);
val max = range.map(Config.RangeFloat::max).orElse(Float.MAX_VALUE);
val defaultValue = Optional.ofNullable(field.getAnnotation(Config.DefaultFloat.class))
.map(Config.DefaultFloat::value)
.orElse(boxed ? (Float) field.get(null) : field.getFloat(null));
field.setFloat(null, rawConfig.getFloat(name, category, defaultValue, min, max, comment, langKey));
} else if (fieldClass.equals(String.class)) {
val defaultValue = Optional.ofNullable(field.getAnnotation(Config.DefaultString.class))
.map(Config.DefaultString::value)
.orElse((String) field.get(null));
val pattern = Optional.ofNullable(field.getAnnotation(Config.Pattern.class))
.map(Config.Pattern::value)
.map(Pattern::compile)
.orElse(null);
field.set(null, rawConfig.getString(name, category, defaultValue, comment, langKey, pattern));
} else if (fieldClass.isEnum()) {
val enumValues = Arrays.stream((Object[]) fieldClass.getDeclaredMethod("values").invoke(null))
.map((obj) -> (Enum<?>) obj)
.collect(Collectors.toList());
val defaultValue = (Enum<?>) Optional.ofNullable(field.getAnnotation(Config.DefaultEnum.class))
.map(Config.DefaultEnum::value)
.map((defName) -> extractField(fieldClass, defName))
.map(ConfigurationManager::extractValue)
.orElse(field.get(null));
val possibleValues = enumValues.stream().map(Enum::name).toArray(String[]::new);
var value = rawConfig.getString(name,
category,
defaultValue.name(),
comment + "\nPossible values: " + Arrays.toString(possibleValues) +
"\n",
possibleValues,
langKey);
try {
if (!Arrays.asList(possibleValues).contains(value)) {
throw new NoSuchFieldException();
}
val enumField = fieldClass.getDeclaredField(value);
if (!enumField.isEnumConstant()) {
throw new NoSuchFieldException();
}
field.set(null, enumField.get(null));
} catch (NoSuchFieldException e) {
LOGGER
.warn("Invalid value " + value + " for enum configuration field " + field.getName() +
" of type " + fieldClass.getName() + " in config class " +
configClass.getName() + "! Using default value of " + defaultValue + "!");
field.set(null, defaultValue);
}
} else if (fieldClass.isArray() && fieldClass.getComponentType().equals(String.class)) {
val defaultValue = Optional.ofNullable(field.getAnnotation(Config.DefaultStringList.class)).map(Config.DefaultStringList::value).orElse((String[])field.get(null));
var value = rawConfig.getStringList(name, category, defaultValue, comment, null, langKey);
field.set(null, value);
} else {
throw new ConfigException("Illegal config field: " + field.getName() + " in " + configClass.getName() +
": Unsupported type " + fieldClass.getName() +
"! Did you forget an @Ignore annotation?");
}
if (field.isAnnotationPresent(Config.RequiresMcRestart.class)) {
cat.setRequiresMcRestart(true);
}
if (field.isAnnotationPresent(Config.RequiresWorldRestart.class)) {
cat.setRequiresWorldRestart(true);
}
}
}
@SneakyThrows
private static Field extractField(Class<?> clazz, String field) {
return clazz.getDeclaredField(field);
}
@SneakyThrows
private static Object extractValue(Field field) {
return field.get(null);
}
/**
* Process the configuration into a list of config elements usable in config GUI code.
*
* @param configClass The class to process.
*
* @return The configuration elements.
*/
@SuppressWarnings({"rawtypes", "unchecked"})
public static List<IConfigElement> getConfigElements(Class<?> configClass) throws ConfigException {
init();
val cfg = Optional.ofNullable(configClass.getAnnotation(Config.class))
.orElseThrow(() -> new ConfigException(
"Class " + configClass.getName() + " does not have a @Config annotation!"));
val rawConfig = Optional.ofNullable(configs.get(cfg.modid()))
.map((conf) -> Optional.ofNullable(configToClassMap.get(conf))
.map((l) -> l.contains(configClass))
.orElse(false) ? conf : null)
.orElseThrow(() -> new ConfigException(
"Tried to get config elements for non-registered config class!"));
val category = cfg.category();
val elements = new ConfigElement<>(rawConfig.getCategory(category)).getChildElements();
return elements.stream().map((element) -> new IConfigElementProxy(element, () -> {
try {
processConfigInternal(configClass, category, rawConfig);
rawConfig.save();
} catch (IllegalAccessException |
NoSuchMethodException |
InvocationTargetException |
NoSuchFieldException |
ConfigException e) {
e.printStackTrace();
}
})).collect(Collectors.toList());
}
private static File minecraftHome() {
return Launch.minecraftHome != null ? Launch.minecraftHome : new File(".");
}
private static void init() {
if (initialized) {
return;
}
configDir = minecraftHome().toPath().resolve("config");
initialized = true;
}
/**
* Internal, do not use.
*/
public static void registerBus() {
FMLCommonHandler.instance().bus().register(instance);
}
/**
* Internal, do not use.
*
* @param event The event.
*/
@SubscribeEvent
public void onConfigChanged(ConfigChangedEvent.OnConfigChangedEvent event) {
init();
val config = configs.get(event.modID);
if (config == null) {
return;
}
val configClasses = configToClassMap.get(config);
configClasses.forEach((configClass) -> {
try {
val category = Optional.ofNullable(configClass.getAnnotation(Config.class))
.map(Config::category)
.orElseThrow(() -> new ConfigException(
"Failed to get config category for class " + configClass.getName()));
processConfigInternal(configClass, category, config);
} catch (Exception e) {
e.printStackTrace();
}
});
}
}
@@ -1,158 +0,0 @@
package com.gtnewhorizons.angelica.config;
import cpw.mods.fml.client.config.ConfigGuiType;
import cpw.mods.fml.client.config.GuiConfigEntries;
import cpw.mods.fml.client.config.GuiEditArrayEntries;
import cpw.mods.fml.client.config.IConfigElement;
import java.util.List;
import java.util.regex.Pattern;
public class IConfigElementProxy<T> implements IConfigElement<T> {
private final IConfigElement<T> proxied;
private final Runnable onUpdate;
public IConfigElementProxy(IConfigElement<T> proxied, Runnable onUpdate) {
this.proxied = proxied;
this.onUpdate = onUpdate;
}
@Override
public boolean isProperty() {
return proxied.isProperty();
}
@SuppressWarnings("rawtypes")
@Override
public Class<? extends GuiConfigEntries.IConfigEntry> getConfigEntryClass() {
return proxied.getConfigEntryClass();
}
@Override
public Class<? extends GuiEditArrayEntries.IArrayEntry> getArrayEntryClass() {
return proxied.getArrayEntryClass();
}
@Override
public String getName() {
return proxied.getName();
}
@Override
public String getQualifiedName() {
return proxied.getQualifiedName();
}
@Override
public String getLanguageKey() {
return proxied.getLanguageKey();
}
@Override
public String getComment() {
return proxied.getComment();
}
@SuppressWarnings("rawtypes")
@Override
public List<IConfigElement> getChildElements() {
return proxied.getChildElements();
}
@Override
public ConfigGuiType getType() {
return proxied.getType();
}
@Override
public boolean isList() {
return proxied.isList();
}
@Override
public boolean isListLengthFixed() {
return proxied.isListLengthFixed();
}
@Override
public int getMaxListLength() {
return proxied.getMaxListLength();
}
@Override
public boolean isDefault() {
return proxied.isDefault();
}
@Override
public Object getDefault() {
return proxied.getDefault();
}
@Override
public Object[] getDefaults() {
return proxied.getDefaults();
}
@Override
public void setToDefault() {
proxied.setToDefault();
}
@Override
public boolean requiresWorldRestart() {
return proxied.requiresWorldRestart();
}
@Override
public boolean showInGui() {
return proxied.showInGui();
}
@Override
public boolean requiresMcRestart() {
return proxied.requiresMcRestart();
}
@Override
public Object get() {
return proxied.get();
}
@Override
public Object[] getList() {
return proxied.getList();
}
@Override
public void set(T value) {
proxied.set(value);
onUpdate.run();
}
@Override
public void set(T[] aVal) {
proxied.set(aVal);
onUpdate.run();
}
@Override
public String[] getValidValues() {
return proxied.getValidValues();
}
@Override
public T getMinValue() {
return proxied.getMinValue();
}
@Override
public T getMaxValue() {
return proxied.getMaxValue();
}
@Override
public Pattern getValidationPattern() {
return proxied.getValidationPattern();
}
}
@@ -1,13 +0,0 @@
package com.gtnewhorizons.angelica.config;
import cpw.mods.fml.client.config.GuiConfig;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.client.gui.GuiScreen;
@SideOnly(Side.CLIENT)
public class SimpleGuiConfig extends GuiConfig {
public SimpleGuiConfig(GuiScreen parent, Class<?> configClass, String modID, String modName) throws ConfigException {
super(parent, ConfigurationManager.getConfigElements(configClass), modID, false, false, modName + " Configuration");
}
}
@@ -1,26 +0,0 @@
package com.gtnewhorizons.angelica.config;
import cpw.mods.fml.client.IModGuiFactory;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.client.Minecraft;
import java.util.Set;
@SideOnly(Side.CLIENT)
public interface SimpleGuiFactory extends IModGuiFactory {
@Override
default void initialize(Minecraft minecraftInstance) {
}
@Override
default Set<RuntimeOptionCategoryElement> runtimeGuiCategories() {
return null;
}
@Override
default RuntimeOptionGuiHandler getHandlerFor(RuntimeOptionCategoryElement element) {
return null;
}
}
@@ -0,0 +1,61 @@
package com.gtnewhorizons.angelica.debug;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.ScaledResolution;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.entity.Entity;
import net.minecraftforge.client.event.RenderGameOverlayEvent;
import org.lwjgl.opengl.GL11;
public class F3Direction {
public static void renderWorldDirectionsEvent(Minecraft mc, RenderGameOverlayEvent.Pre event) {
if (mc.gameSettings.showDebugInfo && mc.gameSettings.thirdPersonView == 0) {
ScaledResolution scaledresolution = new ScaledResolution(mc, mc.displayWidth, mc.displayHeight);
int width = scaledresolution.getScaledWidth();
int height = scaledresolution.getScaledHeight();
GL11.glPushMatrix();
GL11.glTranslatef((float) (width / 2), (float) (height / 2), -90);
Entity entity = mc.renderViewEntity;
GL11.glRotatef(entity.prevRotationPitch + (entity.rotationPitch - entity.prevRotationPitch) * event.partialTicks, -1.0F, 0.0F, 0.0F);
GL11.glRotatef(entity.prevRotationYaw + (entity.rotationYaw - entity.prevRotationYaw) * event.partialTicks, 0.0F, 1.0F, 0.0F);
GL11.glScalef(-1.0F, -1.0F, -1.0F);
renderWorldDirections();
GL11.glPopMatrix();
}
}
public static void renderWorldDirections() {
GL11.glDisable(GL11.GL_TEXTURE_2D);
GL11.glDepthMask(false);
Tessellator tessellator = Tessellator.instance;
GL11.glLineWidth(2.0F);
tessellator.startDrawing(GL11.GL_LINES);
//X
tessellator.setColorRGBA_F(255, 0, 0, 1);
tessellator.addVertex(0.0D, 0.0D, 0.0D);
tessellator.addVertex(10, 0.0D, 0.0D);
//Z
tessellator.setColorRGBA_F(0, 0, 255, 1);
tessellator.addVertex(0.0D, 0.0D, 0.0D);
tessellator.addVertex(0.0D, 0.0D, 10);
//Y
tessellator.setColorRGBA_F(0, 255, 0, 1);
tessellator.addVertex(0.0D, 0.0D, 0.0D);
tessellator.addVertex(0.0D, 10, 0.0D);
tessellator.draw();
GL11.glLineWidth(1.0F);
GL11.glDepthMask(true);
GL11.glEnable(GL11.GL_TEXTURE_2D);
}
}
@@ -0,0 +1,273 @@
package com.gtnewhorizons.angelica.debug;
import static org.lwjgl.opengl.GL11.GL_ALPHA_TEST;
import static org.lwjgl.opengl.GL11.GL_BLEND;
import static org.lwjgl.opengl.GL11.GL_CULL_FACE;
import static org.lwjgl.opengl.GL11.GL_DEPTH_TEST;
import static org.lwjgl.opengl.GL11.GL_FLOAT;
import static org.lwjgl.opengl.GL11.GL_ONE_MINUS_SRC_ALPHA;
import static org.lwjgl.opengl.GL11.GL_SRC_ALPHA;
import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D;
import static org.lwjgl.opengl.GL11.GL_TRIANGLE_STRIP;
import static org.lwjgl.opengl.GL11.GL_VERTEX_ARRAY;
import static org.lwjgl.opengl.GL11.glBlendFunc;
import static org.lwjgl.opengl.GL11.glColor4f;
import static org.lwjgl.opengl.GL11.glDisable;
import static org.lwjgl.opengl.GL11.glDisableClientState;
import static org.lwjgl.opengl.GL11.glDrawArrays;
import static org.lwjgl.opengl.GL11.glEnable;
import static org.lwjgl.opengl.GL11.glEnableClientState;
import static org.lwjgl.opengl.GL15.GL_ARRAY_BUFFER;
import static org.lwjgl.opengl.GL15.GL_STATIC_DRAW;
import static org.lwjgl.opengl.GL15.glBindBuffer;
import static org.lwjgl.opengl.GL15.glBufferData;
import static org.lwjgl.opengl.GL15.glGenBuffers;
import static org.lwjgl.opengl.GL20.glDisableVertexAttribArray;
import static org.lwjgl.opengl.GL20.glEnableVertexAttribArray;
import static org.lwjgl.opengl.GL20.glUniform1;
import static org.lwjgl.opengl.GL20.glUniform1f;
import static org.lwjgl.opengl.GL20.glUniform1i;
import static org.lwjgl.opengl.GL20.glVertexAttribPointer;
import com.gtnewhorizon.gtnhlib.client.renderer.shader.ShaderProgram;
import com.gtnewhorizons.angelica.compat.lwjgl.MemoryStack;
import java.nio.FloatBuffer;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.ScaledResolution;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.util.ResourceLocation;
import org.lwjgl.BufferUtils;
public abstract class F3Graph {
private static final int NUM_SAMPLES = 240;
// Two floats (x,y)
private static final int VERT_FLOATS = 2;
private static final int VERT_COUNT = 4;
private static final int BORDER = 1;
private static final int HEIGHT = 60;
private static final int WIDTH = NUM_SAMPLES;
private static final int FONT_COLOR = 0xFFE0E0E0;
// Due to GLSL 120 limitations, it's just easier to use floats
private final FloatBuffer sampleBuf = BufferUtils.createFloatBuffer(NUM_SAMPLES);
private final long[] samples = new long[NUM_SAMPLES]; // long version for calculations
// Circular buffer holding the last 240 samples, in nanoseconds
private int samplesHead = 0; // one ahead of the position of the last sample
private boolean initialized = false;
private ShaderProgram shader;
private int aPos;
private int uFBWidth;
private int uFBHeight;
private int uScaleFactor;
private int uHeadIdx;
private int uSamples;
private int vertBuf;
private final ResourceLocation texture;
private final float pxPerNs;
private final boolean left;
private long sum;
protected F3Graph(ResourceLocation texture, float pxPerNs, boolean left) {
this.texture = texture;
this.pxPerNs = pxPerNs;
this.left = left;
}
public void putSample(long time) {
// Manage running trackers
sum -= samples[samplesHead];
sum += time;
samples[samplesHead] = time;
sampleBuf.put(samplesHead, (float) time);
samplesHead = (samplesHead + 1) % NUM_SAMPLES;
}
private int getVertX(ScaledResolution sres, int idx) {
if (left) {
return switch (idx) {
case 0, 3 -> WIDTH + BORDER * 2;
case 1, 2 -> 0;
default -> throw new RuntimeException("Tried to get out-of-bounds vertex for graph!");
};
}
final int displayWidth = sres.getScaledWidth();
return switch (idx) {
case 0, 3 -> displayWidth;
case 1, 2 -> displayWidth - WIDTH - BORDER * 2;
default -> throw new RuntimeException("Tried to get out-of-bounds vertex for graph!");
};
}
private int getVertY(ScaledResolution sres, int idx) {
final int displayHeight = sres.getScaledHeight();
return switch (idx) {
case 0, 1 -> displayHeight - HEIGHT - BORDER * 2;
case 2, 3 -> displayHeight;
default -> throw new RuntimeException("Tried to get out-of-bounds vertex for graph!");
};
}
private void init() {
shader = new ShaderProgram(
"angelica",
"shaders/debug_graph.vert.glsl",
"shaders/debug_graph.frag.glsl");
shader.use();
// Register attributes
aPos = shader.getAttribLocation("pos");
// Register uniforms
uFBWidth = shader.getUniformLocation("fbWidth");
uFBHeight = shader.getUniformLocation("fbHeight");
uScaleFactor = shader.getUniformLocation("scaleFactor");
uSamples = shader.getUniformLocation("samples");
uHeadIdx = shader.getUniformLocation("headIdx");
final int uPxPerNs = shader.getUniformLocation("pxPerNs");
final int uLeft = shader.getUniformLocation("left");
// Load vertex buffer
vertBuf = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vertBuf);
try (final MemoryStack stack = MemoryStack.stackPush()) {
final FloatBuffer vertices = stack.mallocFloat(VERT_COUNT * VERT_FLOATS);
// Since we use a triangle strip, we only need 4 vertices. The quad extends to the top of the screen so spikes
// don't get truncated. The max height is replaced in the vert shader, no need to be precise.
vertices.put(new float[]{
BORDER, BORDER,
WIDTH + BORDER, BORDER,
BORDER, Float.MAX_VALUE,
WIDTH + BORDER, Float.MAX_VALUE
});
vertices.rewind();
glBufferData(GL_ARRAY_BUFFER, vertices, GL_STATIC_DRAW);
}
glBindBuffer(GL_ARRAY_BUFFER, 0);
final Minecraft mc = Minecraft.getMinecraft();
final ScaledResolution sr = new ScaledResolution(mc, mc.displayWidth, mc.displayHeight);
// Load initial value for uniforms
glUniform1f(uFBWidth, mc.displayWidth);
glUniform1f(uFBHeight, mc.displayHeight);
glUniform1f(uScaleFactor, sr.getScaleFactor());
glUniform1i(uHeadIdx, samplesHead);
glUniform1(uSamples, sampleBuf);
glUniform1f(uPxPerNs, pxPerNs);
glUniform1i(uLeft, left ? 1 : 0); // this is how you load bool uniforms
ShaderProgram.clear();
}
public void render() {
if (!initialized) {
init();
initialized = true;
}
/*
* We try to copy modern vanilla's tracker.
* It is 240 (FRAME_TIMES) wide by 60 tall, including the 1px borders.
* We instead make it 242x62 including borders to prevent the borders from overlapping the samples.
* The background is ARGB 90505050, the borders FFFFFFFF, and the text FFE0E0E0.
* First the background is rendered, then the samples, then the foreground texture and the text.
* The background is drawn via a 242x62 translucent rect.
* Next, the samples are rendered by a shader on a transparent 240x60 rect.
* Finally, the foreground texture and the text is rendered on top.
* The shader pipeline is only needed for the sample draw.
*/
final Minecraft mc = Minecraft.getMinecraft();
final ScaledResolution sr = new ScaledResolution(mc, mc.displayWidth, mc.displayHeight);
// Setup GL state
final Tessellator tess = Tessellator.instance;
glDisable(GL_DEPTH_TEST);
glEnable(GL_ALPHA_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// Draw background
glDisable(GL_TEXTURE_2D);
glColor4f(0x50 / 255.0F, 0x50 / 255.0F, 0x50 / 255.0F, 0x90 / 255.0F);
tess.startDrawingQuads();
for (int i = 0; i < 4; ++i) {
tess.addVertex(getVertX(sr, i), getVertY(sr, i), 0);
}
tess.draw();
glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
glEnable(GL_TEXTURE_2D);
// Draw samples
shader.use();
// Load uniforms
glUniform1f(uFBWidth, mc.displayWidth);
glUniform1f(uFBHeight, mc.displayHeight);
glUniform1f(uScaleFactor, sr.getScaleFactor());
glUniform1i(uHeadIdx, samplesHead);
glUniform1(uSamples, sampleBuf);
glBindBuffer(GL_ARRAY_BUFFER, vertBuf);
glEnableVertexAttribArray(aPos);
glVertexAttribPointer(aPos, VERT_FLOATS, GL_FLOAT, false, VERT_FLOATS * 4, 0);
glEnableClientState(GL_VERTEX_ARRAY);
// Left side graphs are inverted, so temporarily disable culling
if (!left) glDisable(GL_CULL_FACE);
glDrawArrays(GL_TRIANGLE_STRIP, 0, VERT_COUNT);
if (!left) glEnable(GL_CULL_FACE);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableVertexAttribArray(aPos);
glBindBuffer(GL_ARRAY_BUFFER, 0);
ShaderProgram.clear();
// Draw foreground
mc.getTextureManager().bindTexture(texture);
tess.startDrawingQuads();
tess.addVertexWithUV(getVertX(sr, 0), getVertY(sr, 0), 0.0D, 1, 0);
tess.addVertexWithUV(getVertX(sr, 1), getVertY(sr, 1), 0.0D, 0, 0);
tess.addVertexWithUV(getVertX(sr, 2), getVertY(sr, 2), 0.0D, 0, 1);
tess.addVertexWithUV(getVertX(sr, 3), getVertY(sr, 3), 0.0D, 1, 1);
tess.draw();
// Reset GL state
glEnable(GL_DEPTH_TEST);
glDisable(GL_ALPHA_TEST);
glDisable(GL_BLEND);
// Draw text
// Ensure running counters are reset on first sample
long min = Long.MAX_VALUE;
long max = Long.MIN_VALUE;
for (int i = 0; i < NUM_SAMPLES; ++i) {
min = Math.min(min, samples[i]);
max = Math.max(max, samples[i]);
}
String minStr = String.format("%.1f ms min", min / 1_000_000D);
String avgStr = String.format("%.1f ms avg", sum / 1_000_000 / (double) NUM_SAMPLES);
String maxStr = String.format("%.1f ms max", max / 1_000_000D);
final FontRenderer fr = mc.fontRenderer;
final int top = sr.getScaledHeight() - HEIGHT - BORDER * 2 - fr.FONT_HEIGHT;
final int scaledWidth = sr.getScaledWidth();
if (left) {
fr.drawString(minStr, BORDER * 2, top, FONT_COLOR, true);
fr.drawString(avgStr, BORDER + WIDTH / 2 - fr.getStringWidth(avgStr) / 2, top, FONT_COLOR, true);
fr.drawString(maxStr, BORDER * 2 + WIDTH - fr.getStringWidth(maxStr), top, FONT_COLOR, true);
} else {
fr.drawString(minStr, scaledWidth - (BORDER * 2 + WIDTH), top, FONT_COLOR, true);
fr.drawString(avgStr, scaledWidth - (BORDER + WIDTH / 2 + fr.getStringWidth(avgStr) / 2), top, FONT_COLOR, true);
fr.drawString(maxStr, scaledWidth - (BORDER * 2 + fr.getStringWidth(maxStr)), top, FONT_COLOR, true);
}
}
}
@@ -0,0 +1,14 @@
package com.gtnewhorizons.angelica.debug;
import net.minecraft.util.ResourceLocation;
public class FrametimeGraph extends F3Graph {
public FrametimeGraph() {
// At 1x scale, 30 FPS should be 60 px. 30 FPS = 33_333_333ns per frame, 60px/33_333_333ns = 0.0000018f px/ns
super(
new ResourceLocation("angelica:textures/frametimes_fg.png"),
0.0000018f,
true
);
}
}
@@ -0,0 +1,14 @@
package com.gtnewhorizons.angelica.debug;
import net.minecraft.util.ResourceLocation;
public class TPSGraph extends F3Graph {
public TPSGraph() {
// At 1x scale, 20 TPS should be 60 px. 20 FPS = 50_000_000ns per frame, 60px/50_000_000ns = 0.0000012 px/ns
super(
new ResourceLocation("angelica:textures/tps_fg.png"),
0.0000012f,
false
);
}
}
@@ -0,0 +1,412 @@
package com.gtnewhorizons.angelica.dynamiclights;
import baubles.common.lib.PlayerHandler;
import com.gtnewhorizon.gtnhlib.blockpos.BlockPos;
import com.gtnewhorizon.gtnhlib.blockpos.IBlockPos;
import com.gtnewhorizon.gtnhlib.util.CoordinatePacker;
import com.gtnewhorizons.angelica.api.IDynamicLightProducer;
import com.gtnewhorizons.angelica.compat.ModStatus;
import com.gtnewhorizons.angelica.config.AngelicaConfig;
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
import me.jellysquid.mods.sodium.client.render.SodiumWorldRenderer;
import mods.battlegear2.api.core.IBattlePlayer;
import mods.battlegear2.api.core.IInventoryPlayerBattle;
import net.irisshaders.iris.api.v0.IrisApi;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.monster.EntityCreeper;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.item.Item;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.util.MathHelper;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import xonin.backhand.api.core.BackhandUtils;
import java.util.Set;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.function.Predicate;
public class DynamicLights {
private static DynamicLights instance;
public static DynamicLightsMode Mode = DynamicLightsMode.OFF;
public static boolean ShaderForce = false;
private static final double MAX_RADIUS = 7.75;
private static final double MAX_RADIUS_SQUARED = MAX_RADIUS * MAX_RADIUS;
private final Set<IDynamicLightSource> dynamicLightSources = new ObjectOpenHashSet<>();
private final ReentrantReadWriteLock lightSourcesLock = new ReentrantReadWriteLock();
private long lastUpdate = System.currentTimeMillis();
private int lastUpdateCount = 0;
public static DynamicLights get() {
if (instance == null)
instance = new DynamicLights();
return instance;
}
public static boolean isEnabled() {
return AngelicaConfig.enableDynamicLights &&
Mode.isEnabled() &&
// if shader force is enabled then true
// if not, then true when shaders are not in use
(ShaderForce || !IrisApi.getInstance().isShaderPackInUse());
}
/**
* Updates all light sources.
*
* @param renderer the renderer
*/
public void updateAll(@NotNull SodiumWorldRenderer renderer) {
if (!isEnabled())
return;
long now = System.currentTimeMillis();
if (now >= this.lastUpdate + Mode.getDelay()) {
this.lastUpdate = now;
this.lastUpdateCount = 0;
this.lightSourcesLock.readLock().lock();
for (var lightSource : this.dynamicLightSources) {
if (lightSource.angelica$updateDynamicLight(renderer))
this.lastUpdateCount++;
}
this.lightSourcesLock.readLock().unlock();
}
}
public int getLastUpdateCount() {
return this.lastUpdateCount;
}
public void addLightSource(IDynamicLightSource lightSource) {
this.lightSourcesLock.writeLock().lock();
this.dynamicLightSources.add(lightSource);
this.lightSourcesLock.writeLock().unlock();
}
/**
* Removes the light source from the tracked light sources.
*
* @param lightSource the light source to remove
*/
public void removeLightSource(@NotNull IDynamicLightSource lightSource) {
this.lightSourcesLock.writeLock().lock();
var dynamicLightSources = this.dynamicLightSources.iterator();
IDynamicLightSource it;
while (dynamicLightSources.hasNext()) {
it = dynamicLightSources.next();
if (it.equals(lightSource)) {
dynamicLightSources.remove();
if (SodiumWorldRenderer.getInstance() != null)
lightSource.angelica$scheduleTrackedChunksRebuild(SodiumWorldRenderer.getInstance());
break;
}
}
this.lightSourcesLock.writeLock().unlock();
}
/**
* Removes light sources if the filter matches.
*
* @param filter the removal filter
*/
public void removeLightSources(@NotNull Predicate<IDynamicLightSource> filter) {
this.lightSourcesLock.writeLock().lock();
var dynamicLightSources = this.dynamicLightSources.iterator();
IDynamicLightSource it;
while (dynamicLightSources.hasNext()) {
it = dynamicLightSources.next();
if (filter.test(it)) {
dynamicLightSources.remove();
if (SodiumWorldRenderer.getInstance() != null) {
if (it.angelica$getLuminance() > 0)
it.angelica$resetDynamicLight();
it.angelica$scheduleTrackedChunksRebuild(SodiumWorldRenderer.getInstance());
}
break;
}
}
this.lightSourcesLock.writeLock().unlock();
}
/**
* Clears light sources.
*/
public void clearLightSources() {
this.lightSourcesLock.writeLock().lock();
var dynamicLightSources = this.dynamicLightSources.iterator();
IDynamicLightSource it;
while (dynamicLightSources.hasNext()) {
it = dynamicLightSources.next();
dynamicLightSources.remove();
if (SodiumWorldRenderer.getInstance() != null) {
if (it.angelica$getLuminance() > 0)
it.angelica$resetDynamicLight();
it.angelica$scheduleTrackedChunksRebuild(SodiumWorldRenderer.getInstance());
}
}
this.lightSourcesLock.writeLock().unlock();
}
/**
* Returns whether the light source is tracked or not.
*
* @param lightSource the light source to check
* @return {@code true} if the light source is tracked, else {@code false}
*/
public boolean containsLightSource(@NotNull IDynamicLightSource lightSource) {
boolean result;
this.lightSourcesLock.readLock().lock();
result = this.dynamicLightSources.contains(lightSource);
this.lightSourcesLock.readLock().unlock();
return result;
}
/**
* Returns the number of dynamic light sources that currently emit lights.
*
* @return the number of dynamic light sources emitting light
*/
public int getLightSourcesCount() {
int result;
this.lightSourcesLock.readLock().lock();
result = this.dynamicLightSources.size();
this.lightSourcesLock.readLock().unlock();
return result;
}
public double getDynamicLightLevel(int x, int y, int z) {
double result = 0;
this.lightSourcesLock.readLock().lock();
for (var lightSource : this.dynamicLightSources) {
result = maxDynamicLightLevel(x, y, z, lightSource, result);
}
this.lightSourcesLock.readLock().unlock();
return MathHelper.clamp_double(result, 0, 15);
}
public double getDynamicLightLevel(@NotNull BlockPos pos) {
return this.getDynamicLightLevel(pos.getX(), pos.getY(), pos.getZ());
}
public static double maxDynamicLightLevel(int x, int y, int z, @NotNull IDynamicLightSource lightSource, double currentLightLevel) {
int luminance = lightSource.angelica$getLuminance();
if (luminance > 0) {
// Can't use Entity#squaredDistanceTo because of eye Y coordinate.
double dx = x - lightSource.angelica$getDynamicLightX() + 0.5;
double dy = y - lightSource.angelica$getDynamicLightY() + 0.5;
double dz = z - lightSource.angelica$getDynamicLightZ() + 0.5;
double distanceSquared = dx * dx + dy * dy + dz * dz;
// 7.75 because else we would have to update more chunks and that's not a good idea.
// 15 (max range for blocks) would be too much and a bit cheaty.
if (distanceSquared <= MAX_RADIUS_SQUARED) {
double multiplier = 1.0 - Math.sqrt(distanceSquared) / MAX_RADIUS;
double lightLevel = multiplier * (double) luminance;
if (lightLevel > currentLightLevel) {
return lightLevel;
}
}
}
return currentLightLevel;
}
/**
* Returns the dynamic light level generated by the light source at the specified position.
*
* @param pos the position
* @param lightSource the light source
* @param currentLightLevel the current surrounding dynamic light level
* @return the dynamic light level at the specified position
*/
public static double maxDynamicLightLevel(@NotNull BlockPos pos, @NotNull IDynamicLightSource lightSource, double currentLightLevel) {
return maxDynamicLightLevel(pos.getX(), pos.getY(), pos.getZ(), lightSource, currentLightLevel);
}
public int getLightmapWithDynamicLight(int x, int y, int z, int lightmap) {
return this.getLightmapWithDynamicLight(this.getDynamicLightLevel(x, y, z), lightmap);
}
/**
* Returns the lightmap with combined light levels.
*
* @param dynamicLightLevel the dynamic light level
* @param lightmap the vanilla lightmap coordinates
* @return the modified lightmap coordinates
*/
public int getLightmapWithDynamicLight(double dynamicLightLevel, int lightmap) {
if (dynamicLightLevel > 0) {
// lightmap is (skyLevel << 20 | blockLevel << 4)
// Get vanilla block light level.
int blockLevel = (lightmap & 0xFFFF) >> 4;
if (dynamicLightLevel > blockLevel) {
// Equivalent to a << 4 bitshift with a little quirk: this one ensure more precision (more decimals are saved).
int luminance = (int) (dynamicLightLevel * 16.0);
lightmap &= 0xfff00000;
lightmap |= luminance & 0x000fffff;
}
}
return lightmap;
}
/**
* Schedules a chunk rebuild at the specified chunk position.
*
* @param renderer the renderer
* @param chunkPos the chunk position
*/
public static void scheduleChunkRebuild(@NotNull SodiumWorldRenderer renderer, @NotNull IBlockPos chunkPos) {
scheduleChunkRebuild(renderer, chunkPos.getX(), chunkPos.getY(), chunkPos.getZ());
}
/**
* Schedules a chunk rebuild at the specified chunk position.
*
* @param renderer the renderer
* @param chunkPos the packed chunk position
*/
public static void scheduleChunkRebuild(@NotNull SodiumWorldRenderer renderer, long chunkPos) {
scheduleChunkRebuild(renderer, CoordinatePacker.unpackX(chunkPos), CoordinatePacker.unpackY(chunkPos), CoordinatePacker.unpackZ(chunkPos));
}
public static void scheduleChunkRebuild(@NotNull SodiumWorldRenderer renderer, int x, int y, int z) {
renderer.scheduleRebuildForChunk(x, y, z, false);
}
/**
* Updates the tracked chunk sets.
*
* @param chunkPos the packed chunk position
* @param old the set of old chunk coordinates to remove this chunk from it
* @param newPos the set of new chunk coordinates to add this chunk to it
*/
public static void updateTrackedChunks(@NotNull IBlockPos chunkPos, @Nullable LongOpenHashSet old, @Nullable LongOpenHashSet newPos) {
if (old != null || newPos != null) {
final long pos = chunkPos.asLong();
if (old != null)
old.remove(pos);
if (newPos != null)
newPos.add(pos);
}
}
/**
* Updates the dynamic lights tracking.
*
* @param lightSource the light source
*/
public static void updateTracking(@NotNull IDynamicLightSource lightSource) {
boolean enabled = lightSource.angelica$isDynamicLightEnabled();
int luminance = lightSource.angelica$getLuminance();
if (!enabled && luminance > 0) {
lightSource.angelica$setDynamicLightEnabled(true);
} else if (enabled && luminance < 1) {
lightSource.angelica$setDynamicLightEnabled(false);
}
}
/**
* Returns the luminance from an item stack.
*
* @param stack the item stack
* @param submergedInWater {@code true} if the stack is submerged in water, else {@code false}
* @return the luminance of the item
*/
public static int getLuminanceFromItemStack(@NotNull ItemStack stack, boolean submergedInWater) {
// TODO only have certain items not glow in water?
if (submergedInWater) return 0;
Item item = stack.getItem();
if (item instanceof ItemBlock itemBlock) {
Block block = itemBlock.field_150939_a;
if (block != null) {
return block.getLightValue();
}
} else if (item instanceof IDynamicLightProducer lightProducer){
return lightProducer.getLuminance();
}
if (item == Items.lava_bucket) return Blocks.lava.getLightValue();
return 0;
}
public static int getLuminanceFromEntity(@NotNull Entity entity) {
if (entity.fire > 0) return 15;
if (entity instanceof EntityItem item) {
return getLuminanceFromItemStack(item.getEntityItem(), item.isInsideOfMaterial(Material.water));
}
if (entity instanceof EntityLivingBase living) {
int luminance = 0;
boolean inWater = living.isInsideOfMaterial(Material.water);
// check equipment + hand for light (should work for all entities)
ItemStack itemStack;
for (int i = 0; i < 5; i++) {
if ((itemStack = living.getEquipmentInSlot(i)) != null) {
luminance = Math.max(luminance, getLuminanceFromItemStack(itemStack, inWater));
}
}
if (ModStatus.isBattlegearLoaded &&
living instanceof EntityPlayer player &&
player instanceof IBattlePlayer battlePlayer &&
battlePlayer.battlegear2$isBattlemode()
) {
ItemStack offhand = ((IInventoryPlayerBattle) player.inventory).battlegear2$getCurrentOffhandWeapon();
if (offhand != null) {
luminance = Math.max(luminance, getLuminanceFromItemStack(offhand, inWater));
}
}
else if (ModStatus.isBackhandLoaded && living instanceof EntityPlayer player){
ItemStack offhand = BackhandUtils.getOffhandItem(player);
if (offhand != null) {
luminance = Math.max(luminance, getLuminanceFromItemStack(offhand, inWater));
}
}
if (ModStatus.isBaublesLoaded && living instanceof EntityPlayer player){
var playerBaubles = PlayerHandler.getPlayerBaubles(player);
if (playerBaubles != null){
for (int i = 0; i < playerBaubles.getSizeInventory(); i++){
var stack = playerBaubles.getStackInSlot(i);
if (stack != null){
luminance = Math.max(luminance, getLuminanceFromItemStack(stack, inWater));
}
}
}
}
return luminance;
}
// TODO: Creepers? TNT? Dusts?
return 0;
}
}
@@ -0,0 +1,36 @@
package com.gtnewhorizons.angelica.dynamiclights;
import java.util.Objects;
public enum DynamicLightsMode
{
OFF("Off", 0),
FASTEST("Fastest", 500),
FAST("Fast", 250),
FANCY("Fancy", 50),
REALTIME("Realtime", 0);
private final String name;
private final int delay;
public boolean hasDelay() {
return delay > 0;
}
public int getDelay(){
return delay;
}
public String getName() {
return name;
}
DynamicLightsMode(String name, int delay) {
this.name = name;
this.delay = delay;
}
public boolean isEnabled() {
return !Objects.equals(this, DynamicLightsMode.OFF);
}
}
@@ -0,0 +1,79 @@
package com.gtnewhorizons.angelica.dynamiclights;
import me.jellysquid.mods.sodium.client.render.SodiumWorldRenderer;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
public interface IDynamicLightSource {
/**
* Returns the dynamic light source X coordinate.
*
* @return the X coordinate
*/
double angelica$getDynamicLightX();
/**
* Returns the dynamic light source Y coordinate.
*
* @return the Y coordinate
*/
double angelica$getDynamicLightY();
/**
* Returns the dynamic light source Z coordinate.
*
* @return the Z coordinate
*/
double angelica$getDynamicLightZ();
/**
* Returns the dynamic light source world.
*
* @return the world instance
*/
SodiumWorldRenderer angelica$getDynamicLightWorld();
/**
* Returns whether the dynamic light is enabled or not.
*
* @return {@code true} if the dynamic light is enabled, else {@code false}
*/
default boolean angelica$isDynamicLightEnabled() {
return DynamicLights.isEnabled() && DynamicLights.get().containsLightSource(this);
}
/**
* Sets whether the dynamic light is enabled or not.
* <p>
* Note: please do not call this function in your mod or you will break things.
*
* @param enabled {@code true} if the dynamic light is enabled, else {@code false}
*/
@ApiStatus.Internal
default void angelica$setDynamicLightEnabled(boolean enabled) {
this.angelica$resetDynamicLight();
if (enabled)
DynamicLights.get().addLightSource(this);
else
DynamicLights.get().removeLightSource(this);
}
void angelica$resetDynamicLight();
/**
* Returns the luminance of the light source.
* The maximum is 15, below 1 values are ignored.
*
* @return the luminance of the light source
*/
int angelica$getLuminance();
/**
* Executed at each tick.
*/
void angelica$dynamicLightTick();
boolean angelica$updateDynamicLight(@NotNull SodiumWorldRenderer renderer);
void angelica$scheduleTrackedChunksRebuild(@NotNull SodiumWorldRenderer renderer);
}
@@ -1,7 +1,7 @@
package com.gtnewhorizons.angelica.glsm;
import com.google.common.collect.ImmutableSet;
import com.gtnewhorizons.angelica.glsm.stacks.IStateStack;
import com.gtnewhorizon.gtnhlib.client.renderer.stacks.IStateStack;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import org.lwjgl.opengl.GL11;
@@ -50,12 +50,11 @@ public class Feature {
// GL_COLOR_LOGIC_OP enable bit
// GL_INDEX_LOGIC_OP enable bit
// Logic op function
, GLStateManager.colorMask // Color mode and index mode writemasks
, GLStateManager.color // Color mode and index mode writemasks
, GLStateManager.clearColor // Color mode and index mode clear values
, GLStateManager.colorMask // Color-mode and index-mode writemasks
, GLStateManager.clearColor // Color-mode and index-mode clear values
));
attribToFeatures.put(GL11.GL_CURRENT_BIT, ImmutableSet.of(
// Current RGBA color
GLStateManager.color // Current RGBA color
// Current color index
// Current normal vector
// Current texture coordinates
@@ -78,13 +77,20 @@ public class Feature {
// GL_AUTO_NORMAL flag
, GLStateManager.blendMode // GL_BLEND flag
// Enable bits for the user-definable clipping planes
// GL_COLOR_MATERIAL
, GLStateManager.colorMaterial // GL_COLOR_MATERIAL
, GLStateManager.cullState // GL_CULL_FACE flag
, GLStateManager.depthTest // GL_DEPTH_TEST flag
// GL_DITHER flag
, GLStateManager.fogMode // GL_FOG flag
// GL_LIGHTi where 0 <= i < GL_MAX_LIGHTS
// GL_LIGHTING flag
, GLStateManager.lightStates[0] // GL_LIGHT0
, GLStateManager.lightStates[1] // GL_LIGHT1
, GLStateManager.lightStates[2] // GL_LIGHT2
, GLStateManager.lightStates[3] // GL_LIGHT3
, GLStateManager.lightStates[4] // GL_LIGHT4
, GLStateManager.lightStates[5] // GL_LIGHT5
, GLStateManager.lightStates[6] // GL_LIGHT6
, GLStateManager.lightStates[7] // GL_LIGHT7
, GLStateManager.lightingState // GL_LIGHTING flag
// GL_LINE_SMOOTH flag
// GL_LINE_STIPPLE flag
// GL_INDEX_LOGIC_OP flag
@@ -102,7 +108,7 @@ public class Feature {
// GL_SAMPLE_ALPHA_TO_COVERAGE flag
// GL_SAMPLE_ALPHA_TO_ONE flag
// GL_SAMPLE_COVERAGE flag
// GL_SCISSOR_TEST flag
, GLStateManager.scissorTest // GL_SCISSOR_TEST flag
// GL_STENCIL_TEST flag
// GL_TEXTURE_1D flag
// GL_TEXTURE_2D flag - Below
@@ -142,21 +148,37 @@ public class Feature {
// GL_TEXTURE_COMPRESSION_HINT setting
));
attribToFeatures.put(GL11.GL_LIGHTING_BIT, ImmutableSet.of(
// GL_COLOR_MATERIAL enable bit
// GL_COLOR_MATERIAL_FACE value
// Color material parameters that are tracking the current color
// Ambient scene color
// GL_LIGHT_MODEL_LOCAL_VIEWER value
// GL_LIGHT_MODEL_TWO_SIDE setting
// GL_LIGHTING enable bit
GLStateManager.colorMaterial // GL_COLOR_MATERIAL enable bit
, GLStateManager.colorMaterialFace // GL_COLOR_MATERIAL_FACE value
, GLStateManager.colorMaterialParameter // Color material parameters that are tracking the current color
, GLStateManager.lightModel // Ambient scene color, GL_LIGHT_MODEL_LOCAL_VIEWER, GL_LIGHT_MODEL_TWO_SIDE
, GLStateManager.lightingState // GL_LIGHTING enable bit
// Enable bit for each light
, GLStateManager.lightStates[0] // GL_LIGHT0
, GLStateManager.lightStates[1] // GL_LIGHT1
, GLStateManager.lightStates[2] // GL_LIGHT2
, GLStateManager.lightStates[3] // GL_LIGHT3
, GLStateManager.lightStates[4] // GL_LIGHT4
, GLStateManager.lightStates[5] // GL_LIGHT5
, GLStateManager.lightStates[6] // GL_LIGHT6
, GLStateManager.lightStates[7] // GL_LIGHT7
// Ambient, diffuse, and specular intensity for each light
// Direction, position, exponent, and cutoff angle for each light
// Constant, linear, and quadratic attenuation factors for each light
, GLStateManager.lightDataStates[0]
, GLStateManager.lightDataStates[1]
, GLStateManager.lightDataStates[2]
, GLStateManager.lightDataStates[3]
, GLStateManager.lightDataStates[4]
, GLStateManager.lightDataStates[5]
, GLStateManager.lightDataStates[6]
, GLStateManager.lightDataStates[7]
// Ambient, diffuse, specular, and emissive color for each material
// Ambient, diffuse, and specular color indices for each material
// Specular exponent for each material
// GL_SHADE_MODEL setting
, GLStateManager.frontMaterial
, GLStateManager.backMaterial
, GLStateManager.shadeModelState // GL_SHADE_MODEL setting
));
attribToFeatures.put(GL11.GL_LINE_BIT, ImmutableSet.of(
// GL_LINE_SMOOTH flag
@@ -207,7 +229,7 @@ public class Feature {
// Polygon stipple pattern
));
attribToFeatures.put(GL11.GL_SCISSOR_BIT, ImmutableSet.of(
// GL_SCISSOR_TEST enable bit
GLStateManager.scissorTest // GL_SCISSOR_TEST enable bit
// Scissor box
));
attribToFeatures.put(GL11.GL_STENCIL_BUFFER_BIT, ImmutableSet.of(
@@ -219,11 +241,14 @@ public class Feature {
// Stencil buffer writemask
));
final Set<IStateStack<?>> textureAttribs = new HashSet<>(ImmutableSet.of(
GLStateManager.activeTextureUnit // Active texture unit
// Enable bits for the four texture coordinates
// Border color for each texture image
// Minification function for each texture image
// Magnification function for each texture image
// Texture coordinates and wrap mode for each texture image
// Color and mode for each texture environment
// Enable bits GL_TEXTURE_GEN_x, x is S, T, R, and Q
// GL_TEXTURE_GEN_MODE setting for S, T, R, and Q
@@ -234,15 +259,17 @@ public class Feature {
// Current Texture Bindings - GL_TEXTURE_BINDING_2D
for(int i = 0 ; i < GLStateManager.MAX_TEXTURE_UNITS; i++) {
textureAttribs.add(GLStateManager.textures.getTextureUnitBindings(i));
// textureAttribs.add(GLStateManager.textures.getInfo(i))
}
attribToFeatures.put(GL11.GL_TEXTURE_BIT, textureAttribs);
attribToFeatures.put(GL11.GL_TRANSFORM_BIT, ImmutableSet.of(
// Coefficients of the six clipping planes
// Enable bits for the user-definable clipping planes
GLStateManager.matrixMode
GLStateManager.matrixMode
// GL_NORMALIZE flag
// GL_RESCALE_NORMAL flag
, GLStateManager.rescaleNormalState // GL_RESCALE_NORMAL flag
));
attribToFeatures.put(GL11.GL_VIEWPORT_BIT, ImmutableSet.of(
// Depth range (near and far)
@@ -3,11 +3,8 @@
* License terms: https://www.lwjgl.org/license
*/
package net.coderbot.iris.gl;
package com.gtnewhorizons.angelica.glsm;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.loading.AngelicaTweaker;
import net.coderbot.iris.Iris;
import org.lwjgl.opengl.AMDDebugOutput;
import org.lwjgl.opengl.AMDDebugOutputCallback;
import org.lwjgl.opengl.ARBDebugOutput;
@@ -21,6 +18,7 @@ import org.lwjgl.opengl.KHRDebugCallback;
import java.io.PrintStream;
import java.util.function.Consumer;
import static com.gtnewhorizons.angelica.loading.AngelicaTweaker.LOGGER;
import static org.lwjgl.opengl.ARBDebugOutput.glDebugMessageCallbackARB;
public final class GLDebug {
@@ -30,7 +28,7 @@ public final class GLDebug {
*/
public static int setupDebugMessageCallback() {
if (Thread.currentThread() != GLStateManager.getMainThread()) {
AngelicaTweaker.LOGGER.warn("setupDebugMessageCallback called from non-main thread!");
LOGGER.warn("setupDebugMessageCallback called from non-main thread!");
return 0;
}
return setupDebugMessageCallback(System.err);
@@ -64,7 +62,7 @@ public final class GLDebug {
return throwable;
}
private static void printTrace(PrintStream stream) {
public static void printTrace(PrintStream stream) {
trace(new Consumer<String>() {
boolean first = true;
@@ -84,8 +82,8 @@ public final class GLDebug {
* @return 0 for failure, 1 for success, 2 for restart required.
*/
public static int setupDebugMessageCallback(PrintStream stream) {
if (Iris.capabilities.OpenGL43 || Iris.capabilities.GL_KHR_debug) {
Iris.logger.info("[GL] Using OpenGL 4.3 for error logging.");
if (GLStateManager.capabilities.OpenGL43 || GLStateManager.capabilities.GL_KHR_debug) {
LOGGER.info("[GL] Using OpenGL 4.3 for error logging.");
KHRDebugCallback proc = new KHRDebugCallback((source, type, id, severity, message) -> {
stream.println("[LWJGL] OpenGL debug message");
printDetail(stream, "ID", String.format("0x%X", id));
@@ -102,13 +100,13 @@ public final class GLDebug {
GL43.glDebugMessageCallback(proc);
if ((GL11.glGetInteger(GL30.GL_CONTEXT_FLAGS) & GL43.GL_CONTEXT_FLAG_DEBUG_BIT) == 0) {
Iris.logger.warn("[GL] Warning: A non-debug context may not produce any debug output.");
LOGGER.warn("[GL] Warning: A non-debug context may not produce any debug output.");
GL11.glEnable(GL43.GL_DEBUG_OUTPUT);
return 2;
}
return 1;
} else if (Iris.capabilities.GL_ARB_debug_output) {
Iris.logger.info("[GL] Using ARB_debug_output for error logging.");
} else if (GLStateManager.capabilities.GL_ARB_debug_output) {
LOGGER.info("[GL] Using ARB_debug_output for error logging.");
ARBDebugOutputCallback proc = new ARBDebugOutputCallback((source, type, id, severity, message) -> {
stream.println("[LWJGL] ARB_debug_output message");
printDetail(stream, "ID", String.format("0x%X", id));
@@ -124,8 +122,8 @@ public final class GLDebug {
ARBDebugOutput.glDebugMessageControlARB(GL11.GL_DONT_CARE, GL11.GL_DONT_CARE, GL43.GL_DEBUG_SEVERITY_NOTIFICATION, null, false);
ARBDebugOutput.glDebugMessageCallbackARB(proc);
return 1;
} else if (Iris.capabilities.GL_AMD_debug_output) {
Iris.logger.info("[GL] Using AMD_debug_output for error logging.");
} else if (GLStateManager.capabilities.GL_AMD_debug_output) {
LOGGER.info("[GL] Using AMD_debug_output for error logging.");
AMDDebugOutputCallback proc = new AMDDebugOutputCallback((id, category, severity, message) -> {
stream.println("[LWJGL] AMD_debug_output message");
printDetail(stream, "ID", String.format("0x%X", id));
@@ -141,29 +139,29 @@ public final class GLDebug {
AMDDebugOutput.glDebugMessageCallbackAMD(proc);
return 1;
} else {
Iris.logger.info("[GL] No debug output implementation is available, cannot return debug info.");
LOGGER.info("[GL] No debug output implementation is available, cannot return debug info.");
return 0;
}
}
public static int disableDebugMessages() {
if (Iris.capabilities.OpenGL43) {
if (GLStateManager.capabilities.OpenGL43) {
GL43.glDebugMessageCallback(null);
return 1;
} else if (Iris.capabilities.GL_KHR_debug) {
} else if (GLStateManager.capabilities.GL_KHR_debug) {
KHRDebug.glDebugMessageCallback(null);
if (Iris.capabilities.OpenGL30 && (GL11.glGetInteger(GL30.GL_CONTEXT_FLAGS) & 2) == 0) {
if (GLStateManager.capabilities.OpenGL30 && (GL11.glGetInteger(GL30.GL_CONTEXT_FLAGS) & 2) == 0) {
GL11.glDisable(GL43.GL_DEBUG_OUTPUT);
}
return 1;
} else if (Iris.capabilities.GL_ARB_debug_output) {
} else if (GLStateManager.capabilities.GL_ARB_debug_output) {
glDebugMessageCallbackARB(null);
return 1;
} else if (Iris.capabilities.GL_AMD_debug_output) {
} else if (GLStateManager.capabilities.GL_AMD_debug_output) {
AMDDebugOutput.glDebugMessageCallbackAMD(null);
return 1;
} else {
Iris.logger.info("[GL] No debug output implementation is available, cannot disable debug info.");
LOGGER.info("[GL] No debug output implementation is available, cannot disable debug info.");
return 0;
}
}
@@ -273,14 +271,20 @@ public final class GLDebug {
private static DebugState debugState;
private static interface DebugState {
private interface DebugState {
void nameObject(int id, int object, String name);
void pushGroup(int id, String name);
void pushGroup(String name);
void popGroup();
}
void debugMessage(String name);
String getObjectLabel(int glProgram, int program);
}
private static class KHRDebugState implements DebugState {
private boolean hasGroup;
private static final int ID = 0;
private int depth = 0;
private static final int maxDepth = GL11.glGetInteger(KHRDebug.GL_MAX_DEBUG_GROUP_STACK_DEPTH);
private static final int maxNameLength = GL11.glGetInteger(KHRDebug.GL_MAX_LABEL_LENGTH);
@Override
public void nameObject(int id, int object, String name) {
@@ -288,19 +292,36 @@ public final class GLDebug {
}
@Override
public void pushGroup(int id, String name) {
KHRDebug.glPushDebugGroup(KHRDebug.GL_DEBUG_SOURCE_APPLICATION, id, name);
hasGroup = true;
public void pushGroup(String name) {
depth++;
if (depth > maxDepth) {
throw new RuntimeException("Stack overflow");
}
KHRDebug.glPushDebugGroup(KHRDebug.GL_DEBUG_SOURCE_APPLICATION, ID, name);
}
@Override
public void popGroup() {
if (hasGroup) {
KHRDebug.glPopDebugGroup();
hasGroup = false;
}
depth--;
if (depth < 0) {
throw new RuntimeException("Stack underflow");
}
KHRDebug.glPopDebugGroup();
}
}
@Override
public void debugMessage(String message) {
KHRDebug.glDebugMessageInsert(KHRDebug.GL_DEBUG_SOURCE_APPLICATION, KHRDebug.GL_DEBUG_TYPE_MARKER, ID, KHRDebug.GL_DEBUG_SEVERITY_NOTIFICATION, message);
}
@Override
public String getObjectLabel(int glProgram, int program) {
if(program == 0)
return "";
return KHRDebug.glGetObjectLabel(glProgram, program, maxNameLength);
}
}
private static class UnsupportedDebugState implements DebugState {
@Override
@@ -308,16 +329,26 @@ public final class GLDebug {
}
@Override
public void pushGroup(int id, String name) {
public void pushGroup(String name) {
}
@Override
public void popGroup() {
}
}
public static void initRenderer() {
if (Iris.capabilities.GL_KHR_debug || Iris.capabilities.OpenGL43) {
@Override
public void debugMessage(String name) {
}
@Override
public String getObjectLabel(int glProgram, int program) {
return "";
}
}
public static void initDebugState() {
if (GLStateManager.capabilities.GL_KHR_debug || GLStateManager.capabilities.OpenGL43) {
debugState = new KHRDebugState();
} else {
debugState = new UnsupportedDebugState();
@@ -325,6 +356,31 @@ public final class GLDebug {
}
public static void nameObject(int id, int object, String name) {
debugState.nameObject(id, object, name);
if(debugState != null && Thread.currentThread() == GLStateManager.getMainThread()) {
debugState.nameObject(id, object, name);
}
}
public static void pushGroup(String group) {
if(debugState != null && Thread.currentThread() == GLStateManager.getMainThread()) {
debugState.pushGroup(group);
}
}
public static void popGroup() {
if(debugState != null && Thread.currentThread() == GLStateManager.getMainThread()) {
debugState.popGroup();
}
}
public static void debugMessage(String message) {
if(debugState != null && Thread.currentThread() == GLStateManager.getMainThread()) {
debugState.debugMessage(message);
}
}
public static String getObjectLabel(int glProgram, int program) {
if(debugState != null && Thread.currentThread() == GLStateManager.getMainThread()) {
return debugState.getObjectLabel(glProgram, program);
}
return "";
}
}
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,277 @@
package com.gtnewhorizons.angelica.glsm;
import com.gtnewhorizons.angelica.glsm.dsa.DSAARB;
import com.gtnewhorizons.angelica.glsm.dsa.DSAAccess;
import com.gtnewhorizons.angelica.glsm.dsa.DSACore;
import com.gtnewhorizons.angelica.glsm.dsa.DSAUnsupported;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jetbrains.annotations.Nullable;
import org.joml.Matrix4f;
import org.joml.Vector3i;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.EXTShaderImageLoadStore;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL30;
import org.lwjgl.opengl.GL40;
import org.lwjgl.opengl.GL42;
import org.lwjgl.opengl.GL43;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
/**
* This class is responsible for abstracting calls to OpenGL and asserting that calls are run on the render thread.
*/
public class RenderSystem {
private static final Logger LOGGER = LogManager.getLogger("RenderSystem");
private static DSAAccess dsaState;
private static boolean hasMultibind;
private static boolean supportsCompute;
private RenderSystem() {}
public static void initRenderer() {
try {
if (GLStateManager.capabilities.OpenGL45) {
dsaState = new DSACore();
LOGGER.info("OpenGL 4.5 detected, enabling DSA.");
}
hasMultibind = GLStateManager.capabilities.OpenGL45;
} catch (NoSuchFieldError ignored) {}
try {
if (dsaState == null && GLStateManager.capabilities.GL_ARB_direct_state_access) {
dsaState = new DSAARB();
LOGGER.info("ARB_direct_state_access detected, enabling DSA.");
}
} catch (NoSuchFieldError ignored) {}
if (dsaState == null) {
dsaState = new DSAUnsupported();
LOGGER.info("No DSA support detected, falling back to legacy OpenGL.");
}
try {
hasMultibind |= GLStateManager.capabilities.GL_ARB_multi_bind;
} catch (NoSuchFieldError ignored) {}
supportsCompute = supportsCompute();
}
public static void generateMipmaps(int texture, int mipmapTarget) {
dsaState.generateMipmaps(texture, mipmapTarget);
}
public static void bindAttributeLocation(int program, int index, CharSequence name) {
GL20.glBindAttribLocation(program, index, name);
}
public static void texImage2D(int texture, int target, int level, int internalformat, int width, int height, int border, int format, int type, @Nullable ByteBuffer pixels) {
GLStateManager.glBindTexture(GL11.GL_TEXTURE_2D, texture);
GLStateManager.glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
}
public static void uniformMatrix4fv(int location, boolean transpose, FloatBuffer matrix) {
GL20.glUniformMatrix4(location, transpose, matrix);
}
public static void copyTexImage2D(int target, int level, int internalFormat, int x, int y, int width, int height, int border) {
GL11.glCopyTexImage2D(target, level, internalFormat, x, y, width, height, border);
}
public static void uniform1f(int location, float v0) {
GL20.glUniform1f(location, v0);
}
public static void uniform1i(int location, int v0) {
GL20.glUniform1i(location, v0);
}
public static void uniform2f(int location, float v0, float v1) {
GL20.glUniform2f(location, v0, v1);
}
public static void uniform2i(int location, int v0, int v1) {
GL20.glUniform2i(location, v0, v1);
}
public static void uniform3f(int location, float v0, float v1, float v2) {
GL20.glUniform3f(location, v0, v1, v2);
}
public static void uniform4f(int location, float v0, float v1, float v2, float v3) {
GL20.glUniform4f(location, v0, v1, v2, v3);
}
public static void uniform4i(int location, int v0, int v1, int v2, int v3) {
GL20.glUniform4i(location, v0, v1, v2, v3);
}
public static int getAttribLocation(int programId, String name) {
return GL20.glGetAttribLocation(programId, name);
}
public static int getUniformLocation(int programId, String name) {
return GL20.glGetUniformLocation(programId, name);
}
public static void texParameteriv(int texture, int target, int pname, IntBuffer params) {
dsaState.texParameteriv(texture, target, pname, params);
}
public static void copyTexSubImage2D(int destTexture, int target, int i, int i1, int i2, int i3, int i4, int width, int height) {
dsaState.copyTexSubImage2D(destTexture, target, i, i1, i2, i3, i4, width, height);
}
public static void texParameteri(int texture, int target, int pname, int param) {
dsaState.texParameteri(texture, target, pname, param);
}
public static void texParameterf(int texture, int target, int pname, float param) {
dsaState.texParameterf(texture, target, pname, param);
}
public static String getProgramInfoLog(int program) {
return GL20.glGetProgramInfoLog(program, GL20.glGetProgrami(program, GL20.GL_INFO_LOG_LENGTH));
}
public static String getShaderInfoLog(int shader) {
return GL20.glGetShaderInfoLog(shader, GL20.glGetShaderi(shader, GL20.GL_INFO_LOG_LENGTH));
}
public static void drawBuffers(int framebuffer, IntBuffer buffers) {
dsaState.drawBuffers(framebuffer, buffers);
}
public static void readBuffer(int framebuffer, int buffer) {
dsaState.readBuffer(framebuffer, buffer);
}
public static String getActiveUniform(int program, int index, int maxLength, IntBuffer sizeType) {
return GL20.glGetActiveUniform(program, index, maxLength, sizeType);
}
public static void readPixels(int x, int y, int width, int height, int format, int type, FloatBuffer pixels) {
GL11.glReadPixels(x, y, width, height, format, type, pixels);
}
public static void bufferData(int target, FloatBuffer data, int usage) {
GL15.glBufferData(target, data, usage);
}
public static int bufferStorage(int target, FloatBuffer data, int usage) {
return dsaState.bufferStorage(target, data, usage);
}
public static void vertexAttrib4f(int index, float v0, float v1, float v2, float v3) {
GL20.glVertexAttrib4f(index, v0, v1, v2, v3);
}
public static void detachShader(int program, int shader) {
GL20.glDetachShader(program, shader);
}
public static void framebufferTexture2D(int fb, int fbtarget, int attachment, int target, int texture, int levels) {
dsaState.framebufferTexture2D(fb, fbtarget, attachment, target, texture, levels);
}
public static int getTexParameteri(int texture, int target, int pname) {
return dsaState.getTexParameteri(texture, target, pname);
}
public static void bindImageTexture(int unit, int texture, int level, boolean layered, int layer, int access, int format) {
if (GLStateManager.capabilities.OpenGL42) {
GL42.glBindImageTexture(unit, texture, level, layered, layer, access, format);
} else {
EXTShaderImageLoadStore.glBindImageTextureEXT(unit, texture, level, layered, layer, access, format);
}
}
public static int getMaxImageUnits() {
if (GLStateManager.capabilities.OpenGL42) {
return GL11.glGetInteger(GL42.GL_MAX_IMAGE_UNITS);
} else if (GLStateManager.capabilities.GL_EXT_shader_image_load_store) {
return GL11.glGetInteger(EXTShaderImageLoadStore.GL_MAX_IMAGE_UNITS_EXT);
} else {
return 0;
}
}
public static void getProgramiv(int program, int value, IntBuffer storage) {
GL20.glGetProgram(program, value, storage);
}
public static void dispatchCompute(int workX, int workY, int workZ) {
GL43.glDispatchCompute(workX, workY, workZ);
}
public static void dispatchCompute(Vector3i workGroups) {
GL43.glDispatchCompute(workGroups.x, workGroups.y, workGroups.z);
}
public static void memoryBarrier(int barriers) {
if (supportsCompute) {
GL42.glMemoryBarrier(barriers);
}
}
public static boolean supportsBufferBlending() {
return GLStateManager.capabilities.GL_ARB_draw_buffers_blend || GLStateManager.capabilities.OpenGL40;
}
public static void disableBufferBlend(int buffer) {
GL30.glDisablei(GL11.GL_BLEND, buffer);
}
public static void enableBufferBlend(int buffer) {
GL30.glEnablei(GL11.GL_BLEND, buffer);
}
public static void blendFuncSeparatei(int buffer, int srcRGB, int dstRGB, int srcAlpha, int dstAlpha) {
GL40.glBlendFuncSeparatei(buffer, srcRGB, dstRGB, srcAlpha, dstAlpha);
}
public static void bindTextureToUnit(int unit, int texture) {
dsaState.bindTextureToUnit(unit, texture);
}
public static final FloatBuffer PROJECTION_MATRIX_BUFFER = BufferUtils.createFloatBuffer(16);
public static void setupProjectionMatrix(Matrix4f matrix) {
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glPushMatrix();
matrix.get(0, PROJECTION_MATRIX_BUFFER);
GL11.glLoadMatrix(PROJECTION_MATRIX_BUFFER);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
}
public static void restoreProjectionMatrix() {
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glPopMatrix();
GL11.glMatrixMode(GL11.GL_MODELVIEW);
}
public static void blitFramebuffer(int source, int dest, int offsetX, int offsetY, int width, int height, int offsetX2, int offsetY2, int width2, int height2, int bufferChoice, int filter) {
dsaState.blitFramebuffer(source, dest, offsetX, offsetY, width, height, offsetX2, offsetY2, width2, height2, bufferChoice, filter);
}
public static int createFramebuffer() {
return dsaState.createFramebuffer();
}
public static int createTexture(int target) {
return dsaState.createTexture(target);
}
// TODO: Proper notification of compute support
public static boolean supportsCompute() {
try {
return GLStateManager.capabilities.GL_ARB_compute_shader;
} catch(Exception ignored) {
return false;
}
}
}
@@ -1,94 +0,0 @@
package com.gtnewhorizons.angelica.glsm;
import com.gtnewhorizons.angelica.client.renderer.CapturingTessellator;
import com.gtnewhorizons.angelica.compat.mojang.VertexBuffer;
import com.gtnewhorizons.angelica.compat.mojang.VertexFormat;
import com.gtnewhorizons.angelica.compat.nd.Quad;
import net.minecraft.client.renderer.Tessellator;
import java.nio.ByteBuffer;
import java.util.List;
@SuppressWarnings("unused")
public class TessellatorManager {
private static final ThreadLocal<CapturingTessellator> capturingTessellator = ThreadLocal.withInitial(CapturingTessellator::new);
private static final ThreadLocal<Boolean> currentlyCapturing = ThreadLocal.withInitial(() -> Boolean.FALSE);
private static final Thread mainThread = Thread.currentThread();
public static Tessellator get() {
if(currentlyCapturing.get()) {
return capturingTessellator.get();
} else if(isOnMainThread()) {
return Tessellator.instance;
} else {
// TODO: Verify this works correctly and nothing unexpected is grabbing a tessellator off the main thread
// when not capturing
throw new IllegalStateException("Tried to get the Tessellator off the main thread when not capturing!");
}
}
public static boolean isOnMainThread() {
return Thread.currentThread() == mainThread;
}
public static boolean isMainInstance(Object instance) {
return instance == Tessellator.instance || isOnMainThread();
}
public static void startCapturing() {
if(currentlyCapturing.get()) throw new IllegalStateException("Tried to start capturing when already capturing!");
if(capturingTessellator.get().getQuads().size() > 0) throw new IllegalStateException("Tried to start capturing with existing collected Quads!");
currentlyCapturing.set(true);
}
/*
* Stop the CapturingTessellator and return the pooled quads. The quads are valid until clearQuads() is
* called on the CapturingTesselator, which must be done before starting capturing again.
*/
public static List<Quad> stopCapturingToPooledQuads() {
if(!currentlyCapturing.get()) throw new IllegalStateException("Tried to stop capturing when not capturing!");
currentlyCapturing.set(false);
final CapturingTessellator tess = capturingTessellator.get();
// Be sure we got all the quads
if(tess.isDrawing) tess.draw();
final List<Quad> quads = tess.getQuads();
tess.discard();
return quads;
}
/*
* Stops the CapturingTessellator, stores the quads in a buffer (based on the VertexFormat provided),
* and clears the quads.
*/
public static ByteBuffer stopCapturingToBuffer(VertexFormat format) {
final ByteBuffer buf = CapturingTessellator.quadsToBuffer(stopCapturingToPooledQuads(), format);
capturingTessellator.get().clearQuads();
return buf;
}
/*
* Stops the CapturingTessellator, stores the quads in a buffer (based on the VertexFormat provided),
* uploads the buffer to a new VertexBuffer, and clears the quads.
*/
public static VertexBuffer stopCapturingToVBO(VertexFormat format) {
return new VertexBuffer(format).upload(stopCapturingToBuffer(format));
}
static {
System.out.println("[TessellatorManager] Initialized on thread " + mainThread.getName());
}
public static void cleanup() {
// Ensure we've cleaned everything up
final CapturingTessellator tessellator = capturingTessellator.get();
currentlyCapturing.set(false);
tessellator.discard();
tessellator.clearQuads();
}
}
@@ -1,48 +0,0 @@
package com.gtnewhorizons.angelica.glsm;
import com.gtnewhorizons.angelica.compat.mojang.VertexBuffer;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import it.unimi.dsi.fastutil.objects.ObjectList;
public class VBOManager {
// Not thread safe, only expected to be called from the main thread
private static int nextDisplayList = Integer.MIN_VALUE;
private static int getNextDisplayList() {
return nextDisplayList++;
}
private static ObjectList<VertexBuffer> vertexBuffers = new ObjectArrayList<>(1);
/*
* Allocate a (range) of "display list IDs" that will refer to a VBO in the arraylist of vertex buffers.
*/
public static int generateDisplayLists(int range) {
if(range < 1) throw new IllegalArgumentException("Range must be at least 1!");
final int id = getNextDisplayList();
for (int i = 1; i < range; i++) {
// Reserve, but don't use, the rest in the range
getNextDisplayList();
}
// Return the first in the range
return id;
}
public static VertexBuffer registerVBO(int displayList, VertexBuffer vertexBuffer) {
if(displayList > 0) throw new IllegalArgumentException("Display list must be negative!");
displayList -= Integer.MIN_VALUE;
final int requestedSize = displayList + 1;
if(requestedSize + 1 > vertexBuffers.size()) {
vertexBuffers.size(requestedSize);
}
vertexBuffers.set(displayList, vertexBuffer);
return vertexBuffer;
}
public static VertexBuffer get(int list) {
list -= Integer.MIN_VALUE;
return vertexBuffers.get(list);
}
}
@@ -0,0 +1,474 @@
package com.gtnewhorizons.angelica.glsm.debug;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import org.apache.commons.io.FileUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.joml.Matrix4f;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
// Adapted from https://github.com/makamys/CoreTweaks/blob/master/src/main/java/makamys/coretweaks/util/OpenGLDebugging.java;
// originally from https://github.com/TheGreyGhost/MinecraftByExample/blob/1-8final/src/main/java/minecraftbyexample/usefultools/OpenGLdebugging.java
public class OpenGLDebugging {
public static final Logger LOGGER = LogManager.getLogger("gldumper");
private static final Consumer<String> LINE_LOGGER = LOGGER::debug;
public static final String GL_IS_ENABLED = "glIsEnabled()";
public static final String GL_GET_BOOLEANV = "glGetBooleanv()";
public static final String GL_GET_INTEGERV = "glGetIntegerv()";
public static final String GL_GET_FLOATV = "glGetFloatv()";
public class GLproperty {
public GLproperty(int glConstant, String name, String description, String category, String fetchCommand) {
this.gLConstant = glConstant;
this.name = name;
this.description = description;
this.category = category;
this.fetchCommand = fetchCommand;
}
public int gLConstant;
public String name;
public String description;
public String category;
public String fetchCommand;
static final ByteBuffer byteBuffer = BufferUtils.createByteBuffer(16);
static final IntBuffer intBuffer = BufferUtils.createIntBuffer(16);
static final FloatBuffer floatBuffer = BufferUtils.createFloatBuffer(16);
public String getAsString(boolean glsm) {
switch(fetchCommand) {
case GL_IS_ENABLED: {
return "" + (glsm ? GLStateManager.glIsEnabled(gLConstant) : GL11.glIsEnabled(gLConstant));
}
case GL_GET_BOOLEANV: {
if(GLStateManager.HAS_MULTIPLE_SET.contains(gLConstant)) {
byteBuffer.clear();
if(glsm) {
GLStateManager.glGetBoolean(gLConstant, byteBuffer);
} else {
GL11.glGetBoolean(gLConstant, byteBuffer);
}
final StringBuilder out = new StringBuilder();
for (int i = 0; i < byteBuffer.capacity(); ++i) {
out.append(i == 0 ? "" : ", ").append(byteBuffer.get(i));
}
return out.toString();
} else {
return "" + (glsm ? GLStateManager.glGetBoolean(gLConstant) : GL11.glGetBoolean(gLConstant));
}
}
case GL_GET_INTEGERV: {
if(GLStateManager.HAS_MULTIPLE_SET.contains(gLConstant)) {
intBuffer.clear();
if(glsm) {
GLStateManager.glGetInteger(gLConstant, intBuffer);
} else {
GL11.glGetInteger(gLConstant, intBuffer);
}
final StringBuilder out = new StringBuilder();
for (int i = 0; i < intBuffer.remaining(); ++i) {
out.append(i == 0 ? "" : ", ").append(intBuffer.get(i));
}
return out.toString();
} else {
return "" + (glsm ? GLStateManager.glGetInteger(gLConstant) : GL11.glGetInteger(gLConstant));
}
}
case GL_GET_FLOATV: {
if(GLStateManager.HAS_MULTIPLE_SET.contains(gLConstant)) {
floatBuffer.clear();
if(glsm) {
GLStateManager.glGetFloat(gLConstant, floatBuffer);
} else {
GL11.glGetFloat(gLConstant, floatBuffer);
}
final StringBuilder out = new StringBuilder();
for (int i = 0; i < floatBuffer.remaining(); ++i) {
out.append(i == 0 ? "" : ", ").append(String.format("%f", floatBuffer.get(i)));
}
return out.toString();
} else {
return "" + (glsm ? GLStateManager.glGetFloat(gLConstant) : GL11.glGetFloat(gLConstant));
}
}
default: return "";
}
}
static final Matrix4f cachedMatrix = new Matrix4f();
static final Matrix4f uncachedMatrix = new Matrix4f();
public Matrix4f getAsMatrix4f(boolean glsm) {
if(!fetchCommand.equals(GL_GET_FLOATV)) {
throw new IllegalArgumentException("This property does not return a matrix");
}
floatBuffer.clear();
if(glsm) {
GLStateManager.glGetFloat(gLConstant, floatBuffer);
return cachedMatrix.set(0, floatBuffer);
} else {
GL11.glGetFloat(gLConstant, floatBuffer);
return uncachedMatrix.set(0, floatBuffer);
}
}
}
public static OpenGLDebugging instance = new OpenGLDebugging();
public GLproperty[] propertyList = {
new GLproperty(GL11.GL_ACCUM_ALPHA_BITS, "GL_ACCUM_ALPHA_BITS", "Number of bits per alpha component in the accumulation buffer", "capability", GL_GET_INTEGERV),
new GLproperty(GL11.GL_ACCUM_BLUE_BITS, "GL_ACCUM_BLUE_BITS", "Number of bits per blue component in the accumulation buffer", "capability", GL_GET_INTEGERV),
new GLproperty(GL11.GL_ACCUM_CLEAR_VALUE, "GL_ACCUM_CLEAR_VALUE", "Accumulation-buffer clear value", "accum-buffer", GL_GET_FLOATV),
new GLproperty(GL11.GL_ACCUM_GREEN_BITS, "GL_ACCUM_GREEN_BITS", "Number of bits per green component in the accumulation buffer", "capability", GL_GET_INTEGERV),
new GLproperty(GL11.GL_ACCUM_RED_BITS, "GL_ACCUM_RED_BITS", "Number of bits per red component in the accumulation buffer", "capability", GL_GET_INTEGERV),
new GLproperty(GL11.GL_ALPHA_BITS, "GL_ALPHA_BITS", "Number of bits per alpha component in color buffers", "capability", GL_GET_INTEGERV),
new GLproperty(GL11.GL_ALPHA_TEST, "GL_ALPHA_TEST", "Alpha test enabled", "color-buffer/enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_ALPHA_TEST_FUNC, "GL_ALPHA_TEST_FUNC", "Alpha test function", "color-buffer", GL_GET_INTEGERV),
new GLproperty(GL11.GL_ALPHA_TEST_REF, "GL_ALPHA_TEST_REF", "Alpha test reference value", "color-buffer", GL_GET_FLOATV),
new GLproperty(GL11.GL_AMBIENT, "GL_AMBIENT", "Ambient intensity of light i", "lighting", "glGetLightfv()"),
new GLproperty(GL11.GL_AMBIENT, "GL_AMBIENT", "Ambient material color", "lighting", "glGetMaterialfv()"),
new GLproperty(GL11.GL_ATTRIB_STACK_DEPTH, "GL_ATTRIB_STACK_DEPTH", "Attribute stack pointer", "current", GL_GET_INTEGERV),
new GLproperty(GL11.GL_AUTO_NORMAL, "GL_AUTO_NORMAL", "True if automatic normal generation enabled", "eval", GL_IS_ENABLED),
new GLproperty(GL11.GL_AUX_BUFFERS, "GL_AUX_BUFFERS", "Number of auxiliary buffers", "capability", GL_GET_BOOLEANV),
new GLproperty(GL11.GL_BLEND, "GL_BLEND", "Blending enabled", "color-buffer/enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_BLEND_DST, "GL_BLEND_DST", "Blending destination function", "color-buffer", GL_GET_INTEGERV),
new GLproperty(GL11.GL_BLEND_SRC, "GL_BLEND_SRC", "Blending source function", "color-buffer", GL_GET_INTEGERV),
new GLproperty(GL11.GL_BLUE_BITS, "GL_BLUE_BITS", "Number of bits per blue component in color buffers", "capability", GL_GET_INTEGERV),
new GLproperty(GL11.GL_CLIENT_ATTRIB_STACK_DEPTH, "GL_CLIENT_ATTRIB_STACK_DEPTH", "Client attribute stack pointer", "current", GL_GET_INTEGERV),
new GLproperty(GL11.GL_COEFF, "GL_COEFF", "1D control points", "capability", "glGetMapfv()"),
new GLproperty(GL11.GL_COEFF, "GL_COEFF", "2D control points", "capability", "glGetMapfv()"),
new GLproperty(GL11.GL_COLOR_ARRAY, "GL_COLOR_ARRAY", "RGBA color array enable", "vertex-array", GL_IS_ENABLED),
new GLproperty(GL11.GL_COLOR_ARRAY_POINTER, "GL_COLOR_ARRAY_POINTER", "Pointer to the color array", "vertex-array", "glGetPointerv()"),
new GLproperty(GL11.GL_COLOR_ARRAY_SIZE, "GL_COLOR_ARRAY_SIZE", "Colors per vertex", "vertex-array", GL_GET_INTEGERV),
new GLproperty(GL11.GL_COLOR_ARRAY_STRIDE, "GL_COLOR_ARRAY_STRIDE", "Stride between colors", "vertex-array", GL_GET_INTEGERV),
new GLproperty(GL11.GL_COLOR_ARRAY_TYPE, "GL_COLOR_ARRAY_TYPE", "Type of color components", "vertex-array", GL_GET_INTEGERV),
new GLproperty(GL11.GL_COLOR_CLEAR_VALUE, "GL_COLOR_CLEAR_VALUE", "Color-buffer clear value (RGBA mode)", "color-buffer", GL_GET_FLOATV),
new GLproperty(GL11.GL_COLOR_INDEXES, "GL_COLOR_INDEXES", "ca, cd, and cs for color-index lighting", "lighting/e nable", "glGetMaterialfv()"),
new GLproperty(GL11.GL_COLOR_LOGIC_OP, "GL_COLOR_LOGIC_OP", "RGBA color logical operation enabled", "color-buffer/enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_COLOR_MATERIAL, "GL_COLOR_MATERIAL", "True if color tracking is enabled", "lighting", GL_IS_ENABLED),
new GLproperty(GL11.GL_COLOR_MATERIAL_FACE, "GL_COLOR_MATERIAL_FACE", "Face(s) affected by color tracking", "lighting", GL_GET_INTEGERV),
new GLproperty(GL11.GL_COLOR_MATERIAL_PARAMETER, "GL_COLOR_MATERIAL_PARAMETER", "Material properties tracking current color", "lighting", GL_GET_INTEGERV),
new GLproperty(GL11.GL_COLOR_WRITEMASK, "GL_COLOR_WRITEMASK", "Color write enables; R, G, B, or A", "color-buffer", GL_GET_BOOLEANV),
new GLproperty(GL11.GL_CONSTANT_ATTENUATION, "GL_CONSTANT_ATTENUATION", "Constant attenuation factor", "lighting", "glGetLightfv()"),
new GLproperty(GL11.GL_CULL_FACE, "GL_CULL_FACE", "Polygon culling enabled", "polygon/enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_CULL_FACE_MODE, "GL_CULL_FACE_MODE", "Cull front-/back-facing polygons", "polygon", GL_GET_INTEGERV),
new GLproperty(GL11.GL_CURRENT_COLOR, "GL_CURRENT_COLOR", "Current color", "current", GL_GET_FLOATV),
new GLproperty(GL11.GL_CURRENT_INDEX, "GL_CURRENT_INDEX", "Current color index", "current", GL_GET_FLOATV),
new GLproperty(GL11.GL_CURRENT_NORMAL, "GL_CURRENT_NORMAL", "Current normal", "current", GL_GET_FLOATV),
new GLproperty(GL11.GL_CURRENT_RASTER_COLOR, "GL_CURRENT_RASTER_COLOR", "Color associated with raster position", "current", GL_GET_FLOATV),
new GLproperty(GL11.GL_CURRENT_RASTER_DISTANCE, "GL_CURRENT_RASTER_DISTANCE", "Current raster distance", "current", GL_GET_FLOATV),
new GLproperty(GL11.GL_CURRENT_RASTER_INDEX, "GL_CURRENT_RASTER_INDEX", "Color index associated with raster position", "current", GL_GET_FLOATV),
new GLproperty(GL11.GL_CURRENT_RASTER_POSITION, "GL_CURRENT_RASTER_POSITION", "Current raster position", "current", GL_GET_FLOATV),
new GLproperty(GL11.GL_CURRENT_RASTER_POSITION_VALID, "GL_CURRENT_RASTER_POSITION_VALID", "Raster position valid bit", "current", GL_GET_BOOLEANV),
new GLproperty(GL11.GL_CURRENT_RASTER_TEXTURE_COORDS, "GL_CURRENT_RASTER_TEXTURE_COORDS", "Texture coordinates associated with raster position", "current", GL_GET_FLOATV),
new GLproperty(GL11.GL_CURRENT_TEXTURE_COORDS, "GL_CURRENT_TEXTURE_COORDS", "Current texture coordinates", "current", GL_GET_FLOATV),
new GLproperty(GL11.GL_DEPTH_BITS, "GL_DEPTH_BITS", "Number of depth-buffer bitplanes", "capability", GL_GET_INTEGERV),
new GLproperty(GL11.GL_DEPTH_CLEAR_VALUE, "GL_DEPTH_CLEAR_VALUE", "Depth-buffer clear value", "depth-buffer", GL_GET_INTEGERV),
new GLproperty(GL11.GL_DEPTH_FUNC, "GL_DEPTH_FUNC", "Depth buffer test function", "depth-buffer", GL_GET_INTEGERV),
new GLproperty(GL11.GL_DEPTH_RANGE, "GL_DEPTH_RANGE", "Depth range near and far", "viewport", GL_GET_FLOATV),
new GLproperty(GL11.GL_DEPTH_TEST, "GL_DEPTH_TEST", "Depth buffer enabled", "depth-buffer/ena ble", GL_IS_ENABLED),
new GLproperty(GL11.GL_DEPTH_WRITEMASK, "GL_DEPTH_WRITEMASK", "Depth buffer enabled for writing", "depth-buffer", GL_GET_BOOLEANV),
new GLproperty(GL11.GL_DIFFUSE, "GL_DIFFUSE", "Diffuse intensity of light i", "lighting", "glGetLightfv()"),
new GLproperty(GL11.GL_DIFFUSE, "GL_DIFFUSE", "Diffuse material color", "lighting", "glGetMaterialfv()"),
new GLproperty(GL11.GL_DITHER, "GL_DITHER", "Dithering enabled", "color-buffer/enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_DOMAIN, "GL_DOMAIN", "1D domain endpoints", "capability", "glGetMapfv()"),
new GLproperty(GL11.GL_DOMAIN, "GL_DOMAIN", "2D domain endpoints", "capability", "glGetMapfv()"),
new GLproperty(GL11.GL_DOUBLEBUFFER, "GL_DOUBLEBUFFER", "True if front and back buffers exist", "capability", GL_GET_BOOLEANV),
new GLproperty(GL11.GL_DRAW_BUFFER, "GL_DRAW_BUFFER", "Buffers selected for drawing", "color-buffer", GL_GET_INTEGERV),
new GLproperty(GL11.GL_EDGE_FLAG, "GL_EDGE_FLAG", "Edge flag", "current", GL_GET_BOOLEANV),
new GLproperty(GL11.GL_EDGE_FLAG_ARRAY, "GL_EDGE_FLAG_ARRAY", "Edge flag array enable", "vertex-array", GL_IS_ENABLED),
new GLproperty(GL11.GL_EDGE_FLAG_ARRAY_POINTER, "GL_EDGE_FLAG_ARRAY_POINTER", "Pointer to the edge flag array", "vertex-array", "glGetPointerv()"),
new GLproperty(GL11.GL_EDGE_FLAG_ARRAY_STRIDE, "GL_EDGE_FLAG_ARRAY_STRIDE", "Stride between edge flags", "vertex-array", GL_GET_INTEGERV),
new GLproperty(GL11.GL_EMISSION, "GL_EMISSION", "Emissive material color", "lighting", "glGetMaterialfv()"),
new GLproperty(GL11.GL_EYE_PLANE, "GL_EYE_PLANE", "Texgen plane equation coefficients", "texture", "glGetTexGenfv()"),
new GLproperty(GL11.GL_FEEDBACK_BUFFER_POINTER, "GL_FEEDBACK_BUFFER_POINTER", "Pointer to feedback buffer", "feedback", "glGetPointerv()"),
new GLproperty(GL11.GL_FEEDBACK_BUFFER_SIZE, "GL_FEEDBACK_BUFFER_SIZE", "Size of feedback buffer", "feedback", GL_GET_INTEGERV),
new GLproperty(GL11.GL_FEEDBACK_BUFFER_TYPE, "GL_FEEDBACK_BUFFER_TYPE", "Type of feedback buffer", "feedback", GL_GET_INTEGERV),
new GLproperty(GL11.GL_FOG, "GL_FOG", "True if fog enabled", "fog/enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_FOG_COLOR, "GL_FOG_COLOR", "Fog color", "fog", GL_GET_FLOATV),
new GLproperty(GL11.GL_FOG_DENSITY, "GL_FOG_DENSITY", "Exponential fog density", "fog", GL_GET_FLOATV),
new GLproperty(GL11.GL_FOG_END, "GL_FOG_END", "Linear fog end", "fog", GL_GET_FLOATV),
new GLproperty(GL11.GL_FOG_HINT, "GL_FOG_HINT", "Fog hint", "hint", GL_GET_INTEGERV),
new GLproperty(GL11.GL_FOG_INDEX, "GL_FOG_INDEX", "Fog index", "fog", GL_GET_FLOATV),
new GLproperty(GL11.GL_FOG_MODE, "GL_FOG_MODE", "Fog mode", "fog", GL_GET_INTEGERV),
new GLproperty(GL11.GL_FOG_START, "GL_FOG_START", "Linear fog start", "fog", GL_GET_FLOATV),
new GLproperty(GL11.GL_FRONT_FACE, "GL_FRONT_FACE", "Polygon front-face CW/CCW indicator", "polygon", GL_GET_INTEGERV),
new GLproperty(GL11.GL_GREEN_BITS, "GL_GREEN_BITS", "Number of bits per green component in color buffers", "capability", GL_GET_INTEGERV),
new GLproperty(GL11.GL_INDEX_ARRAY, "GL_INDEX_ARRAY", "Color-index array enable", "vertex-array", GL_IS_ENABLED),
new GLproperty(GL11.GL_INDEX_ARRAY_POINTER, "GL_INDEX_ARRAY_POINTER", "Pointer to the index array", "vertex-array", "glGetPointerv()"),
new GLproperty(GL11.GL_INDEX_ARRAY_STRIDE, "GL_INDEX_ARRAY_STRIDE", "Stride between color indices", "vertex-array", GL_GET_INTEGERV),
new GLproperty(GL11.GL_INDEX_ARRAY_TYPE, "GL_INDEX_ARRAY_TYPE", "Type of color indices", "vertex-array", GL_GET_INTEGERV),
new GLproperty(GL11.GL_INDEX_BITS, "GL_INDEX_BITS", "Number of bits per index in color buffers", "capability", GL_GET_INTEGERV),
new GLproperty(GL11.GL_INDEX_CLEAR_VALUE, "GL_INDEX_CLEAR_VALUE", "Color-buffer clear value (color-index mode)", "color-buffer", GL_GET_FLOATV),
new GLproperty(GL11.GL_INDEX_LOGIC_OP, "GL_INDEX_LOGIC_OP", "Color index logical operation enabled", "color-buffer/enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_INDEX_MODE, "GL_INDEX_MODE", "True if color buffers store indices", "capability", GL_GET_BOOLEANV),
new GLproperty(GL11.GL_INDEX_OFFSET, "GL_INDEX_OFFSET", "Value of GL_INDEX_OFFSET", "pixel", GL_GET_INTEGERV),
new GLproperty(GL11.GL_INDEX_SHIFT, "GL_INDEX_SHIFT", "Value of GL_INDEX_SHIFT", "pixel", GL_GET_INTEGERV),
new GLproperty(GL11.GL_INDEX_WRITEMASK, "GL_INDEX_WRITEMASK", "Color-index writemask", "color-buffer", GL_GET_INTEGERV),
new GLproperty(GL11.GL_LIGHT0, "GL_LIGHT0", "True if light 0 enabled", "lighting/enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_LIGHT1, "GL_LIGHT1", "True if light 1 enabled", "lighting/enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_LIGHT2, "GL_LIGHT2", "True if light 2 enabled", "lighting/enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_LIGHT3, "GL_LIGHT3", "True if light 3 enabled", "lighting/enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_LIGHT4, "GL_LIGHT4", "True if light 4 enabled", "lighting/enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_LIGHT5, "GL_LIGHT5", "True if light 5 enabled", "lighting/enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_LIGHT6, "GL_LIGHT6", "True if light 6 enabled", "lighting/enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_LIGHT7, "GL_LIGHT7", "True if light 7 enabled", "lighting/enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_LIGHTING, "GL_LIGHTING", "True if lighting is enabled", "lighting/e nable", GL_IS_ENABLED),
new GLproperty(GL11.GL_LIGHT_MODEL_AMBIENT, "GL_LIGHT_MODEL_AMBIENT", "Ambient scene color", "lighting", GL_GET_FLOATV),
new GLproperty(GL11.GL_LIGHT_MODEL_LOCAL_VIEWER, "GL_LIGHT_MODEL_LOCAL_VIEWER", "Viewer is local", "lighting", GL_GET_BOOLEANV),
new GLproperty(GL11.GL_LIGHT_MODEL_TWO_SIDE, "GL_LIGHT_MODEL_TWO_SIDE", "Use two-sided lighting", "lighting", GL_GET_BOOLEANV),
new GLproperty(GL11.GL_LINEAR_ATTENUATION, "GL_LINEAR_ATTENUATION", "Linear attenuation factor", "lighting", "glGetLightfv()"),
new GLproperty(GL11.GL_LINE_SMOOTH, "GL_LINE_SMOOTH", "Line antialiasing on", "line/enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_LINE_SMOOTH_HINT, "GL_LINE_SMOOTH_HINT", "Line smooth hint", "hint", GL_GET_INTEGERV),
new GLproperty(GL11.GL_LINE_STIPPLE, "GL_LINE_STIPPLE", "Line stipple enable", "line/enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_LINE_STIPPLE_PATTERN, "GL_LINE_STIPPLE_PATTERN", "Line stipple", "line", GL_GET_INTEGERV),
new GLproperty(GL11.GL_LINE_STIPPLE_REPEAT, "GL_LINE_STIPPLE_REPEAT", "Line stipple repeat", "line", GL_GET_INTEGERV),
new GLproperty(GL11.GL_LINE_WIDTH, "GL_LINE_WIDTH", "Line width", "line", GL_GET_FLOATV),
new GLproperty(GL11.GL_LINE_WIDTH_GRANULARITY, "GL_LINE_WIDTH_GRANULARITY", "Antialiased line-width granularity", "capability", GL_GET_FLOATV),
new GLproperty(GL11.GL_LINE_WIDTH_RANGE, "GL_LINE_WIDTH_RANGE", "Range (low to high) of antialiased line widths", "capability", GL_GET_FLOATV),
new GLproperty(GL11.GL_LIST_BASE, "GL_LIST_BASE", "Setting of glListBase()", "list", GL_GET_INTEGERV),
new GLproperty(GL11.GL_LIST_INDEX, "GL_LIST_INDEX", "Number of display list under construction; 0 if none", "current", GL_GET_INTEGERV),
new GLproperty(GL11.GL_LIST_MODE, "GL_LIST_MODE", "Mode of display list under construction; undefined if none", "current", GL_GET_INTEGERV),
new GLproperty(GL11.GL_LOGIC_OP_MODE, "GL_LOGIC_OP_MODE", "Logical operation function", "color-buffer", GL_GET_INTEGERV),
new GLproperty(GL11.GL_MAP1_GRID_DOMAIN, "GL_MAP1_GRID_DOMAIN", "1D grid endpoints", "eval", GL_GET_FLOATV),
new GLproperty(GL11.GL_MAP1_GRID_SEGMENTS, "GL_MAP1_GRID_SEGMENTS", "1D grid divisions", "eval", GL_GET_FLOATV),
new GLproperty(GL11.GL_MAP2_GRID_DOMAIN, "GL_MAP2_GRID_DOMAIN", "2D grid endpoints", "eval", GL_GET_FLOATV),
new GLproperty(GL11.GL_MAP2_GRID_SEGMENTS, "GL_MAP2_GRID_SEGMENTS", "2D grid divisions", "eval", GL_GET_FLOATV),
new GLproperty(GL11.GL_MAP_COLOR, "GL_MAP_COLOR", "True if colors are mapped", "pixel", GL_GET_BOOLEANV),
new GLproperty(GL11.GL_MAP_STENCIL, "GL_MAP_STENCIL", "True if stencil values are mapped", "pixel", GL_GET_BOOLEANV),
new GLproperty(GL11.GL_MATRIX_MODE, "GL_MATRIX_MODE", "Current matrix mode", "transform", GL_GET_INTEGERV),
new GLproperty(GL11.GL_MAX_ATTRIB_STACK_DEPTH, "GL_MAX_ATTRIB_STACK_DEPTH", "Maximum depth of the attribute stack", "capability", GL_GET_INTEGERV),
new GLproperty(GL11.GL_MAX_CLIENT_ATTRIB_STACK_DEPTH, "GL_MAX_CLIENT_ATTRIB_STACK_DEPTH", "Maximum depth of the client attribute stack", "capability", GL_GET_INTEGERV),
new GLproperty(GL11.GL_MAX_CLIP_PLANES, "GL_MAX_CLIP_PLANES", "Maximum number of user clipping planes", "capability", GL_GET_INTEGERV),
new GLproperty(GL11.GL_MAX_EVAL_ORDER, "GL_MAX_EVAL_ORDER", "Maximum evaluator polynomial order", "capability", GL_GET_INTEGERV),
new GLproperty(GL11.GL_MAX_LIGHTS, "GL_MAX_LIGHTS", "Maximum number of lights", "capability", GL_GET_INTEGERV),
new GLproperty(GL11.GL_MAX_LIST_NESTING, "GL_MAX_LIST_NESTING", "Maximum display-list call nesting", "capability", GL_GET_INTEGERV),
new GLproperty(GL11.GL_MAX_MODELVIEW_STACK_DEPTH, "GL_MAX_MODELVIEW_STACK_DEPTH", "Maximum modelview-matrix stack depth", "capability", GL_GET_INTEGERV),
new GLproperty(GL11.GL_MAX_NAME_STACK_DEPTH, "GL_MAX_NAME_STACK_DEPTH", "Maximum selection-name stack depth", "capability", GL_GET_INTEGERV),
new GLproperty(GL11.GL_MAX_PIXEL_MAP_TABLE, "GL_MAX_PIXEL_MAP_TABLE", "Maximum size of a glPixelMap() translation table", "capability", GL_GET_INTEGERV),
new GLproperty(GL11.GL_MAX_PROJECTION_STACK_DEPTH, "GL_MAX_PROJECTION_STACK_DEPTH", "Maximum projection-matrix stack depth", "capability", GL_GET_INTEGERV),
new GLproperty(GL11.GL_MAX_TEXTURE_SIZE, "GL_MAX_TEXTURE_SIZE", "See discussion in Texture Proxy in Chapter 9", "capability", GL_GET_INTEGERV),
new GLproperty(GL11.GL_MAX_TEXTURE_STACK_DEPTH, "GL_MAX_TEXTURE_STACK_DEPTH", "Maximum depth of texture matrix stack", "capability", GL_GET_INTEGERV),
new GLproperty(GL11.GL_MAX_VIEWPORT_DIMS, "GL_MAX_VIEWPORT_DIMS", "Maximum viewport dimensions", "capability", GL_GET_INTEGERV),
new GLproperty(GL11.GL_MODELVIEW_MATRIX, "GL_MODELVIEW_MATRIX", "Modelview matrix stack", "matrix", GL_GET_FLOATV),
new GLproperty(GL11.GL_MODELVIEW_STACK_DEPTH, "GL_MODELVIEW_STACK_DEPTH", "Modelview matrix stack pointer", "matrix", GL_GET_INTEGERV),
new GLproperty(GL11.GL_NAME_STACK_DEPTH, "GL_NAME_STACK_DEPTH", "Name stack depth", "current", GL_GET_INTEGERV),
new GLproperty(GL11.GL_NORMALIZE, "GL_NORMALIZE", "Current normal normalization on/off", "transform/ enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_NORMAL_ARRAY, "GL_NORMAL_ARRAY", "Normal array enable", "vertex-array", GL_IS_ENABLED),
new GLproperty(GL11.GL_NORMAL_ARRAY_POINTER, "GL_NORMAL_ARRAY_POINTER", "Pointer to the normal array", "vertex-array", "glGetPointerv()"),
new GLproperty(GL11.GL_NORMAL_ARRAY_STRIDE, "GL_NORMAL_ARRAY_STRIDE", "Stride between normals", "vertex-array", GL_GET_INTEGERV),
new GLproperty(GL11.GL_NORMAL_ARRAY_TYPE, "GL_NORMAL_ARRAY_TYPE", "Type of normal coordinates", "vertex-array", GL_GET_INTEGERV),
new GLproperty(GL11.GL_OBJECT_PLANE, "GL_OBJECT_PLANE", "Texgen object linear coefficients", "texture", "glGetTexGenfv()"),
new GLproperty(GL11.GL_ORDER, "GL_ORDER", "1D map order", "capability", "glGetMapiv()"),
new GLproperty(GL11.GL_ORDER, "GL_ORDER", "2D map orders", "capability", "glGetMapiv()"),
new GLproperty(GL11.GL_PACK_ALIGNMENT, "GL_PACK_ALIGNMENT", "Value of GL_PACK_ALIGNMENT", "pixel-store", GL_GET_INTEGERV),
new GLproperty(GL11.GL_PACK_LSB_FIRST, "GL_PACK_LSB_FIRST", "Value of GL_PACK_LSB_FIRST", "pixel-store", GL_GET_BOOLEANV),
new GLproperty(GL11.GL_PACK_ROW_LENGTH, "GL_PACK_ROW_LENGTH", "Value of GL_PACK_ROW_LENGTH", "pixel-store", GL_GET_INTEGERV),
new GLproperty(GL11.GL_PACK_SKIP_PIXELS, "GL_PACK_SKIP_PIXELS", "Value of GL_PACK_SKIP_PIXELS", "pixel-store", GL_GET_INTEGERV),
new GLproperty(GL11.GL_PACK_SKIP_ROWS, "GL_PACK_SKIP_ROWS", "Value of GL_PACK_SKIP_ROWS", "pixel-store", GL_GET_INTEGERV),
new GLproperty(GL11.GL_PACK_SWAP_BYTES, "GL_PACK_SWAP_BYTES", "Value of GL_PACK_SWAP_BYTES", "pixel-store", GL_GET_BOOLEANV),
new GLproperty(GL11.GL_PERSPECTIVE_CORRECTION_HINT, "GL_PERSPECTIVE_CORRECTION_HINT", "Perspective correction hint", "hint", GL_GET_INTEGERV),
new GLproperty(GL11.GL_POINT_SIZE, "GL_POINT_SIZE", "Point size", "point", GL_GET_FLOATV),
new GLproperty(GL11.GL_POINT_SIZE_GRANULARITY, "GL_POINT_SIZE_GRANULARITY", "Antialiased point-size granularity", "capability", GL_GET_FLOATV),
new GLproperty(GL11.GL_POINT_SIZE_RANGE, "GL_POINT_SIZE_RANGE", "Range (low to high) of antialiased point sizes", "capability", GL_GET_FLOATV),
new GLproperty(GL11.GL_POINT_SMOOTH, "GL_POINT_SMOOTH", "Point antialiasing on", "point/enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_POINT_SMOOTH_HINT, "GL_POINT_SMOOTH_HINT", "Point smooth hint", "hint", GL_GET_INTEGERV),
new GLproperty(GL11.GL_POLYGON_MODE, "GL_POLYGON_MODE", "Polygon rasterization mode (front and back)", "polygon", GL_GET_INTEGERV),
new GLproperty(GL11.GL_POLYGON_OFFSET_FACTOR, "GL_POLYGON_OFFSET_FACTOR", "Polygon offset factor", "polygon", GL_GET_FLOATV),
new GLproperty(GL11.GL_POLYGON_OFFSET_FILL, "GL_POLYGON_OFFSET_FILL", "Polygon offset enable for GL_FILL mode rasterization", "polygon/enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_POLYGON_OFFSET_LINE, "GL_POLYGON_OFFSET_LINE", "Polygon offset enable for GL_LINE mode rasterization", "polygon/enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_POLYGON_OFFSET_POINT, "GL_POLYGON_OFFSET_POINT", "Polygon offset enable for GL_POINT mode rasterization", "polygon/enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_POLYGON_SMOOTH, "GL_POLYGON_SMOOTH", "Polygon antialiasing on", "polygon/enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_POLYGON_SMOOTH_HINT, "GL_POLYGON_SMOOTH_HINT", "Polygon smooth hint", "hint", GL_GET_INTEGERV),
new GLproperty(GL11.GL_POLYGON_STIPPLE, "GL_POLYGON_STIPPLE", "Polygon stipple enable", "polygon/enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_POSITION, "GL_POSITION", "Position of light i", "lighting", "glGetLightfv()"),
new GLproperty(GL11.GL_PROJECTION_MATRIX, "GL_PROJECTION_MATRIX", "Projection matrix stack", "matrix", GL_GET_FLOATV),
new GLproperty(GL11.GL_PROJECTION_STACK_DEPTH, "GL_PROJECTION_STACK_DEPTH", "Projection matrix stack pointer", "matrix", GL_GET_INTEGERV),
new GLproperty(GL11.GL_QUADRATIC_ATTENUATION, "GL_QUADRATIC_ATTENUATION", "Quadratic attenuation factor", "lighting", "glGetLightfv()"),
new GLproperty(GL11.GL_READ_BUFFER, "GL_READ_BUFFER", "Read source buffer", "pixel", GL_GET_INTEGERV),
new GLproperty(GL11.GL_RED_BITS, "GL_RED_BITS", "Number of bits per red component in color buffers", "capability", GL_GET_INTEGERV),
new GLproperty(GL11.GL_RENDER_MODE, "GL_RENDER_MODE", "glRenderMode() setting", "current", GL_GET_INTEGERV),
new GLproperty(GL11.GL_RGBA_MODE, "GL_RGBA_MODE", "True if color buffers store RGBA", "capability", GL_GET_BOOLEANV),
new GLproperty(GL11.GL_SCISSOR_BOX, "GL_SCISSOR_BOX", "Scissor box", "scissor", GL_GET_INTEGERV),
new GLproperty(GL11.GL_SCISSOR_TEST, "GL_SCISSOR_TEST", "Scissoring enabled", "scissor/enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_SELECTION_BUFFER_POINTER, "GL_SELECTION_BUFFER_POINTER", "Pointer to selection buffer", "select", "glGetPointerv()"),
new GLproperty(GL11.GL_SELECTION_BUFFER_SIZE, "GL_SELECTION_BUFFER_SIZE", "Size of selection buffer", "select", GL_GET_INTEGERV),
new GLproperty(GL11.GL_SHADE_MODEL, "GL_SHADE_MODEL", "glShadeModel() setting", "lighting", GL_GET_INTEGERV),
new GLproperty(GL11.GL_SHININESS, "GL_SHININESS", "Specular exponent of material", "lighting", "glGetMaterialfv()"),
new GLproperty(GL11.GL_SPECULAR, "GL_SPECULAR", "Specular intensity of light i", "lighting", "glGetLightfv()"),
new GLproperty(GL11.GL_SPECULAR, "GL_SPECULAR", "Specular material color", "lighting", "glGetMaterialfv()"),
new GLproperty(GL11.GL_SPOT_CUTOFF, "GL_SPOT_CUTOFF", "Spotlight angle of light i", "lighting", "glGetLightfv()"),
new GLproperty(GL11.GL_SPOT_DIRECTION, "GL_SPOT_DIRECTION", "Spotlight direction of light i", "lighting", "glGetLightfv()"),
new GLproperty(GL11.GL_SPOT_EXPONENT, "GL_SPOT_EXPONENT", "Spotlight exponent of light i", "lighting", "glGetLightfv()"),
new GLproperty(GL11.GL_STENCIL_BITS, "GL_STENCIL_BITS", "Number of stencil bitplanes", "capability", GL_GET_INTEGERV),
new GLproperty(GL11.GL_STENCIL_CLEAR_VALUE, "GL_STENCIL_CLEAR_VALUE", "Stencil-buffer clear value", "stencil-buffer", GL_GET_INTEGERV),
new GLproperty(GL11.GL_STENCIL_FAIL, "GL_STENCIL_FAIL", "Stencil fail action", "stencil-buffer", GL_GET_INTEGERV),
new GLproperty(GL11.GL_STENCIL_FUNC, "GL_STENCIL_FUNC", "Stencil function", "stencil-buffer", GL_GET_INTEGERV),
new GLproperty(GL11.GL_STENCIL_PASS_DEPTH_FAIL, "GL_STENCIL_PASS_DEPTH_FAIL", "Stencil depth buffer fail action", "stencil-buffer", GL_GET_INTEGERV),
new GLproperty(GL11.GL_STENCIL_PASS_DEPTH_PASS, "GL_STENCIL_PASS_DEPTH_PASS", "Stencil depth buffer pass action", "stencil-buffer", GL_GET_INTEGERV),
new GLproperty(GL11.GL_STENCIL_REF, "GL_STENCIL_REF", "Stencil reference value", "stencil-buffer", GL_GET_INTEGERV),
new GLproperty(GL11.GL_STENCIL_TEST, "GL_STENCIL_TEST", "Stenciling enabled", "stencil-buffer/enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_STENCIL_VALUE_MASK, "GL_STENCIL_VALUE_MASK", "Stencil mask", "stencil-buffer", GL_GET_INTEGERV),
new GLproperty(GL11.GL_STENCIL_WRITEMASK, "GL_STENCIL_WRITEMASK", "Stencil-buffer writemask", "stencil-buffer", GL_GET_INTEGERV),
new GLproperty(GL11.GL_STEREO, "GL_STEREO", "True if left and right buffers exist", "capability", GL_GET_BOOLEANV),
new GLproperty(GL11.GL_SUBPIXEL_BITS, "GL_SUBPIXEL_BITS", "Number of bits of subpixel precision in x and y", "capability", GL_GET_INTEGERV),
new GLproperty(GL11.GL_TEXTURE, "GL_TEXTURE", "x-D texture image at level of detail i", "UNUSED", "glGetTexImage()"),
new GLproperty(GL11.GL_TEXTURE_1D, "GL_TEXTURE_1D", "True if 1-D texturing enabled ", "texture/enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_TEXTURE_2D, "GL_TEXTURE_2D", "True if 2-D texturing enabled ", "texture/enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_TEXTURE_ALPHA_SIZE, "GL_TEXTURE_ALPHA_SIZE", "x-D texture image i's alpha resolution", "UNUSED", "glGetTexLevelParameter*()"),
new GLproperty(GL11.GL_TEXTURE_BINDING_1D, "GL_TEXTURE_BINDING_1D", "Texture object bound to GL_TEXTURE_1D", "texture", GL_GET_INTEGERV),
new GLproperty(GL11.GL_TEXTURE_BINDING_2D, "GL_TEXTURE_BINDING_2D", "Texture object bound to GL_TEXTURE_2D", "texture", GL_GET_INTEGERV),
new GLproperty(GL11.GL_TEXTURE_BLUE_SIZE, "GL_TEXTURE_BLUE_SIZE", "x-D texture image i's blue resolution", "UNUSED", "glGetTexLevelParameter*()"),
new GLproperty(GL11.GL_TEXTURE_BORDER, "GL_TEXTURE_BORDER", "x-D texture image i's border width", "UNUSED", "glGetTexLevelParameter*()"),
new GLproperty(GL11.GL_TEXTURE_BORDER_COLOR, "GL_TEXTURE_BORDER_COLOR", "Texture border color", "texture", "glGetTexParameter*()"),
new GLproperty(GL11.GL_TEXTURE_COORD_ARRAY, "GL_TEXTURE_COORD_ARRAY", "Texture coordinate array enable", "vertex-array", GL_IS_ENABLED),
new GLproperty(GL11.GL_TEXTURE_COORD_ARRAY_POINTER, "GL_TEXTURE_COORD_ARRAY_POINTER", "Pointer to the texture coordinate array", "vertex-array", "glGetPointerv()"),
new GLproperty(GL11.GL_TEXTURE_COORD_ARRAY_SIZE, "GL_TEXTURE_COORD_ARRAY_SIZE", "Texture coordinates per element", "vertex-array", GL_GET_INTEGERV),
new GLproperty(GL11.GL_TEXTURE_COORD_ARRAY_STRIDE, "GL_TEXTURE_COORD_ARRAY_STRIDE", "Stride between texture coordinates", "vertex-array", GL_GET_INTEGERV),
new GLproperty(GL11.GL_TEXTURE_COORD_ARRAY_TYPE, "GL_TEXTURE_COORD_ARRAY_TYPE", "Type of texture coordinates", "vertex-array", GL_GET_INTEGERV),
new GLproperty(GL11.GL_TEXTURE_ENV_COLOR, "GL_TEXTURE_ENV_COLOR", "Texture environment color", "texture", "glGetTexEnvfv()"),
new GLproperty(GL11.GL_TEXTURE_ENV_MODE, "GL_TEXTURE_ENV_MODE", "Texture application function", "texture", "glGetTexEnviv()"),
new GLproperty(GL11.GL_TEXTURE_GEN_MODE, "GL_TEXTURE_GEN_MODE", "Function used for texgen", "texture", "glGetTexGeniv()"),
new GLproperty(GL11.GL_TEXTURE_GEN_Q, "GL_TEXTURE_GEN_Q", "Texgen enabled (x is S, T, R, or Q)", "texture/enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_TEXTURE_GEN_R, "GL_TEXTURE_GEN_R", "Texgen enabled (x is S, T, R, or Q)", "texture/enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_TEXTURE_GEN_S, "GL_TEXTURE_GEN_S", "Texgen enabled (x is S, T, R, or Q)", "texture/enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_TEXTURE_GEN_T, "GL_TEXTURE_GEN_T", "Texgen enabled (x is S, T, R, or Q)", "texture/enable", GL_IS_ENABLED),
new GLproperty(GL11.GL_TEXTURE_GREEN_SIZE, "GL_TEXTURE_GREEN_SIZE", "x-D texture image i's green resolution", "UNUSED", "glGetTexLevelParameter*()"),
new GLproperty(GL11.GL_TEXTURE_HEIGHT, "GL_TEXTURE_HEIGHT", "x-D texture image i's height", "UNUSED", "glGetTexLevelParameter*()"),
new GLproperty(GL11.GL_TEXTURE_INTENSITY_SIZE, "GL_TEXTURE_INTENSITY_SIZE", "x-D texture image i's intensity resolution", "UNUSED", "glGetTexLevelParameter*()"),
new GLproperty(GL11.GL_TEXTURE_LUMINANCE_SIZE, "GL_TEXTURE_LUMINANCE_SIZE", "x-D texture image i's luminance resolution", "UNUSED", "glGetTexLevelParameter*()"),
new GLproperty(GL11.GL_TEXTURE_MAG_FILTER, "GL_TEXTURE_MAG_FILTER", "Texture magnification function", "texture", "glGetTexParameter*()"),
new GLproperty(GL11.GL_TEXTURE_MATRIX, "GL_TEXTURE_MATRIX", "Texture matrix stack", "matrix", GL_GET_FLOATV),
new GLproperty(GL11.GL_TEXTURE_MIN_FILTER, "GL_TEXTURE_MIN_FILTER", "Texture minification function", "texture", "glGetTexParameter*()"),
new GLproperty(GL11.GL_TEXTURE_PRIORITY, "GL_TEXTURE_PRIORITY", "Texture object priority", "texture", "glGetTexParameter*()"),
new GLproperty(GL11.GL_TEXTURE_RED_SIZE, "GL_TEXTURE_RED_SIZE", "x-D texture image i's red resolution", "UNUSED", "glGetTexLevelParameter*()"),
new GLproperty(GL11.GL_TEXTURE_STACK_DEPTH, "GL_TEXTURE_STACK_DEPTH", "Texture matrix stack pointer", "matrix", GL_GET_INTEGERV),
new GLproperty(GL11.GL_TEXTURE_WIDTH, "GL_TEXTURE_WIDTH", "x-D texture image i's width", "UNUSED", "glGetTexLevelParameter*()"),
new GLproperty(GL11.GL_TEXTURE_WRAP_S, "GL_TEXTURE_WRAP_S", "Texture wrap mode (x is S or T)", "texture", "glGetTexParameter*()"),
new GLproperty(GL11.GL_TEXTURE_WRAP_T, "GL_TEXTURE_WRAP_T", "Texture wrap mode (x is S or T)", "texture", "glGetTexParameter*()"),
new GLproperty(GL11.GL_UNPACK_ALIGNMENT, "GL_UNPACK_ALIGNMENT", "Value of GL_UNPACK_ALIGNMENT", "pixel-store", GL_GET_INTEGERV),
new GLproperty(GL11.GL_UNPACK_LSB_FIRST, "GL_UNPACK_LSB_FIRST", "Value of GL_UNPACK_LSB_FIRST", "pixel-store", GL_GET_BOOLEANV),
new GLproperty(GL11.GL_UNPACK_ROW_LENGTH, "GL_UNPACK_ROW_LENGTH", "Value of GL_UNPACK_ROW_LENGTH", "pixel-store", GL_GET_INTEGERV),
new GLproperty(GL11.GL_UNPACK_SKIP_PIXELS, "GL_UNPACK_SKIP_PIXELS", "Value of GL_UNPACK_SKIP_PIXELS", "pixel-store", GL_GET_INTEGERV),
new GLproperty(GL11.GL_UNPACK_SKIP_ROWS, "GL_UNPACK_SKIP_ROWS", "Value of GL_UNPACK_SKIP_ROWS", "pixel-store", GL_GET_INTEGERV),
new GLproperty(GL11.GL_UNPACK_SWAP_BYTES, "GL_UNPACK_SWAP_BYTES", "Value of GL_UNPACK_SWAP_BYTES", "pixel-store", GL_GET_BOOLEANV),
new GLproperty(GL11.GL_VERTEX_ARRAY, "GL_VERTEX_ARRAY", "Vertex array enable", "vertex-array", GL_IS_ENABLED),
new GLproperty(GL11.GL_VERTEX_ARRAY_POINTER, "GL_VERTEX_ARRAY_POINTER", "Pointer to the vertex array", "vertex-array", "glGetPointerv()"),
new GLproperty(GL11.GL_VERTEX_ARRAY_SIZE, "GL_VERTEX_ARRAY_SIZE", "Coordinates per vertex", "vertex-array", GL_GET_INTEGERV),
new GLproperty(GL11.GL_VERTEX_ARRAY_STRIDE, "GL_VERTEX_ARRAY_STRIDE", "Stride between vertices", "vertex-array", GL_GET_INTEGERV),
new GLproperty(GL11.GL_VERTEX_ARRAY_TYPE, "GL_VERTEX_ARRAY_TYPE", "Type of vertex coordinates", "vertex-array", GL_GET_INTEGERV),
new GLproperty(GL11.GL_VIEWPORT, "GL_VIEWPORT", "Viewport origin and extent", "viewport", GL_GET_INTEGERV),
new GLproperty(GL11.GL_ZOOM_X, "GL_ZOOM_X", "x zoom factor", "pixel", GL_GET_FLOATV),
new GLproperty(GL11.GL_ZOOM_Y, "GL_ZOOM_Y", "y zoom factor", "pixel", GL_GET_FLOATV),
};
public static void dumpToFile(Consumer<Consumer<String>> dumper, String fileName) {
final List<String> lines = new ArrayList<>();
dumper.accept(lines::add);
try {
FileUtils.writeLines(new File(fileName), lines);
} catch (IOException e) {
LOGGER.error("Failed to write file");
e.printStackTrace();
}
}
public static void dumpStateToFile() {
dumpToFile(p -> dumpState(p, false), "gl-dump-state.txt");
}
public static void dumpGLSMStateToFile() {
dumpToFile(p -> dumpState(p, true), "glsm-dump-state.txt");
}
public static void dumpState(boolean glsm) {
dumpState(LINE_LOGGER, glsm);
}
public static void dumpState(Consumer<String> printer, boolean glsm) {
for (int i = 0; i < instance.propertyList.length; ++i) {
final GLproperty gLProperty = instance.propertyList[i];
printer.accept(gLProperty.name + ":" + gLProperty.getAsString(glsm) + " (" + gLProperty.description + ")");
}
}
public static void dumpIsEnabledToFile(boolean glsm) {
dumpToFile(p -> dumpIsEnabled(p, glsm), (glsm ? "glsm" : "gl") + "-dump-enabled.txt");
}
public static void dumpIsEnabled(boolean glsm) {
dumpIsEnabled(LINE_LOGGER, glsm);
}
public static void dumpIsEnabled(Consumer<String> printer, boolean glsm) {
for (int i = 0; i < instance.propertyList.length; ++i) {
final GLproperty gLProperty = instance.propertyList[i];
if (gLProperty.fetchCommand.equals(GL_IS_ENABLED)) {
printer.accept(gLProperty.name + ":");
printer.accept("" + gLProperty.getAsString(glsm));
printer.accept(" (" + gLProperty.description + ")");
}
}
}
public static void dumpTypeToFile(String type, boolean glsm) {
dumpToFile(p -> dumpType(type, p, glsm), (glsm ? "glsm" : "gl") + "-dump-type-" + type + ".txt");
}
public static void dumpType(String type, boolean glsm) {
dumpType(type, LINE_LOGGER, glsm);
}
public static void dumpType(String type, Consumer<String> printer, boolean glsm) {
for (int i = 0; i < instance.propertyList.length; ++i) {
final GLproperty gLProperty = instance.propertyList[i];
if (gLProperty.category.equals(type)) {
printer.accept(gLProperty.name + ":");
printer.accept(gLProperty.getAsString(glsm));
printer.accept(" (" + gLProperty.description + ")");
}
}
}
public static void checkGLSM() {
boolean mismatch = false;
for (int i = 0; i < instance.propertyList.length; ++i) {
final GLproperty gLProperty = instance.propertyList[i];
if(gLProperty.fetchCommand.equals(GL_GET_FLOATV) && gLProperty.name.endsWith("_MATRIX")) {
final Matrix4f cached = gLProperty.getAsMatrix4f(true);
final Matrix4f uncached = gLProperty.getAsMatrix4f(false);
// Some precision issues due to RAD vs degrees, and translated (vs f)
if (!cached.equals(uncached, 0.001f)) {
LOGGER.error("GLSM mismatch: " + gLProperty.name + "\ncached:\n" + cached + "uncached:\n" + uncached);
mismatch = true;
}
} else {
final String cached = gLProperty.getAsString(true);
final String uncached = gLProperty.getAsString(false);
if (!cached.equals(uncached)) {
LOGGER.error("GLSM mismatch: " + gLProperty.name + " cached: " + cached + " uncached: " + uncached);
mismatch = true;
}
}
}
if (!mismatch) {
LOGGER.info("GLSM state matches!");
}
}
}
@@ -0,0 +1,95 @@
package com.gtnewhorizons.angelica.glsm.dsa;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import org.lwjgl.opengl.ARBDirectStateAccess;
import org.lwjgl.opengl.GL45;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
public class DSAARB extends DSAUnsupported {
@Override
public void generateMipmaps(int texture, int target) {
ARBDirectStateAccess.glGenerateTextureMipmap(texture);
}
@Override
public void texParameteri(int texture, int target, int pname, int param) {
if(!GLStateManager.updateTexParameteriCache(target, texture, pname, param)) return;
ARBDirectStateAccess.glTextureParameteri(texture, pname, param);
}
@Override
public void texParameterf(int texture, int target, int pname, float param) {
if(!GLStateManager.updateTexParameterfCache(target, texture, pname, param)) return;
ARBDirectStateAccess.glTextureParameterf(texture, pname, param);
}
@Override
public void texParameteriv(int texture, int target, int pname, IntBuffer params) {
ARBDirectStateAccess.glTextureParameter(texture, pname, params);
}
@Override
public void readBuffer(int framebuffer, int buffer) {
ARBDirectStateAccess.glNamedFramebufferReadBuffer(framebuffer, buffer);
}
@Override
public void drawBuffers(int framebuffer, IntBuffer buffers) {
ARBDirectStateAccess.glNamedFramebufferDrawBuffers(framebuffer, buffers);
}
@Override
public int getTexParameteri(int texture, int target, int pname) {
return GLStateManager.getTexParameterOrDefault(texture, pname, () -> ARBDirectStateAccess.glGetTextureParameteri(texture, pname));
}
@Override
public void copyTexSubImage2D(int destTexture, int target, int i, int i1, int i2, int i3, int i4, int width, int height) {
ARBDirectStateAccess.glCopyTextureSubImage2D(destTexture, i, i1, i2, i3, i4, width, height);
}
@Override
public void bindTextureToUnit(int unit, int texture) {
if(GLStateManager.getBoundTexture(unit) == texture) return;
if (texture == 0) {
super.bindTextureToUnit(unit, texture);
} else {
ARBDirectStateAccess.glBindTextureUnit(unit, texture);
GLStateManager.getTextures().getTextureUnitBindings(unit).setBinding(texture);
}
}
@Override
public int bufferStorage(int target, FloatBuffer data, int usage) {
final int buffer = GL45.glCreateBuffers();
GL45.glNamedBufferData(buffer, data, usage);
return buffer;
}
@Override
public void blitFramebuffer(int source, int dest, int offsetX, int offsetY, int width, int height, int offsetX2, int offsetY2, int width2, int height2,
int bufferChoice, int filter) {
ARBDirectStateAccess.glBlitNamedFramebuffer(source, dest, offsetX, offsetY, width, height, offsetX2, offsetY2, width2, height2, bufferChoice, filter);
}
@Override
public void framebufferTexture2D(int fb, int fbtarget, int attachment, int target, int texture, int levels) {
ARBDirectStateAccess.glNamedFramebufferTexture(fb, attachment, texture, levels);
}
@Override
public int createFramebuffer() {
return ARBDirectStateAccess.glCreateFramebuffers();
}
@Override
public int createTexture(int target) {
return ARBDirectStateAccess.glCreateTextures(target);
}
}
@@ -0,0 +1,31 @@
package com.gtnewhorizons.angelica.glsm.dsa;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
public interface DSAAccess {
void generateMipmaps(int texture, int target);
void texParameteri(int texture, int target, int pname, int param);
void texParameterf(int texture, int target, int pname, float param);
void texParameteriv(int texture, int target, int pname, IntBuffer params);
void readBuffer(int framebuffer, int buffer);
void drawBuffers(int framebuffer, IntBuffer buffers);
int getTexParameteri(int texture, int target, int pname);
void copyTexSubImage2D(int destTexture, int target, int i, int i1, int i2, int i3, int i4, int width, int height);
void bindTextureToUnit(int unit, int texture);
int bufferStorage(int target, FloatBuffer data, int usage);
void blitFramebuffer(int source, int dest, int offsetX, int offsetY, int width, int height, int offsetX2, int offsetY2, int width2, int height2, int bufferChoice, int filter);
void framebufferTexture2D(int fb, int fbtarget, int attachment, int target, int texture, int levels);
int createFramebuffer();
int createTexture(int target);
}
@@ -0,0 +1,5 @@
package com.gtnewhorizons.angelica.glsm.dsa;
public class DSACore extends DSAARB {
}
@@ -0,0 +1,110 @@
package com.gtnewhorizons.angelica.glsm.dsa;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.glsm.RenderSystem;
import net.minecraft.client.renderer.OpenGlHelper;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL13;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL30;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
public class DSAUnsupported implements DSAAccess {
@Override
public void generateMipmaps(int texture, int target) {
GLStateManager.glBindTexture(GL11.GL_TEXTURE_2D, texture);
GL30.glGenerateMipmap(target);
}
@Override
public void texParameteri(int texture, int target, int pname, int param) {
GLStateManager.glBindTexture(GL11.GL_TEXTURE_2D, texture);
GLStateManager.glTexParameteri(target, pname, param);
}
@Override
public void texParameterf(int texture, int target, int pname, float param) {
GLStateManager.glBindTexture(GL11.GL_TEXTURE_2D, texture);
GLStateManager.glTexParameterf(target, pname, param);
}
@Override
public void texParameteriv(int texture, int target, int pname, IntBuffer params) {
GLStateManager.glBindTexture(GL11.GL_TEXTURE_2D, texture);
GLStateManager.glTexParameter(target, pname, params);
}
@Override
public void readBuffer(int framebuffer, int buffer) {
OpenGlHelper.func_153171_g/*glBindFramebuffer*/(GL30.GL_FRAMEBUFFER, framebuffer);
GL11.glReadBuffer(buffer);
}
@Override
public void drawBuffers(int framebuffer, IntBuffer buffers) {
OpenGlHelper.func_153171_g/*glBindFramebuffer*/(GL30.GL_FRAMEBUFFER, framebuffer);
GL20.glDrawBuffers(buffers);
}
@Override
public int getTexParameteri(int texture, int target, int pname) {
GLStateManager.glBindTexture(GL11.GL_TEXTURE_2D, texture);
return GLStateManager.glGetTexParameteri(target, pname);
}
@Override
public void copyTexSubImage2D(int destTexture, int target, int i, int i1, int i2, int i3, int i4, int width, int height) {
final int previous = GLStateManager.getBoundTexture();
GLStateManager.glBindTexture(GL11.GL_TEXTURE_2D, destTexture);
GL11.glCopyTexSubImage2D(target, i, i1, i2, i3, i4, width, height);
GLStateManager.glBindTexture(GL11.GL_TEXTURE_2D, previous);
}
@Override
public void bindTextureToUnit(int unit, int texture) {
GLStateManager.glActiveTexture(GL13.GL_TEXTURE0 + unit);
GLStateManager.glBindTexture(GL11.GL_TEXTURE_2D, texture);
}
@Override
public int bufferStorage(int target, FloatBuffer data, int usage) {
final int buffer = GL15.glGenBuffers();
GL15.glBindBuffer(target, buffer);
RenderSystem.bufferData(target, data, usage);
GL15.glBindBuffer(target, 0);
return buffer;
}
@Override
public void blitFramebuffer(int source, int dest, int offsetX, int offsetY, int width, int height, int offsetX2, int offsetY2, int width2, int height2,
int bufferChoice, int filter) {
OpenGlHelper.func_153171_g/*glBindFramebuffer*/(GL30.GL_READ_FRAMEBUFFER, source);
OpenGlHelper.func_153171_g/*glBindFramebuffer*/(GL30.GL_DRAW_FRAMEBUFFER, dest);
GL30.glBlitFramebuffer(offsetX, offsetY, width, height, offsetX2, offsetY2, width2, height2, bufferChoice, filter);
}
@Override
public void framebufferTexture2D(int fb, int fbtarget, int attachment, int target, int texture, int levels) {
OpenGlHelper.func_153171_g/*glBindFramebuffer*/(fbtarget, fb);
GL30.glFramebufferTexture2D(fbtarget, attachment, target, texture, levels);
}
@Override
public int createFramebuffer() {
final int framebuffer = OpenGlHelper.func_153165_e/*glGenFramebuffers*/();
OpenGlHelper.func_153171_g/*glBindFramebuffer*/(GL30.GL_FRAMEBUFFER, framebuffer);
return framebuffer;
}
@Override
public int createTexture(int target) {
final int texture = GL11.glGenTextures();
GLStateManager.glBindTexture(GL11.GL_TEXTURE_2D, texture);
return texture;
}
}
@@ -1,5 +1,6 @@
package com.gtnewhorizons.angelica.glsm.stacks;
import com.gtnewhorizon.gtnhlib.client.renderer.stacks.IStateStack;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.glsm.states.AlphaState;
@@ -34,4 +35,7 @@ public class AlphaStateStack extends AlphaState implements IStateStack<AlphaStat
return this;
}
public boolean isEmpty() {
return pointer == 0;
}
}
@@ -1,5 +1,6 @@
package com.gtnewhorizons.angelica.glsm.stacks;
import com.gtnewhorizon.gtnhlib.client.renderer.stacks.IStateStack;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.glsm.states.BlendState;
@@ -34,4 +35,7 @@ public class BlendStateStack extends BlendState implements IStateStack<BlendStat
return this;
}
public boolean isEmpty() {
return pointer == 0;
}
}
@@ -1,7 +1,9 @@
package com.gtnewhorizons.angelica.glsm.stacks;
import com.gtnewhorizon.gtnhlib.client.renderer.stacks.IStateStack;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.glsm.states.BooleanState;
import org.lwjgl.opengl.GL11;
public class BooleanStateStack extends BooleanState implements IStateStack<BooleanStateStack> {
@@ -32,7 +34,13 @@ public class BooleanStateStack extends BooleanState implements IStateStack<Boole
}
set(stack[--pointer]);
if (GLStateManager.isAMD() && glCap == GL11.GL_BLEND) {
setEnabled(enabled);
}
return this;
}
public boolean isEmpty() {
return pointer == 0;
}
}
@@ -1,5 +1,6 @@
package com.gtnewhorizons.angelica.glsm.stacks;
import com.gtnewhorizon.gtnhlib.client.renderer.stacks.IStateStack;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.glsm.states.Color4;
@@ -16,6 +17,11 @@ public class Color4Stack extends Color4 implements IStateStack<Color4Stack> {
}
}
public Color4Stack(Color4 color4) {
this();
set(color4);
}
public Color4Stack push() {
if(pointer == stack.length) {
throw new IllegalStateException("Stack overflow size " + (pointer + 1) + " reached");
@@ -34,4 +40,7 @@ public class Color4Stack extends Color4 implements IStateStack<Color4Stack> {
return this;
}
public boolean isEmpty() {
return pointer == 0;
}
}
@@ -1,5 +1,6 @@
package com.gtnewhorizons.angelica.glsm.stacks;
import com.gtnewhorizon.gtnhlib.client.renderer.stacks.IStateStack;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.glsm.states.ColorMask;
@@ -34,4 +35,7 @@ public class ColorMaskStack extends ColorMask implements IStateStack<ColorMaskSt
return this;
}
public boolean isEmpty() {
return pointer == 0;
}
}
Loaded 100 of 769 files, more files were not shown because too many files have changed in this diff. Show more