Compare commits

...
36 Commits
Author SHA1 Message Date
mist475 21b0de542c base mcpf merge (#45) 2023-12-25 11:44:38 -08:00
Jason Mitchell 7ae4e14a3e Add some more guards around GL capabilities 2023-12-25 11:35:24 -08:00
Jason Mitchell bfd6c25a03 Update README.MD 2023-12-25 09:20:35 -08:00
+4 992644c20f The Mergening (#13)
* ThreadedTessellator -> RenderBlocks instance Tessellator
* Plus a CME workaround until I can figure out why it's happening
* One inject with multiple methods instead of two injects
* Add AF's Tessellator#reset mixin
Fixes screen flashing when chunks are being built
* Thread Saftey
* Make each tesselator use its own ByteBuffer
* Don't make RecyclingList a static variable 🤦
* Add some additions via ITessellatorInstance
* Stop using builtin updateRenderers
* Remove a few unused things in MixinTessellator
* Remove useless casting due to implementing the interface
* Overwrite some more rendering methods to ensure they're not used
* Implement IBlockAccess on WorldSlice
* Currently just proxies to the World... need to get it to use the local cache
* Make WorldSlice use its copied values instead of using the world
* block, meta, and light.  Still need TODO biome
* Finish making WorldSlice thread safe
* Remove last unsafe this.world accesses
* Copy biomeData
* Implement getTileEntity(), and getBiomeGenForCoords()
* Remove unused 1.16+ classes - Biome, Colorizer, and ColorBlender related
* Cache worldHeight instead of asking the provider every time
* Debug Screen updates
* Disable Culling for now (until it works)
* Tessellator Updates
* Use one instance on the main thread, and individual instances on every other thread
* Prevent draw() and buffer.reset() on non singleton instance
* Misc cleanup, maybe better growBuffer?
* Fixing splash screen and GUI issues by excluding SplashProgress from GLStateManager transformer
* Update docs
* Fixing a one line in SodiumWorldRenderer that allows the game setting for the distance at which entities will render. Hope it's not too bad mitch :)
* TileEntites now render
* Less silly transparency
* Removing clamp implementation because I missed the one in mathhelper
* Initial sodium entity smooth lighting
* Fix entity smooth lighting
* Fix lerp uses and use render layers properly (#17)
* Remove some uses of blockstate + patch FluidState
* Fix lerp
* Enable Sodium fluid rendering
* Update FluidRenderer.java
* Rewind buffers when copying
* Fix multidraw
* Force cutout on all non-translucent blocks
* Let vanilla handle render pass state
* Rewrite render layer check to use Forge 1.7 hook
* Fix skylight handling
* Fix flickering
* Clone TEs correctly
* Fixing entityDistMulti (I think)
* Fix TEs rendering on the wrong pass
* Buff max render distance to 32
Pretty useless since the integrated server stalls instantly, but our renderer supports it
* Fix fog
* Fix render distance changes being ignored
* Implement entity culling
* Block face culling
* Re-enable occlusion culling
* Fix x/z coordinate mixup when indexing biome arrays
Partially fixes wrong biome colors, but at chunk edges it's still wrong because
neighboring chunks aren't accessed
* Make a copy of biome data
The old code seemed to work fine but this should be safer
* Make CompatMemoryUtil#memReallocDirect preserve buffer position
LWJGL3's MemoryUtil#memRealloc does this, see its javadoc.
Fixes screen flashing and this error getting printed when indirect buffer grows:
GL_INVALID_OPERATION error generated. Bound draw indirect buffer is not large enough.
* Use biome data of neighboring chunk sections
Fixes wrong colors at chunk edges
* Re-enable fog culling
* Tile entity culling
* Remove some unneeded Sodium code
* Massive code cleanup
* Avoids errors when usin lwjglxdebug
* Bump hodgepodge dep
* Add AngelicaConfig
* Add Mixin to disable MC's builtin checkGLError
* Add configs for iris/sodium
* Iris work
* Move some StateNotifiers to GLStateManager
* Remove some redundant mixins based on sodium/angelica work and rendering state captures
* Add Iris DebugScreenHandler
* rm archaicfix's occlusion renderer and threaded updates
* Implemented Sodium's GUI and a couple of setting fixes (#20)
* Ported Sodium's GUI
* Correct AO
* Fixed Vignette
* Re-enable DirectMemoryAccess
* Adds some code from lwjgl3 in CompatMemoryUtil.java
* Re-add *Unsafe classes
* Remove MixinWorldRenderer
* Add NEID (mixin pr) support
* Only shadow runtime module of antlr4
Reduces jar size by 11 mb
* Update NotFine
* Make LongHashMap actually perform like a hash map
* Options GUI Fixes and some option implementations (#22)
* Correct useNoErrorGLContext option
* Added translucency sorting option
* Implemented Particle Culling
gives real fps boost, however, it's not as big as i thought

* Begin implementing animateOnlyVisibleTextures
* Correct Donation page opening
* Fixed Shift + P
Now it uses NotFine's GUI, but it think that NotFine's GUI should be rewrited for using other config options
* Correct URL's for Linux
* second code cleanup in particle culling
* Fix incorrect TE map population
* Add optional assertMainThread behind `-Dangelica.assertMainThread=true`
* Add back air optimization, but only apply to vanilla air
* Implement more options (#23)
* Combine free regions in GlBufferArena
* Clear global block entity list when initializing renderer
* AF, CompileStubs, and SplashProgress
Remove most of ArchaicFix
* Move a few mixins over to angelica
* Disable if org.lwjgl.util.Debug is set
* Only enable Iris/lwjgl debug callbacks if org.lwjgl.util.Debug is set
* Rewrite Tessellator hacks - now using a ThreadLocal instead of only patching RenderBlocks
* Reenable AF mixins, switch to cached debug var, disable incompatible mixins
* Remove AF deps and a late mixin that was missed
* Add Iris Sodium Compat impl
* Fix Sodium GLProgram to use ResourceLocation instead of Identifier
* Start applying Iris -> Sodium Mixins
* Make NotFine menu open if holding shift
* Fixed Tessellators in production env
* Finish Sodium Fluid Renderer (#24)
* Init and pass Sodium LightPipelines
* Remove registry lookup and refactor WorldUtil
* Hook up lighting pipeline
* Patch fluid velocity
* It's alive! Sodium Fluid Renderer is alive!
* Fix face culling not taking third person camera offset into account
* rewrite ACTEntityRenderer to stop transforming ALL the classes
* use ClassConstantPoolParser in TessellatorTransformer to speed up search for Tessellator references
* use ClassConstantPoolParser in GLStateManagerTransformer to speed up search for class references
* rewrite GLStateManagerTransformer and TessellatorTransformer
* merge GLStateManagerTransfor and TessellatorTransformer into one Transformer
* Fixed smooth lighting rendering
* Iris block_id Mixins & BlockStateIdMap initial impl for 1.7.10
* Fix running with lwjgl debug flag & Cleanup old ShadersMod transformers
* Initialize GLStateManager via Mixins instead of all in the static block
* Clean up chunk load/unload tracking, fix chunks rendering without neighbors sometimes
* Fix occlusion culler not re-running after important uploads

Backport of https://github.com/CaffeineMC/sodium-fabric/pull/755

* Add chunks to queues without going through occlusion culler

Partially reverts the previous chunk tracking commit, because
that logic will reintroduce https://github.com/CaffeineMC/sodium-fabric/issues/605

As long as we only rebuild with neighbors present, we shouldn't
see the visual seams
* Extremely primitive synchronization approach for ISBRH
* Use factory for Spdium menu createElement outputs
This will allow NotFine to use Sodium menu elements and vice versa in a future commit.
* Splash Screen Compat
* Separate remaining NamedState enums
* NotFine but it loads Sodium pages
* Hook up NotFine optimizations
* Hook up some NotFine features
* copy over hud caching code from hodgepodge
* backport glstatemanager mixin
* Track thread that currently owns the GL Context in addition to the main thread.
* First pass over FontRenderer, 1300->1400 FPS on my GPU when showing F3
Done:
 - A batching vertex buffer builder for font output
 - Reduction in drawcalls from 1-3 per character to 1 per font atlas switch
 - Mixin to draw the entire F3 screen in one batch, instead of separate batches per line
TODO:
 - Switch drawing to a VBO
 - Cache string meshes across frames
 - Cache string width calculations used for layouts
 - Multidraw to reduce draw calls even further
* Add JVM flag to bypass GL state caching
* Push/Pop Attrib Hacks -- to be evolved later
* Fix FontRenderer+SplashScreen combo
* HUDCaching tweaks
* Add license
* Jabba Compat, and reset tesselator state even if the chunk render thread blows up
* Initial Xaero's World Map + Minimap Support
* Disable Fastcraft & Optifine if present
* Iris Progress
* Wire up more Iris mixins, informing pipeline stages.  Still not rendering anything visible.
* Don't try to transform the server
* Avoid running biome generator on client in singleplayer
* Call world biome retrieval methods instead of copying array directly (#25)
* Shaders now do something!
* Shadow Pass work
* First shadow pass renders; however it moves all around when moving the camera...
* Second shadow pass not running because it makes everything very very dark instead of just rendering translucents
* Actually use the ShadowRenderer Model View when running the shadow pass...
* Enable Sodium SmoothLightPipeline & Iris useSeparateAo
* Avoid repeatedly copying biome data on each Y level (#27)
* Celestial Rotation fixes
* Water progress
* Uniforms audit
* Lightmap workaround
* PBR compiling, stuck on Normal and Specular textures being added in
* Shaderpack selection "works"; ShaderOptions TODO
* Hud caching angelica (#28)
* Potential hud-caching fix
* Shader Options almost working
** Clicking on everything doesn't yet work, and the visuals are slightly off
* Entity shadows seem to be working
* Move glint fix to Mixin
* Rework mouse handling for ShaderPackConfig
* Stop centering shader options vertically
* Angelica pbr (#31)
* Only use Sodium light pipeline if useSeparateAo is on
Sodium pipeline is still very buggy, so isolate it to Iris-only
for now
* Fix region sorting for translucency
* Open Shaderpack now works on Linux
* RM Shadersmod
* Initial iris scrollbar clicking
* Punt unsupported ISBRHs to the main thread
* Delete the ISBRH lock, shouldn't be needed anymore
* Render GT blocks on main thread
* Require CCC 1.2.0+
* Depend on CCC 1.2
* Fix TESRs not being tracked for blocks rendered on main thread
* Cut down number of runtime dependencies, enable CoreTweaks in dev by default
* Add modern F3 background
* Pull over some hodgepodge mixins


---------

Co-authored-by: makamys <[email protected]>
Co-authored-by: embeddedt <[email protected]>
Co-authored-by: rjnasers <[email protected]>
Co-authored-by: ah-OOG-ah <[email protected]>
Co-authored-by: Ryan Nasers <[email protected]>
Co-authored-by: Rad <[email protected]>
Co-authored-by: Bogdan <[email protected]>
Co-authored-by: Caedis <[email protected]>
Co-authored-by: jss2a98aj <[email protected]>
Co-authored-by: Alexdoru <[email protected]>
Co-authored-by: Raven Szewczyk <[email protected]>
Co-authored-by: mist475 <[email protected]>
Co-authored-by: Ryan Nasers <[email protected]>
2023-12-24 21:49:28 -08:00
Jason Mitchell 96036a67eb Update 000-report-bug.yml
no more reporting about a report
2023-12-24 16:20:32 -08:00
Jason Mitchell 95d3332675 Update 000-report-bug.yml 2023-12-24 16:08:32 -08:00
Jason Mitchell 62ed17757b Update 000-report-bug.yml 2023-12-24 16:08:11 -08:00
Jason Mitchell f69d2bb9f8 .... 2023-12-17 10:01:31 -08:00
Jason Mitchell d4310a6163 .... 2023-12-17 10:00:05 -08:00
Jason Mitchell 0a37dc6a9a Update issue templates 2023-12-17 09:59:25 -08:00
Jason Mitchell a3fefe413e Issue Templates 2023-12-17 09:58:40 -08:00
glowredman fa8be308de Fully port ASM to Mixins (#11)
* Update buildscript

* Enable genericInjection

* Re-enable remapping for certain mixins

* Update buildscript

* Small fixes

- Add generic types
- Add diamond operators
- Fix typo in "NormalMap"
- Remove redundant assignments
- Access static field via class instead of instance
- Use List as type instead of ArrayList
- Add serialVersionUID

* Rename MixinEntityRender -> MixinRender

* Rewrite EntityRenderer ASM as Mixins

* Replace `@Accessor` mixins in favor of ATs

* Move compat to mixins

* Logger cleanup

* Rewrite ItemRenderer ASM as Mixins

* Unify names

* Rewrite RendererLivingEntity ASM as Mixins

* Use Log4J Logger

* Delete ACTRenderManager

* Rewrite ACTRenderSpider as Mixins

* Rewrite AbstractTexture ASM as Mixins

* Port TextureAtlasSprite ASM as Mixins

* Rewrite ThreadDownloadImageData ASM as Mixins

* Rewrite DynamicTexture ASM as Mixins

* Rewrite LayeredTexture ASM as Mixins

* Rewrite TextureManager ASM as Mixins

* Rewrite ITextureObject ASM as mixins

* Rewrite ITextureObject ASM as Mixins

* Clean up compileStubs

* Delete unused stuff

* Finishing touches
2023-08-23 16:39:00 -07:00
Jason Mitchell 2329be3d2d spotless 2023-08-23 16:39:00 -07:00
Jason Mitchell d5eadf8e22 Add MixinEntityRenderer
* Port over (most of) renderHand
2023-08-23 16:39:00 -07:00
Raven Szewczyk f559e032bb Fix recursive and relative #include handling 2023-08-23 16:39:00 -07:00
Raven Szewczyk 940037bc27 Fix NPE in ModelRenderer 2023-08-23 16:39:00 -07:00
Raven Szewczyk c7d721aa5c Update gradle and dependencies 2023-08-23 16:39:00 -07:00
Raven Szewczyk 40a987d81a Mixin Tessellator 2023-08-23 16:39:00 -07:00
Caedis 6840ff5c64 also delete the old transformer 2023-08-23 16:39:00 -07:00
Caedis dd6bbccd32 Spotless 2023-08-23 16:39:00 -07:00
Caedis bdb473a1ee Mixin SimpleTexture 2023-08-23 16:39:00 -07:00
Caedis 26cf4c7e5a Update build.gradle 2023-08-23 16:39:00 -07:00
Caedis 746f6b11eb Mixin TextureClock and TextureCompass 2023-08-23 16:39:00 -07:00
Raven Szewczyk 6134e7ac6b Update buildscript to use unimixins 2023-08-23 16:39:00 -07:00
Jason Mitchell c2c42ffdc9 Mixin-ify RenderGlobal transformer 2023-08-23 16:39:00 -07:00
Jason Mitchell 82f2180888 Progress
* Remove some compilerStubs, access adjustment ASM and replace with Mixin Accessors
* Renderer Mixins
2023-08-23 16:39:00 -07:00
Jason Mitchell 63cc799966 Renderer Mixins & Lighting Level Mixins 2023-08-23 16:39:00 -07:00
Jason Mitchell bf467a3b96 Mixin Shaders Button 2023-08-23 16:39:00 -07:00
992d5e08b9 Start using mixins (#8)
* SMCLog -> ALog

* Start using Mixins!
* Shader startup ACTMinecraft -> MixinMinecraft

* spotlessApply (#9)

Co-authored-by: GitHub GTNH Actions <>

* Update buildscript, add mixingasm and nei

* Remove unneeded transformer exclusions

* Fix broken stack frames

* Fix mcp namer for rfg

* Inject the asm transformer manually in the correct order to avoid mixin-induced issues

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Raven Szewczyk <[email protected]>
2023-02-23 18:24:05 +00:00
Raven Szewczyk 102938304c Working obfuscated run, switch to FMLLoadingPlugin properly 2023-02-20 20:07:20 +00:00
Raven Szewczyk 9af8478236 Update gradle properties for RFG 2023-02-20 19:54:24 +00:00
Raven Szewczyk 3cc367bf0d Update buildscript 2023-02-20 19:46:58 +00:00
Raven Szewczyk 416b967e8a [ci skip] upgraded build system 2023-01-31 09:50:48 +00:00
Jason Mitchell 5f4739cc78 [ci skip] Add git-blame-ignore-revs for spotlessApply 2023-01-29 12:49:10 -08:00
Jason Mitchell f64f7f366a [ci skip] spotlessApply with the new settings 2023-01-29 12:49:10 -08:00
Jason Mitchell c47661b619 [ci skip] Update buildscript to RetroFuturaGradle 2023-01-29 12:48:47 -08:00
1187 changed files with 88080 additions and 12672 deletions

No files matched your search

+2
View File
@@ -0,0 +1,2 @@
# Ignore spotlessApply reformat
f64f7f366af8fc32dddfe9c9acd1259eb7d65787
+36 -27
View File
@@ -1,35 +1,44 @@
* text eol=lf
*.jar binary
*.[jJ][aA][rR] binary
*.png binary
*.jpg binary
*.jpeg binary
*.gif binary
*.tif binary
*.tiff binary
*.ico binary
*.svg text
*.eps binary
*.[pP][nN][gG] binary
*.[jJ][pP][gG] binary
*.[jJ][pP][eE][gG] binary
*.[gG][iI][fF] binary
*.[tT][iI][fF] binary
*.[tT][iI][fF][fF] binary
*.[iI][cC][oO] binary
*.[sS][vV][gG] text
*.[eE][pP][sS] binary
*.[xX][cC][fF] binary
*.kar binary
*.m4a binary
*.mid binary
*.midi binary
*.mp3 binary
*.ogg binary
*.ra binary
*.[kK][aA][rR] binary
*.[mM]4[aA] binary
*.[mM][iI][dD] binary
*.[mM][iI][dD][iI] binary
*.[mM][pP]3 binary
*.[oO][gG][gG] binary
*.[rR][aA] binary
*.7z binary
*.gz binary
*.tar binary
*.tgz binary
*.zip binary
*.7[zZ] binary
*.[gG][zZ] binary
*.[tT][aA][rR] binary
*.[tT][gG][zZ] binary
*.[zZ][iI][pP] binary
*.patch -text
*.[tT][cC][nN] binary
*.[sS][oO] binary
*.[dD][lL][lL] binary
*.[dD][yY][lL][iI][bB] binary
*.[pP][sS][dD] binary
*.[tT][tT][fF] binary
*.[oO][tT][fF] binary
*.bat text eol=crlf
*.cmd text eol=crlf
*.ps1 text eol=crlf
*.[pP][aA][tT][cC][hH] -text
*autogenerated binary
*.[bB][aA][tT] text eol=crlf
*.[cC][mM][dD] text eol=crlf
*.[pP][sS]1 text eol=crlf
*[aA][uU][tT][oO][gG][eE][nN][eE][rR][aA][tT][eE][dD]* binary
+63
View File
@@ -0,0 +1,63 @@
name: Report Bug
description: "Report a bug."
body:
- type: markdown
attributes:
value: "A bug/crash report with sufficient information and logs to reproduce and track down."
- 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: Fake#1234"
- type: input
id: version
attributes:
label: Mod Version
description: "What version of the Mod are you using? (Note: None have been officially released yet)"
placeholder: "Example: 1.0.0-alpha1"
validations:
required: true
- type: dropdown
id: java
attributes:
label: Java Version
description: What Java version are you using? It's worth mentioning that if you play on Java9+ you should try update to latest minor release (e.g. prefer Java 17.0.6 over 17.0.2) of that version.
options:
- Java 8
- Java 9
- Java 11
- Java 17
- Java 19
- Java 20
- Java 21
- Other (Please Specify)
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: textarea
id: modlist
attributes:
label: Mod List
description: "List of mods, ideally a minimal reproducible set (can be retrieved from latest.log)"
placeholder: "List of mods go here"
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
+1
View File
@@ -0,0 +1 @@
blank_issues_enabled: false
+1 -1
View File
@@ -26,7 +26,7 @@ whitelist.json
*.iml
*.ipr
*.iws
src/main/resources/mixins.*.json
src/main/resources/mixins.*([!.]).json
*.bat
*.DS_Store
!gradlew.bat
+44 -16
View File
@@ -1,19 +1,47 @@
# Angelica
the little angle that supports shaders while saving your fps from a certain death - boubou
* 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
Not yet in an usable state
**Alpha Quality - Here there be Dragons**
Original build instructions obtained via minecraftforums archeology:
```
Developing environment
- Extract forge src to forge folder. Run "gradlew setupDecompWorkspace setupDevWorkspace" until it succeeded, then "gradlew build", then "gradlew eclipse".
- Delete everything in src\main folder inside forge folder.
- Extract smc-2.3.18-mc1.7.10-src.7z to src\main folder.
- Read patch file shadersmod-mcf.patch
- Find %userprofile%\.gradle\caches\minecraft\net\minecraftforge\forge\*\forgeSrc-*-sources.jar and extract it somewhere.
-- Select files that need to be patched and copy them to src\main with correct folder structure.
- Apply patch shadersmod-mcf.patch
- In eclipse, add java_dev folder as another source folder.
- In eclipse, exclude InitNames in src folder from build path. Use InitNames in java_dev folder instead.
- Find %userprofile%\.gradle\caches\modules-2\files-2.1\net.minecraftforge\forge\*\*\forge-*-userdev.jar and extract conf\*.csv and conf\*.srg in it to forge\conf and rename packaged.srg to joined.srg.
```
# 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
* RPLE - Future compat planned
# 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.2 and below - Use 2.4.3 or above
* CodeChickenCore/Lib <1.2.0 - Threading issues, use 1.2.0+
# Credits
* ShadersMod
* Original ShadersMods: karyonix, sonic ether, id_miner, daxnitro
* eigenraven, Caedis, glowredman, and mitchej123 for the conversion of ASM to Mixin
* eigenraven and vlaetansky for getting the original ShadersMod compiling again
* ArchaicFix
* Includes graphic enhancements from [ArchaicFix](https://github.com/embeddedt/ArchaicFix/tree/4afb943751883b27a1f0aa7c5ba71698bc897e95) by embeddedt under the [LGPL](https://github.com/embeddedt/ArchaicFix/blob/main/LICENSE.md)
* NotFine
* Includes modified version of [NotFine](https://github.com/jss2a98aj/NotFine/tree/a2652e24b5654f437fb7138f6d1f5e947a7d7125) by jss2a98aj under the LGPL
* Iris Shaders
* The [Iris](https://github.com/IrisShaders/Iris) Team: coderbot, IMS212, Justsnoopy30, FoundationGames
* Asek3 for the Iris Forge port [Oculus](https://github.com/Asek3/Oculus/tree/839ce8eca8cf0c4f6b7a1322b906e5c99125ca69)
* Backported code under the LGPL
* 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)
* Neodymium
* Makamys for [Neodymium](https://github.com/makamys/Neodymium) - Various Tessellator -> Quad functionality taken under the LGPL 3
* MCPatcherForge
* Original [MCPatcher](https://bitbucket.org/prupe/mcpatcher/src/master/): Paul Rupe
* [Forge version](https://bitbucket.org/prupe/mcpatcher/src/master/): Mist475 under LGPL 3.0 with default ctm textures for glass and bookshelves by DarkBum under CC-BY-SA
* 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!
* IMS, jss2a98aj, || dbp ||, roadhog360 for advice and moral support
+5 -19
View File
@@ -1,21 +1,7 @@
configurations {
compileStubs
}
sourceSets {
compileStubsStubs
compileStubs {
compileClasspath += configurations.compileStubs
}
}
jar {
manifest {
attributes([
"Manifest-Version" : 1.0,
"TweakClass" : "com.gtnewhorizons.angelica.loading.ATweaker",
"TweakOrder" : 1100,
])
allprojects {
gradle.projectsEvaluated {
tasks.withType(JavaCompile) {
options.compilerArgs << "-Xmaxerrs" << "2000"
}
}
}
+1121 -475
View File
File diff suppressed because it is too large. Load diff
+74 -2
View File
@@ -1,5 +1,77 @@
/*
* Add your dependencies here. Supported configurations:
* - api("group:name:version:classifier"): if you use the types from this dependency in the public API of this mod
* Available at runtime and compiletime for mods depending on this mod
* - implementation("g:n:v:c"): if you need this for internal implementation details of the mod, but none of it is visible via the public API
* Available at runtime but not compiletime for mods depending on this mod
* - compileOnly("g:n:v:c"): if the mod you're building doesn't need this dependency during runtime at all, e.g. for optional mods
* Not available at all for mods depending on this mod, only visible at compiletime for this mod
* - compileOnlyApi("g:n:v:c"): like compileOnly, but also visible at compiletime for mods depending on this mod
* Available at compiletime but not runtime for mods depending on this mod
* - runtimeOnlyNonPublishable("g:n:v:c"): if you want to include a mod in this mod's runClient/runServer runs, but not publish it as a dependency
* Not available at all for mods depending on this mod, only visible at runtime for this mod
* - devOnlyNonPublishable("g:n:v:c"): a combination of runtimeOnlyNonPublishable and compileOnly for dependencies present at both compiletime and runtime,
* but not published as Maven dependencies - useful for RFG-deobfuscated dependencies or local testing
* - runtimeOnly("g:n:v:c"): if you don't need this at compile time, but want it to be present at runtime
* Available at runtime for mods depending on this mod
* - annotationProcessor("g:n:v:c"): mostly for java compiler plugins, if you know you need this, use it, otherwise don't worry
* - testCONFIG("g:n:v:c") - replace CONFIG by one of the above (except api), same as above but for the test sources instead of main
*
* - shadowImplementation("g:n:v:c"): effectively the same as API, but the dependency is included in your jar under a renamed package name
* Requires you to enable usesShadowedDependencies in gradle.properties
*
* - compile("g:n:v:c"): deprecated, replace with "api" (works like the old "compile") or "implementation" (can be more efficient)
*
* You can exclude transitive dependencies (dependencies of the chosen dependency) by appending { transitive = false } if needed,
* but use this sparingly as it can break using your mod as another mod's dependency if you're not careful.
*
* To depend on obfuscated jars you can use `devOnlyNonPublishable(rfg.deobf("dep:spec:1.2.3"))` to fetch an obfuscated jar from maven,
* or `devOnlyNonPublishable(rfg.deobf(project.files("libs/my-mod-jar.jar")))` to use a file.
*
* Gradle names for some of the configuration can be misleading, compileOnlyApi and runtimeOnly both get published as dependencies in Maven, but compileOnly does not.
* The buildscript adds runtimeOnlyNonPublishable to also have a runtime dependency that's not published.
*
* For more details, see https://docs.gradle.org/8.0.1/userguide/java_library_plugin.html#sec:java_library_configurations_graph
*/
dependencies {
compileOnly(sourceSets.compileStubs.output)
compileStubs(sourceSets.compileStubsStubs.output)
compileOnly("com.github.GTNewHorizons:Hodgepodge:2.4.3")
compileOnly("org.projectlombok:lombok:1.18.22") {transitive = false }
annotationProcessor("org.projectlombok:lombok:1.18.22")
// 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
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
exclude module: "antlr4" // we only want to shadow the runtime module
}
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')
// 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 }
compileOnly(rfg.deobf('curse.maven:witchery-69673:2234410'))
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("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"))
runtimeOnly(deobf("https://github.com/makamys/CoreTweaks/releases/download/0.3.3.2/CoreTweaks-1.7.10-0.3.3.2+nomixin.jar"))
}
Binary file not shown.
+77 -13
View File
@@ -28,16 +28,31 @@ remoteMappings = https://raw.githubusercontent.com/MinecraftForge/FML/1.7.10/con
# Do you need to test how your custom blocks interacts with a player that is not the owner? -> leave name empty
developmentEnvironmentUserName = Developer
# Enables using modern java syntax (up to version 17) via Jabel, while still targetting 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
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
replaceGradleTokenInFile = Tags.java
gradleTokenModId = GRADLETOKEN_MODID
gradleTokenModName = GRADLETOKEN_MODNAME
gradleTokenVersion = GRADLETOKEN_VERSION
gradleTokenGroupName = GRADLETOKEN_GROUPNAME
generateGradleTokenClass = com.gtnewhorizons.angelica.Tags
gradleTokenModId =
gradleTokenModName =
gradleTokenVersion = VERSION
gradleTokenGroupName =
# [DEPRECATED]
# Multiple source files can be defined here by providing a comma-seperated 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
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.
@@ -45,21 +60,22 @@ gradleTokenGroupName = GRADLETOKEN_GROUPNAME
apiPackage =
# Specify the configuration file for Forge's access transformers here. It must be placed into /src/main/resources/META-INF/
# Example value: mymodid_at.cfg
accessTransformersFile =
# There can be multiple files in a comma-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 = false
usesMixins = true
# Adds some debug arguments like verbose output and 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 =
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
coreModClass =
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
@@ -69,11 +85,50 @@ 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.
usesShadowedDependencies = false
usesShadowedDependencies = true
# If disabled, won't remove unused classes from shaded 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
includeWellKnownRepositories = true
# 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 =
# The project's relations on Modrinth. You can use this to refer to other projects on Modrinth.
# Syntax: scope1-type1:name1;scope2-type2:name2;...
# Where scope can be one of [required, optional, incompatible, embedded],
# type can be one of [project, version],
# 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 =
# 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 =
# 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 =
# Optional parameter to customize the produced artifacts. Use this to preserver artifact naming when migrating older
# projects. New projects should not use this parameter.
#customArchiveBaseName =
# customArchiveBaseName =
# Optional parameter to prevent the source code from being published
# noPublishedSources =
@@ -81,4 +136,13 @@ usesShadowedDependencies = false
# 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.
# disableSpotless = true
# 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"
# (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.
# 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
Binary file not shown.
+2 -1
View File
@@ -1,5 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.9.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2.1-bin.zip
networkTimeout=10000
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Vendored Regular → Executable
+173 -116
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env sh
#!/bin/sh
#
# Copyright 2015 the original author or authors.
# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -17,78 +17,110 @@
#
##############################################################################
##
## Gradle start up script for UN*X
##
#
# Gradle start up script for POSIX generated by Gradle.
#
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# 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
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# 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"'
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
MAX_FD=maximum
warn () {
echo "$*"
}
} >&2
die () {
echo
echo "$*"
echo
exit 1
}
} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
JAVACMD=$JAVA_HOME/jre/sh/java
else
JAVACMD="$JAVA_HOME/bin/java"
JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
@@ -97,7 +129,7 @@ Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
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.
Please set the JAVA_HOME variable in your environment to match the
@@ -105,84 +137,109 @@ location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
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
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
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.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@"
Vendored
+15 -23
View File
@@ -14,7 +14,7 @@
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@@ -25,10 +25,14 @@
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@@ -37,7 +41,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
if %ERRORLEVEL% equ 0 goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
@@ -51,7 +55,7 @@ goto fail
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
@@ -61,38 +65,26 @@ echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
if %ERRORLEVEL% equ 0 goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal
+9 -1
View File
@@ -1,5 +1,13 @@
// Add any additional repositories for your dependencies here
repositories {
maven {
name = 'covers1624 maven'
url = 'https://nexus.covers1624.net/repository/maven-hosted/'
metadataSources {
mavenPom()
artifact()
}
}
mavenLocal()
}
+21 -3
View File
@@ -1,10 +1,28 @@
pluginManagement {
repositories {
maven {
// RetroFuturaGradle
name "GTNH Maven"
url "http://jenkins.usrv.eu:8081/nexus/content/groups/public/"
allowInsecureProtocol = true
mavenContent {
includeGroup("com.gtnewhorizons.retrofuturagradle")
}
}
gradlePluginPortal()
mavenCentral()
mavenLocal()
}
}
plugins {
id 'com.diffplug.blowdryerSetup' version '1.6.0'
id 'org.gradle.toolchains.foojay-resolver-convention' version '0.4.0' // Provides java toolchains
}
apply plugin: 'com.diffplug.blowdryerSetup'
blowdryerSetup {
github('GTNewHorizons/ExampleMod1.7.10', 'tag', '0.1.5')
repoSubfolder 'gtnhShared'
github('GTNewHorizons/ExampleMod1.7.10', 'tag', '0.2.0')
//devLocal '.' // Use this when testing config updates locally
}
@@ -1,7 +0,0 @@
package net.minecraft.client.model;
import java.util.List;
public class ModelBase {
public List boxList;
}
@@ -1,10 +0,0 @@
package net.minecraft.client.model;
import java.util.List;
public class ModelRenderer {
public List childModels;
public void resetDisplayList() {}
}
@@ -1,14 +0,0 @@
package net.minecraft.client.renderer;
public class EntityRenderer {
public static int anaglyphField;
public static boolean anaglyphEnable;
/**
* Render player hand
*/
public void renderHand(float p_78476_1_, int p_78476_2_) {}
public void renderWorld(float f, long l) {}
}
@@ -1,8 +0,0 @@
package net.minecraft.client.renderer;
public class RenderGlobal {
public WorldRenderer[] worldRenderers;
public void loadRenderers() {}
}
@@ -1,180 +0,0 @@
package net.minecraft.client.renderer;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.ShortBuffer;
import net.minecraft.client.shader.TesselatorVertexState;
public class Tessellator {
private static int nativeBufferSize;
private static int trivertsInBuffer;
public static boolean renderingWorldRenderer;
public boolean defaultTexture;
private int rawBufferSize;
public int textureID;
/** The byte buffer used for GL allocation. */
public ByteBuffer byteBuffer;
/** The same memory as byteBuffer, but referenced as an integer buffer. */
public IntBuffer intBuffer;
/** The same memory as byteBuffer, but referenced as an float buffer. */
public FloatBuffer floatBuffer;
/** The same memory as byteBuffer, but referenced as an short buffer. */
public ShortBuffer shortBuffer;
/** Raw integer array. */
public int[] rawBuffer;
/** The number of vertices to be drawn in the next draw call. Reset to 0 between draw calls. */
public int vertexCount;
/** The first coordinate to be used for the texture. */
public double textureU;
/** The second coordinate to be used for the texture. */
public double textureV;
public int brightness;
/** The color (RGBA) value to be used for the following draw call. */
public int color;
/** Whether the current draw object for this tessellator has color values. */
public boolean hasColor;
/** Whether the current draw object for this tessellator has texture coordinates. */
public boolean hasTexture;
public boolean hasBrightness;
/** Whether the current draw object for this tessellator has normal values. */
public boolean hasNormals;
/** The index into the raw buffer to be used for the next data. */
public int rawBufferIndex;
/**
* The number of vertices manually added to the given draw call. This differs from vertexCount because it adds extra
* vertices when converting quads to triangles.
*/
public int addedVertices;
/** Disables all color information for the following draw call. */
public boolean isColorDisabled;
/** The draw mode currently being used by the tessellator. */
public int drawMode;
/** An offset to be applied along the x-axis for all vertices in this draw call. */
public double xOffset;
/** An offset to be applied along the y-axis for all vertices in this draw call. */
public double yOffset;
/** An offset to be applied along the z-axis for all vertices in this draw call. */
public double zOffset;
/** The normal to be applied to the face being drawn. */
public int normal;
/** The static instance of the Tessellator. */
public static final Tessellator instance = new Tessellator();
/** Whether this tessellator is currently in draw mode. */
public boolean isDrawing;
/** The size of the buffers used (in integers). */
public int bufferSize;
public float midTextureU;
public float midTextureV;
public float normalX;
public float normalY;
public float normalZ;
public float[] vertexPos = new float[16];
private Tessellator(int p_i1250_1_) {}
public Tessellator() {}
/**
* Draws the data set up in this tessellator and resets the state to prepare for new drawing.
*/
public int draw() {
return 0;
}
public TesselatorVertexState getVertexState(float p_147564_1_, float p_147564_2_, float p_147564_3_) {
return null;
}
public void setVertexState(TesselatorVertexState p_147565_1_) {}
/**
* Clears the tessellator state in preparation for new drawing.
*/
public void reset() {}
/**
* Sets draw mode in the tessellator to draw quads.
*/
public void startDrawingQuads() {}
/**
* Resets tessellator state and prepares for drawing (with the specified draw mode).
*/
public void startDrawing(int p_78371_1_) {}
/**
* Sets the texture coordinates.
*/
public void setTextureUV(double p_78385_1_, double p_78385_3_) {}
public void setBrightness(int p_78380_1_) {}
/**
* Sets the RGB values as specified, converting from floats between 0 and 1 to integers from 0-255.
*/
public void setColorOpaque_F(float p_78386_1_, float p_78386_2_, float p_78386_3_) {}
/**
* Sets the RGBA values for the color, converting from floats between 0 and 1 to integers from 0-255.
*/
public void setColorRGBA_F(float p_78369_1_, float p_78369_2_, float p_78369_3_, float p_78369_4_) {}
/**
* Sets the RGB values as specified, and sets alpha to opaque.
*/
public void setColorOpaque(int p_78376_1_, int p_78376_2_, int p_78376_3_) {}
/**
* Sets the RGBA values for the color. Also clamps them to 0-255.
*/
public void setColorRGBA(int p_78370_1_, int p_78370_2_, int p_78370_3_, int p_78370_4_) {}
public void func_154352_a(byte p_154352_1_, byte p_154352_2_, byte p_154352_3_) {}
/**
* Adds a vertex specifying both x,y,z and the texture u,v for it.
*/
public void addVertexWithUV(
double p_78374_1_, double p_78374_3_, double p_78374_5_, double p_78374_7_, double p_78374_9_) {}
/**
* Adds a vertex with the specified x,y,z to the current draw call. It will trigger a draw() if the buffer gets
* full.
*/
public void addVertex(double p_78377_1_, double p_78377_3_, double p_78377_5_) {}
/**
* Sets the color to the given opaque value (stored as byte values packed in an integer).
*/
public void setColorOpaque_I(int p_78378_1_) {}
/**
* Sets the color to the given color (packed as bytes in integer) and alpha values.
*/
public void setColorRGBA_I(int p_78384_1_, int p_78384_2_) {}
/**
* Disables colors for the current draw call.
*/
public void disableColor() {}
/**
* Sets the normal for the current draw call.
*/
public void setNormal(float p_78375_1_, float p_78375_2_, float p_78375_3_) {}
/**
* Sets the translation for all vertices in the current draw call.
*/
public void setTranslation(double p_78373_1_, double p_78373_3_, double p_78373_5_) {}
/**
* Offsets the translation for all vertices in the current draw call.
*/
public void addTranslation(float p_78372_1_, float p_78372_2_, float p_78372_3_) {}
}
@@ -1,13 +0,0 @@
package net.minecraft.client.renderer;
import net.minecraft.client.renderer.culling.ICamera;
public class WorldRenderer {
public boolean isInFrustum;
public boolean skipAllRenderPasses() {
return false;
}
public void updateInFrustum(ICamera frustrum) {}
}
@@ -1,6 +0,0 @@
package net.minecraft.client.renderer.culling;
public class Frustrum implements ICamera {
public void setPosition(double x, double y, double z) {}
}
@@ -1,3 +0,0 @@
package net.minecraft.client.renderer.culling;
public interface ICamera {}
@@ -1,3 +0,0 @@
package net.minecraft.client.renderer.entity;
public abstract class Render {}
@@ -1,10 +0,0 @@
package net.minecraft.client.renderer.entity;
import net.minecraft.client.model.ModelBase;
public abstract class RendererLivingEntity extends Render {
public ModelBase mainModel;
/** The model to be used during the render passes. */
public ModelBase renderPassModel;
}
@@ -1,17 +0,0 @@
package net.minecraft.client.renderer.texture;
import com.gtnewhorizons.angelica.client.MultiTexID;
public abstract class AbstractTexture implements ITextureObject {
public int glTextureId = -1;
public MultiTexID multiTex;
public int getGlTextureId() {
return 0;
}
public MultiTexID getMultiTexID() {
return null;
}
}
@@ -1,13 +0,0 @@
package net.minecraft.client.renderer.texture;
public class DynamicTexture extends AbstractTexture {
public DynamicTexture(int i, int i1) {
super();
}
public int[] getTextureData() {
return null;
}
public void updateDynamicTexture() {}
}
@@ -1,10 +0,0 @@
package net.minecraft.client.renderer.texture;
import com.gtnewhorizons.angelica.client.MultiTexID;
public interface ITextureObject {
MultiTexID getMultiTexID();
int getGlTextureId();
}
@@ -1,8 +0,0 @@
package net.minecraft.client.renderer.texture;
public class TextureAtlasSprite {
public boolean useAnisotropicFiltering;
public void updateAnimation() {}
}
@@ -1,18 +0,0 @@
package net.minecraft.client.renderer.texture;
import net.minecraft.util.ResourceLocation;
public class TextureMap extends AbstractTexture {
public static ResourceLocation locationBlocksTexture;
public int atlasWidth;
public int atlasHeight;
public int getTextureType() {
return 0;
}
public ResourceLocation completeResourceLocation(ResourceLocation resourceLocation, int i) {
return null;
}
}
-1
View File
@@ -1 +0,0 @@
Stubs for the compile stubs
@@ -1,3 +0,0 @@
package com.gtnewhorizons.angelica.client;
public class MultiTexID {}
@@ -1,3 +0,0 @@
package net.minecraft.client.shader;
public class TesselatorVertexState {}
@@ -1,3 +0,0 @@
package net.minecraft.util;
public class ResourceLocation {}
@@ -0,0 +1,22 @@
package com.gtnewhorizons.angelica;
import com.gtnewhorizon.gtnhmixins.ILateMixinLoader;
import com.gtnewhorizon.gtnhmixins.LateMixin;
import com.gtnewhorizons.angelica.mixins.Mixins;
import java.util.List;
import java.util.Set;
@LateMixin
public class AngelicaLateMixins implements ILateMixinLoader {
@Override
public String getMixinConfig() {
return "mixins.angelica.late.json";
}
@Override
public List<String> getMixins(Set<String> loadedMods) {
return Mixins.getLateMixins(loadedMods);
}
}
@@ -0,0 +1,47 @@
package com.gtnewhorizons.angelica;
import com.gtnewhorizons.angelica.proxy.CommonProxy;
import com.gtnewhorizons.angelica.utils.AnimationMode;
import com.gtnewhorizons.angelica.utils.ManagedEnum;
import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.Mod;
import cpw.mods.fml.common.SidedProxy;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
@Mod(
modid = "angelica",
name = "Angelica",
version = Tags.VERSION,
dependencies = " before:lwjgl3ify@[1.5.3,);" + " after:hodgepodge@[2.4.3,);" + " after:CodeChickenCore@[1.2.0,);",
acceptedMinecraftVersions = "[1.7.10]",
acceptableRemoteVersions = "*")
public class AngelicaMod {
@SidedProxy(clientSide = "com.gtnewhorizons.angelica.proxy.ClientProxy", serverSide = "com.gtnewhorizons.angelica.proxy.CommonProxy")
public static CommonProxy proxy;
/** Mixin Version */
public static boolean isNEIDLoaded;
/** ASM Version */
public static boolean isOldNEIDLoaded;
public static final boolean lwjglDebug = Boolean.parseBoolean(System.getProperty("org.lwjgl.util.Debug", "false"));
public static final ManagedEnum<AnimationMode> animationsMode = new ManagedEnum<>(AnimationMode.VISIBLE_ONLY);
@Mod.EventHandler
public void preInit(FMLPreInitializationEvent event) {
isNEIDLoaded = Loader.isModLoaded("neid");
isOldNEIDLoaded = Loader.isModLoaded("notenoughIDs");
proxy.preInit(event);
}
@Mod.EventHandler
public void init(FMLInitializationEvent event) {
proxy.init(event);
}
@Mod.EventHandler
public void postInit(FMLPostInitializationEvent event) {
proxy.postInit(event);
}
}
@@ -0,0 +1,10 @@
- [x] Frustum (Seems related to Frustrum)
- [X] NativeImage
- [ ] PoseStack
- [ ] RenderType
- [ ] MultiBufferSource.BufferSource
- [ ] VertexBuffer
- [ ] VertexConsumer
- [ ] VertextFormat
- [ ] TextureAtlas (Seems related to TextureManager) - PBR related
- [ ] GUI
@@ -1,12 +0,0 @@
package com.gtnewhorizons.angelica;
// Use this class for Strings only. Do not import any classes here. It will lead to issues with Mixins if in use!
public class Tags {
// GRADLETOKEN_* will be replaced by your configuration values at build time
public static final String MODID = "GRADLETOKEN_MODID";
public static final String MODNAME = "GRADLETOKEN_MODNAME";
public static final String VERSION = "GRADLETOKEN_VERSION";
public static final String GROUPNAME = "GRADLETOKEN_GROUPNAME";
}
@@ -1,16 +0,0 @@
package com.gtnewhorizons.angelica.client;
import net.minecraft.client.renderer.texture.AbstractTexture;
import net.minecraft.client.resources.IResourceManager;
public class DefaultTexture extends AbstractTexture {
public DefaultTexture() {
loadTexture(null);
}
public void loadTexture(IResourceManager resourcemanager) {
int[] aint = ShadersTex.createAIntImage(1, 0xFFFFFFFF);
ShadersTex.setupTexture(this.getMultiTexID(), aint, 1, 1, false, false);
}
}
@@ -1,354 +0,0 @@
package com.gtnewhorizons.angelica.client;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.List;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.settings.GameSettings;
import org.lwjgl.Sys;
public class GuiShaders extends GuiScreen {
/** This GUI's parent GUI. */
protected GuiScreen parentGui;
private int updateTimer = -1;
public boolean needReinit;
/*
private class GuiListShaderpacks {
int posX,posY,sizeX,sizeY;
int viewPosY;
int itemHeight = 20;
int selection;
ArrayList<String> listShaderpacks;
public void draw() {
Tessellator tess = Tessellator.instance;
int listSize = listShaderpacks.size();
int i,j;
for (i=viewPosY/itemHeight, j=Math.min((viewPosY+sizeY)/itemHeight,listSize); i<j; ++i)
{
int itemY = posY-viewPosY+itemHeight*i;
boolean selected = i==selection;
tess.startDrawingQuads();
tess.setColorRGBA(0,0,selected?128:0,128);
tess.addVertex(posX,itemY,0);
tess.addVertex(posX,itemY+itemHeight,0);
tess.addVertex(posX+sizeX,itemY+itemHeight,0);
tess.addVertex(posX+sizeX,itemY,0);
tess.draw();
field_146289_q.drawString(listShaderpacks.get(i), posX, itemY, 0xFFFFFFFF, true);
}
}
}
private GuiListShaderpacks guiListShaderpacks;
*/
private GuiSlotShaders shaderList;
/** This GUI's 'Done' button. */
// private GuiSmallButton doneButton;
public GuiShaders(GuiScreen par1GuiScreen, GameSettings par2GameSettings) {
this.parentGui = par1GuiScreen;
}
private static String toStringOnOff(boolean value) {
return value ? "On" : "Off";
}
@Override
/**
* Adds the buttons (and other controls) to the screen in question.
*/
public void initGui() {
if (Shaders.shadersConfig == null) Shaders.loadConfig();
List buttonList = this.buttonList;
int width = this.width;
int height = this.height;
buttonList.add(new GuiButton(
17, width * 3 / 4 - 60, 30, 160, 18, "NormapMap: " + toStringOnOff(Shaders.configNormalMap)));
buttonList.add(new GuiButton(
18, width * 3 / 4 - 60, 50, 160, 18, "SpecularMap: " + toStringOnOff(Shaders.configSpecularMap)));
buttonList.add(new GuiButton(
15,
width * 3 / 4 - 60,
70,
160,
18,
"RenderResMul: " + String.format("%.04f", Shaders.configRenderResMul)));
buttonList.add(new GuiButton(
16,
width * 3 / 4 - 60,
90,
160,
18,
"ShadowResMul: " + String.format("%.04f", Shaders.configShadowResMul)));
buttonList.add(new GuiButton(
10,
width * 3 / 4 - 60,
110,
160,
18,
"HandDepth: " + String.format("%.04f", Shaders.configHandDepthMul)));
buttonList.add(new GuiButton(
9, width * 3 / 4 - 60, 130, 160, 18, "CloudShadow: " + toStringOnOff(Shaders.configCloudShadow)));
// buttonList.add(new GuiButton(14, width *3 /4 -60, 150, 160, 18, "ShadowClipFrustrum: "
// +toStringOnOff(Shaders.configShadowClipFrustrum)));
buttonList.add(new GuiButton(
4,
width * 3 / 4 - 60,
170,
160,
18,
"tweakBlockDamage: " + toStringOnOff(Shaders.configTweakBlockDamage)));
buttonList.add(new GuiButton(
19, width * 3 / 4 - 60, 190, 160, 18, "OldLighting: " + toStringOnOff(Shaders.configOldLighting)));
// buttonList.add(new GuiButton(11, width *3 /4 -60, 210, 160, 18, "Tex Min: "
// +Shaders.texMinFilDesc[Shaders.configTexMinFilB]));
// buttonList.add(new GuiButton(12, width *3 /4 -60, 230, 160, 18, "Tex_n Mag: "
// +Shaders.texMagFilDesc[Shaders.configTexMagFilN]));
// buttonList.add(new GuiButton(13, width *3 /4 -60, 250, 160, 18, "Tex_s Mag: "
// +Shaders.texMagFilDesc[Shaders.configTexMagFilS]));
buttonList.add(new GuiButton(6, width * 3 / 4 - 60, height - 25, 160, 20, "Done"));
buttonList.add(new GuiButton(5, width / 4 - 80, height - 25, 160, 20, "Open shaderpacks folder"));
this.shaderList = new GuiSlotShaders(this);
this.shaderList.registerScrollButtons(7, 8); // registerScrollButtons(7, 8);
this.needReinit = false;
}
@Override
/** actionPerformed
* Fired when a control is clicked. This is the equivalent of ActionListener.actionPerformed(ActionEvent e).
*/
protected void actionPerformed(GuiButton par1GuiButton) {
if (par1GuiButton.enabled) // enabled
{
switch (par1GuiButton.id) // id
{
case 4: /* New block breaking */
Shaders.configTweakBlockDamage = !Shaders.configTweakBlockDamage;
// displayString
par1GuiButton.displayString = "tweakBlockDamage: " + toStringOnOff(Shaders.configTweakBlockDamage);
break;
case 9: /* Cloud shadow */
Shaders.configCloudShadow = !Shaders.configCloudShadow;
par1GuiButton.displayString = "CloudShadow: " + toStringOnOff(Shaders.configCloudShadow);
break;
case 10: /* Hand Depth */ {
float val = Shaders.configHandDepthMul;
float[] choices = {0.0625f, 0.125f, 0.25f, 0.5f, 1.0f};
int i;
if (!isShiftKeyDown()) { // isShiftKeyDown
for (i = 0; i < choices.length && choices[i] <= val; ++i) {}
if (i == choices.length) i = 0;
} else {
for (i = choices.length - 1; i >= 0 && val <= choices[i]; --i) {}
if (i < 0) i = choices.length - 1;
}
Shaders.configHandDepthMul = choices[i];
par1GuiButton.displayString = "HandDepth: " + String.format("%.4f", Shaders.configHandDepthMul);
break;
}
case 15: /* Render Resolution Multiplier */ {
float val = Shaders.configRenderResMul;
float[] choices = {0.25f, 0.3333333333f, 0.5f, 0.7071067812f, 1.0f, 1.414213562f, 2.0f};
int i;
if (!isShiftKeyDown()) {
for (i = 0; i < choices.length && choices[i] <= val; ++i) {}
if (i == choices.length) i = 0;
} else {
for (i = choices.length - 1; i >= 0 && val <= choices[i]; --i) {}
if (i < 0) i = choices.length - 1;
}
Shaders.configRenderResMul = choices[i];
par1GuiButton.displayString = "RenderResMul: " + String.format("%.4f", Shaders.configRenderResMul);
Shaders.scheduleResize();
break;
}
case 16: /* Shadow Resolution Multiplier */ {
float val = Shaders.configShadowResMul;
float[] choices = {0.25f, 0.3333333333f, 0.5f, 0.7071067812f, 1.0f, 1.414213562f, 2.0f, 3.0f, 4.0f};
int i;
if (!isShiftKeyDown()) {
for (i = 0; i < choices.length && choices[i] <= val; ++i) {}
if (i == choices.length) i = 0;
} else {
for (i = choices.length - 1; i >= 0 && val <= choices[i]; --i) {}
if (i < 0) i = choices.length - 1;
}
Shaders.configShadowResMul = choices[i];
par1GuiButton.displayString = "ShadowResMul: " + String.format("%.4f", Shaders.configShadowResMul);
Shaders.scheduleResizeShadow();
break;
}
case 17: /* Normal Map */ {
Shaders.configNormalMap = !Shaders.configNormalMap;
// displayString
par1GuiButton.displayString = "NormapMap: " + toStringOnOff(Shaders.configNormalMap);
mc.scheduleResourcesRefresh(); // schedule refresh texture
break;
}
case 18: /* Normal Map */ {
Shaders.configSpecularMap = !Shaders.configSpecularMap;
// displayString
par1GuiButton.displayString = "SpecularMap: " + toStringOnOff(Shaders.configSpecularMap);
mc.scheduleResourcesRefresh(); // schedule refresh texture
break;
}
case 19: /* old Lighting */ {
Shaders.configOldLighting = !Shaders.configOldLighting;
// displayString
par1GuiButton.displayString = "OldLighting: " + toStringOnOff(Shaders.configOldLighting);
Shaders.updateBlockLightLevel();
mc.renderGlobal.loadRenderers();
break;
}
case 11: /* texture filter */ {
Shaders.configTexMinFilB = (Shaders.configTexMinFilB + 1) % Shaders.texMinFilRange;
Shaders.configTexMinFilN = Shaders.configTexMinFilS = Shaders.configTexMinFilB;
par1GuiButton.displayString = "Tex Min: " + Shaders.texMinFilDesc[Shaders.configTexMinFilB];
ShadersTex.updateTextureMinMagFilter();
break;
}
case 12: /* texture filter */ {
Shaders.configTexMagFilN = (Shaders.configTexMagFilN + 1) % Shaders.texMagFilRange;
par1GuiButton.displayString = "Tex_n Mag: " + Shaders.texMagFilDesc[Shaders.configTexMagFilN];
ShadersTex.updateTextureMinMagFilter();
break;
}
case 13: /* texture filter */ {
Shaders.configTexMagFilS = (Shaders.configTexMagFilS + 1) % Shaders.texMagFilRange;
par1GuiButton.displayString = "Tex_s Mag: " + Shaders.texMagFilDesc[Shaders.configTexMagFilS];
ShadersTex.updateTextureMinMagFilter();
break;
}
case 14: /* shadow frustum clipping */ {
Shaders.configShadowClipFrustrum = !Shaders.configShadowClipFrustrum;
par1GuiButton.displayString =
"ShadowClipFrustrum: " + toStringOnOff(Shaders.configShadowClipFrustrum);
ShadersTex.updateTextureMinMagFilter();
break;
}
case 5: /* Open shaderpacks folder */
switch (net.minecraft.util.Util.getOSType()) {
case OSX:
{
try {
Runtime.getRuntime().exec(new String[] {
"/usr/bin/open", Shaders.shaderpacksdir.getAbsolutePath()
});
return;
} catch (IOException var7) {
var7.printStackTrace();
}
}
break;
case WINDOWS:
{
String var2 = String.format(
"cmd.exe /C start \"Open file\" \"%s\"",
new Object[] {Shaders.shaderpacksdir.getAbsolutePath()});
try {
Runtime.getRuntime().exec(var2);
return;
} catch (IOException var6) {
var6.printStackTrace();
}
}
break;
default:
break;
}
boolean var8 = false;
try {
Class var3 = Class.forName("java.awt.Desktop");
Object var4 = var3.getMethod("getDesktop", new Class[0]).invoke((Object) null, new Object[0]);
var3.getMethod("browse", new Class[] {URI.class})
.invoke(var4, new Object[] {(new File(mc.mcDataDir, Shaders.shaderpacksdirname)).toURI()
});
} catch (Throwable var5) {
var5.printStackTrace();
var8 = true;
}
if (var8) {
System.out.println("Opening via system class!");
Sys.openURL("file://" + Shaders.shaderpacksdir.getAbsolutePath());
}
break;
case 6: /* Done */
File confshader = new File(Shaders.shadersdir, "current.cfg");
try {
Shaders.storeConfig();
} catch (Exception ex) {
}
if (needReinit) {
needReinit = false;
Shaders.loadShaderPack();
Shaders.uninit();
this.mc.renderGlobal.loadRenderers();
}
this.mc.displayGuiScreen(this.parentGui); // displayGuiScreen
break;
default:
this.shaderList.actionPerformed(par1GuiButton); // actionPerformed
}
}
}
@Override
/**
* Draws the screen and all the components in it.
*/
public void drawScreen(int par1, int par2, float par3) {
drawDefaultBackground(); // background
this.shaderList.drawScreen(par1, par2, par3); // drawScreen
if (this.updateTimer <= 0) {
this.shaderList.updateList();
this.updateTimer += 20;
}
this.drawCenteredString(this.fontRendererObj, "Shaders ", this.width / 2, 16, 0xffffff);
this.drawCenteredString(this.fontRendererObj, " v" + Shaders.versionString, this.width - 40, 10, 0x808080);
// this.drawCenteredString(this.fontRenderer, "( Place zipped Shader files here. )", this.width / 4 + 10,
// this.height - 26, 0x808080);
super.drawScreen(par1, par2, par3);
}
@Override
/**
* Called from the main game loop to update the screen.
*/
public void updateScreen() {
super.updateScreen();
--this.updateTimer;
}
public Minecraft getMc() {
return this.mc;
}
public void drawCenteredString(String par1, int par2, int par3, int par4) {
this.drawCenteredString(this.fontRendererObj, par1, par2, par3, par4);
}
}
@@ -1,75 +0,0 @@
package com.gtnewhorizons.angelica.client;
import java.util.ArrayList;
import net.minecraft.client.gui.GuiSlot;
import net.minecraft.client.renderer.Tessellator;
class GuiSlotShaders extends GuiSlot {
private ArrayList shaderslist;
final GuiShaders shadersGui;
public GuiSlotShaders(GuiShaders par1GuiShaders) {
// super(par1GuiShaders.getMc(), par1GuiShaders.width / 2 + 20, par1GuiShaders.height, 40, par1GuiShaders.height
// - 70, 16);
super(
par1GuiShaders.getMc(),
par1GuiShaders.width / 2 + 20,
par1GuiShaders.height,
40,
par1GuiShaders.height - 70,
16);
this.shadersGui = par1GuiShaders;
this.shaderslist = Shaders.listofShaders();
}
public void updateList() {
this.shaderslist = Shaders.listofShaders();
}
@Override
/** getSize */
protected int getSize() {
return this.shaderslist.size();
}
@Override
/** elementClicked */
protected void elementClicked(int par1, boolean par2, int par3, int par4) {
Shaders.setShaderPack((String) shaderslist.get(par1));
shadersGui.needReinit = false;
Shaders.loadShaderPack();
Shaders.uninit();
}
@Override
/** isSelected */
protected boolean isSelected(int par1) {
return ((String) this.shaderslist.get(par1)).equals(Shaders.currentshadername);
}
@Override
/** getScrollBarX */
protected int getScrollBarX() {
return this.width - 6;
}
@Override
/** getContentHeight */
protected int getContentHeight() {
return this.getSize() * 18;
}
@Override
/** drawBackground */
protected void drawBackground() {
// this.shadersGui.drawDefaultBackground();
}
@Override
/** drawSlot */
protected void drawSlot(int par1, int par2, int par3, int par4, Tessellator par5, int par6, int par7) {
this.shadersGui.drawCenteredString(
(String) this.shaderslist.get(par1), this.shadersGui.width / 4 + 10, par3 + 1, 0xffffff);
}
}
@@ -1,76 +0,0 @@
package com.gtnewhorizons.angelica.client;
import java.nio.ByteBuffer;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
/**
*
* @author Nathanael Lane
*/
public class HFNoiseTexture {
public int texID;
public int textureUnit;
public HFNoiseTexture(int width, int height) {
texID = GL11.glGenTextures();
textureUnit = 15;
byte[] image = genHFNoiseImage(width, height);
ByteBuffer data = BufferUtils.createByteBuffer(image.length);
data.put(image);
data.flip();
// GL13.glActiveTexture(GL13.GL_TEXTURE0 + this.textureUnit);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, texID);
GL11.glTexImage2D(
GL11.GL_TEXTURE_2D, 0, GL11.GL_RGB, width, height, 0, GL11.GL_RGB, GL11.GL_UNSIGNED_BYTE, data);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_REPEAT);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_REPEAT);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
// GL30.glGenerateMipmap(GL11.GL_TEXTURE_2D);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);
}
public int getID() {
return texID;
}
public void destroy() {
GL11.glDeleteTextures(texID);
texID = 0;
}
// from George Marsaglia's paper on XORshift PRNGs
private int random(int seed) {
seed ^= (seed << 13);
seed ^= (seed >> 17);
seed ^= (seed << 5);
return seed;
}
private byte random(int x, int y, int z) {
int seed = (random(x) + random(y * 19)) * random(z * 23) - z;
return (byte) (random(seed) % 128);
}
/*
* Just a random value for each pixel to get maximum frequency
*/
private byte[] genHFNoiseImage(int width, int height) {
byte[] image = new byte[width * height * 3];
int index = 0;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
for (int z = 1; z < 4; z++) {
image[index++] = random(x, y, z);
}
}
}
return image;
}
}
@@ -1,10 +0,0 @@
package com.gtnewhorizons.angelica.client;
import java.io.InputStream;
public interface IShaderPack {
void close();
InputStream getResourceAsStream(String resName);
}
@@ -1,13 +0,0 @@
package com.gtnewhorizons.angelica.client;
public class MultiTexID {
public int base;
public int norm;
public int spec;
public MultiTexID(int baseTex, int normTex, int specTex) {
base = baseTex;
norm = normTex;
spec = specTex;
}
}
@@ -1,16 +0,0 @@
package com.gtnewhorizons.angelica.client;
import java.io.InputStream;
public class ShaderPackDefault implements IShaderPack {
public ShaderPackDefault() {}
@Override
public void close() {}
@Override
public InputStream getResourceAsStream(String resName) {
return ShaderPackDefault.class.getResourceAsStream(resName);
}
}
@@ -1,30 +0,0 @@
package com.gtnewhorizons.angelica.client;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
public class ShaderPackFolder implements IShaderPack {
protected File packFile;
public ShaderPackFolder(String name, File file) {
packFile = file;
}
@Override
public void close() {}
@Override
public InputStream getResourceAsStream(String resName) {
try {
File resFile = new File(packFile, resName.substring(1));
if (resFile != null) {
return new BufferedInputStream(new FileInputStream(resFile));
}
} catch (Exception excp) {
}
return null;
}
}
@@ -1,16 +0,0 @@
package com.gtnewhorizons.angelica.client;
import java.io.InputStream;
public class ShaderPackNone implements IShaderPack {
public ShaderPackNone() {}
@Override
public void close() {}
@Override
public InputStream getResourceAsStream(String resName) {
return null;
}
}
@@ -1,48 +0,0 @@
package com.gtnewhorizons.angelica.client;
import java.io.File;
import java.io.InputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
public class ShaderPackZip implements IShaderPack {
protected File packFile;
protected ZipFile packZipFile;
public ShaderPackZip(String name, File file) {
packFile = file;
packZipFile = null;
}
@Override
public void close() {
if (packZipFile != null) {
try {
packZipFile.close();
} catch (Exception excp) {
}
packZipFile = null;
}
}
@Override
public InputStream getResourceAsStream(String resName) {
if (packZipFile == null) {
try {
packZipFile = new ZipFile(packFile);
} catch (Exception excp) {
}
}
if (packZipFile != null) {
try {
ZipEntry entry = packZipFile.getEntry(resName.substring(1));
if (entry != null) {
return packZipFile.getInputStream(entry);
}
} catch (Exception excp) {
}
}
return null;
}
}
File diff suppressed because it is too large. Load diff
@@ -1,87 +0,0 @@
package com.gtnewhorizons.angelica.client;
import java.nio.IntBuffer;
import net.minecraft.block.Block;
import net.minecraft.block.BlockIce;
import net.minecraft.client.renderer.EntityRenderer;
import net.minecraft.client.renderer.ItemRenderer;
import net.minecraft.client.renderer.RenderGlobal;
import net.minecraft.client.renderer.WorldRenderer;
import net.minecraft.client.renderer.culling.Frustrum;
import net.minecraft.item.Item;
import net.minecraft.item.ItemBlock;
import org.lwjgl.opengl.GL11;
public class ShadersRender {
public static void setFrustrumPosition(Frustrum frustrum, double x, double y, double z) {
frustrum.setPosition(x, y, z);
}
public static void clipRenderersByFrustrum(RenderGlobal renderGlobal, Frustrum frustrum, float par2) {
Shaders.checkGLError("pre clip");
if (!Shaders.isShadowPass) {
WorldRenderer[] worldRenderers = renderGlobal.worldRenderers;
for (int i = 0; i < worldRenderers.length; ++i) {
if (!worldRenderers[i].skipAllRenderPasses()) {
worldRenderers[i].updateInFrustum(frustrum);
}
}
} else {
WorldRenderer[] worldRenderers = renderGlobal.worldRenderers;
for (int i = 0; i < worldRenderers.length; ++i) {
if (!worldRenderers[i].skipAllRenderPasses()) {
worldRenderers[i].isInFrustum = true;
}
}
}
}
public static void renderHand0(EntityRenderer er, float par1, int par2) {
if (!Shaders.isShadowPass) {
Item item = (Shaders.itemToRender != null) ? Shaders.itemToRender.getItem() : null;
Block block = (item instanceof ItemBlock) ? ((ItemBlock) item).field_150939_a : null;
// ItemCloth is for semitransparent block : stained glass, wool
if (!(item instanceof ItemBlock) && !(block instanceof BlockIce)) {
Shaders.readCenterDepth();
Shaders.beginHand();
er.renderHand(par1, par2);
Shaders.endHand();
Shaders.isHandRendered = true;
}
}
}
public static void renderHand1(EntityRenderer er, float par1, int par2) {
if (!Shaders.isShadowPass) {
if (!Shaders.isHandRendered) {
Shaders.readCenterDepth();
GL11.glEnable(GL11.GL_BLEND);
Shaders.beginHand();
er.renderHand(par1, par2);
Shaders.endHand();
Shaders.isHandRendered = true;
}
}
}
public static void renderItemFP(ItemRenderer itemRenderer, float par1) {
// clear depth buffer locally
GL11.glDepthFunc(GL11.GL_GEQUAL);
GL11.glPushMatrix();
IntBuffer drawBuffers = Shaders.activeDrawBuffers;
Shaders.setDrawBuffers(Shaders.drawBuffersNone);
itemRenderer.renderItemInFirstPerson(par1);
Shaders.setDrawBuffers(drawBuffers);
GL11.glPopMatrix();
GL11.glDepthFunc(GL11.GL_LEQUAL);
// really render item or hand
itemRenderer.renderItemInFirstPerson(par1);
}
public static void renderFPOverlay(EntityRenderer er, float par1, int par2) {
Shaders.beginFPOverlay();
er.renderHand(par1, par2);
Shaders.endFPOverlay();
}
}
@@ -1,243 +0,0 @@
package com.gtnewhorizons.angelica.client;
import static org.lwjgl.opengl.ARBVertexShader.glDisableVertexAttribArrayARB;
import static org.lwjgl.opengl.ARBVertexShader.glEnableVertexAttribArrayARB;
import static org.lwjgl.opengl.ARBVertexShader.glVertexAttribPointerARB;
import com.gtnewhorizons.angelica.transform.ALog;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;
import java.util.Arrays;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.Tessellator;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL13;
public class ShadersTess {
public static final int vertexStride = 16;
public static int draw(Tessellator tess) {
if (!tess.isDrawing) {
throw new IllegalStateException("Not tesselating!");
} else {
tess.isDrawing = false;
if (tess.drawMode == GL11.GL_QUADS && tess.vertexCount % 4 != 0) {
ALog.warning("%s", "bad vertexCount");
}
int voffset = 0;
int realDrawMode = tess.drawMode;
while (voffset < tess.vertexCount) {
int vcount;
vcount = Math.min(tess.vertexCount - voffset, tess.byteBuffer.capacity() / (vertexStride * 4));
if (realDrawMode == GL11.GL_QUADS) vcount = vcount / 4 * 4;
tess.floatBuffer.clear();
tess.shortBuffer.clear();
tess.intBuffer.clear();
tess.intBuffer.put(tess.rawBuffer, voffset * vertexStride, vcount * vertexStride);
tess.byteBuffer.position(0);
tess.byteBuffer.limit(vcount * (vertexStride * 4));
voffset += vcount;
if (tess.hasTexture) {
tess.floatBuffer.position(3);
GL11.glTexCoordPointer(2, (vertexStride * 4), tess.floatBuffer);
GL11.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
}
if (tess.hasBrightness) {
OpenGlHelper.setClientActiveTexture(OpenGlHelper.lightmapTexUnit);
tess.shortBuffer.position(6 * 2);
GL11.glTexCoordPointer(2, (vertexStride * 4), tess.shortBuffer);
GL11.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
OpenGlHelper.setClientActiveTexture(OpenGlHelper.defaultTexUnit);
}
if (tess.hasColor) {
tess.byteBuffer.position(5 * 4);
GL11.glColorPointer(4, true, (vertexStride * 4), tess.byteBuffer);
GL11.glEnableClientState(GL11.GL_COLOR_ARRAY);
}
if (tess.hasNormals) {
tess.floatBuffer.position(9);
GL11.glNormalPointer((vertexStride * 4), tess.floatBuffer);
GL11.glEnableClientState(GL11.GL_NORMAL_ARRAY);
}
tess.floatBuffer.position(0);
GL11.glVertexPointer(3, (vertexStride * 4), tess.floatBuffer);
ShadersTess.preDrawArray(tess);
GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY);
GL11.glDrawArrays(realDrawMode, 0, vcount);
}
// end loop
GL11.glDisableClientState(GL11.GL_VERTEX_ARRAY);
ShadersTess.postDrawArray(tess);
if (tess.hasTexture) {
GL11.glDisableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
}
if (tess.hasBrightness) {
OpenGlHelper.setClientActiveTexture(OpenGlHelper.lightmapTexUnit);
GL11.glDisableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
OpenGlHelper.setClientActiveTexture(OpenGlHelper.defaultTexUnit);
}
if (tess.hasColor) {
GL11.glDisableClientState(GL11.GL_COLOR_ARRAY);
}
if (tess.hasNormals) {
GL11.glDisableClientState(GL11.GL_NORMAL_ARRAY);
}
int n = tess.rawBufferIndex * 4;
tess.reset();
return n;
}
}
public static void preDrawArray(Tessellator tess) {
// Shaders.checkGLError("preDrawArray");
if (Shaders.useMultiTexCoord3Attrib && tess.hasTexture) {
GL13.glClientActiveTexture(GL13.GL_TEXTURE3);
GL11.glTexCoordPointer(2, (vertexStride * 4), (FloatBuffer) tess.floatBuffer.position(12));
GL11.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
GL13.glClientActiveTexture(GL13.GL_TEXTURE0);
}
if (Shaders.useMidTexCoordAttrib && tess.hasTexture) {
glVertexAttribPointerARB(
Shaders.midTexCoordAttrib, 2, false, vertexStride * 4, (FloatBuffer) tess.floatBuffer.position(12));
glEnableVertexAttribArrayARB(Shaders.midTexCoordAttrib);
}
if (Shaders.useEntityAttrib) {
glVertexAttribPointerARB(Shaders.entityAttrib, 3, false, false, vertexStride * 4, (ShortBuffer)
tess.shortBuffer.position(7 * 2));
glEnableVertexAttribArrayARB(Shaders.entityAttrib);
}
// Shaders.checkGLError("preDrawArray");
}
public static void preDrawArrayVBO(Tessellator tess) {
// Shaders.checkGLError("preDrawArray");
if (Shaders.useMultiTexCoord3Attrib && tess.hasTexture) {
GL13.glClientActiveTexture(GL13.GL_TEXTURE3);
GL11.glTexCoordPointer(2, GL11.GL_FLOAT, (vertexStride * 4), 12 * 4L);
GL11.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
GL13.glClientActiveTexture(GL13.GL_TEXTURE0);
}
if (Shaders.useMidTexCoordAttrib && tess.hasTexture) {
glVertexAttribPointerARB(Shaders.midTexCoordAttrib, 2, GL11.GL_FLOAT, false, vertexStride * 4, 12 * 4L);
glEnableVertexAttribArrayARB(Shaders.midTexCoordAttrib);
}
if (Shaders.useEntityAttrib) {
glVertexAttribPointerARB(Shaders.entityAttrib, 3, GL11.GL_SHORT, false, vertexStride * 4, 7 * 4L);
glEnableVertexAttribArrayARB(Shaders.entityAttrib);
}
// Shaders.checkGLError("preDrawArray");
}
public static void postDrawArray(Tessellator tess) {
// Shaders.checkGLError("postDrawArray");
if (Shaders.useEntityAttrib) {
glDisableVertexAttribArrayARB(Shaders.entityAttrib);
}
if (Shaders.useMidTexCoordAttrib && tess.hasTexture) {
glDisableVertexAttribArrayARB(Shaders.midTexCoordAttrib);
}
if (Shaders.useMultiTexCoord3Attrib && tess.hasTexture) {
GL13.glClientActiveTexture(GL13.GL_TEXTURE3);
GL11.glDisableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
GL13.glClientActiveTexture(GL13.GL_TEXTURE0);
}
// Shaders.checkGLError("postDrawArray");
}
public static void addVertex(Tessellator tess, double parx, double pary, double parz) {
int[] rawBuffer = tess.rawBuffer;
int rbi = tess.rawBufferIndex;
float fx = (float) (parx + tess.xOffset);
float fy = (float) (pary + tess.yOffset);
float fz = (float) (parz + tess.zOffset);
// Check if buffer is nearly full
if (rbi >= tess.bufferSize - vertexStride * 4) {
if (tess.bufferSize >= 0x1000000) {
// Max size reached. Just draw.
if (tess.addedVertices % 4 == 0) {
tess.draw();
tess.isDrawing = true;
}
} else if (tess.bufferSize > 0) {
// Expand
tess.bufferSize *= 2;
tess.rawBuffer = rawBuffer = Arrays.copyOf(tess.rawBuffer, tess.bufferSize);
System.out.format("Expand tesselator buffer %d\n", tess.bufferSize);
} else {
// Initialize
tess.bufferSize = 0x10000;
tess.rawBuffer = rawBuffer = new int[tess.bufferSize];
}
}
// shaders mod calculate normal and mid UV
if (tess.drawMode == 7) {
int i = tess.addedVertices % 4;
float[] vertexPos = tess.vertexPos;
vertexPos[i * 4 + 0] = fx;
vertexPos[i * 4 + 1] = fy;
vertexPos[i * 4 + 2] = fz;
if (i == 3) {
// calculate normal
float x1 = vertexPos[8 + 0] - vertexPos[+0];
float y1 = vertexPos[8 + 1] - vertexPos[+1];
float z1 = vertexPos[8 + 2] - vertexPos[+2];
float x2 = vertexPos[12 + 0] - vertexPos[4 + 0];
float y2 = vertexPos[12 + 1] - vertexPos[4 + 1];
float z2 = vertexPos[12 + 2] - vertexPos[4 + 2];
float vnx = y1 * z2 - y2 * z1;
float vny = z1 * x2 - z2 * x1;
float vnz = x1 * y2 - x2 * y1;
float lensq = vnx * vnx + vny * vny + vnz * vnz;
float mult = (lensq != 0.0) ? (float) (1f / Math.sqrt(lensq)) : 1f;
rawBuffer[rbi + (9 - vertexStride * 3)] = rawBuffer[rbi + (9 - vertexStride * 2)] =
rawBuffer[rbi + (9 - vertexStride * 1)] = Float.floatToRawIntBits(tess.normalX = vnx * mult);
rawBuffer[rbi + (10 - vertexStride * 3)] = rawBuffer[rbi + (10 - vertexStride * 2)] =
rawBuffer[rbi + (10 - vertexStride * 1)] = Float.floatToRawIntBits(tess.normalY = vny * mult);
rawBuffer[rbi + (11 - vertexStride * 3)] = rawBuffer[rbi + (11 - vertexStride * 2)] =
rawBuffer[rbi + (11 - vertexStride * 1)] = Float.floatToRawIntBits(tess.normalZ = vnz * mult);
tess.hasNormals = true;
// mid UV
tess.midTextureU = (Float.intBitsToFloat(rawBuffer[rbi + (3 - vertexStride * 3)])
+ Float.intBitsToFloat(rawBuffer[rbi + (3 - vertexStride * 2)])
+ Float.intBitsToFloat(rawBuffer[rbi + (3 - vertexStride * 1)])
+ (float) tess.textureU)
/ 4;
tess.midTextureV = (Float.intBitsToFloat(rawBuffer[rbi + (4 - vertexStride * 3)])
+ Float.intBitsToFloat(rawBuffer[rbi + (4 - vertexStride * 2)])
+ Float.intBitsToFloat(rawBuffer[rbi + (4 - vertexStride * 1)])
+ (float) tess.textureV)
/ 4;
rawBuffer[rbi + (12 - vertexStride * 3)] = rawBuffer[rbi + (12 - vertexStride * 2)] =
rawBuffer[rbi + (12 - vertexStride * 1)] = Float.floatToRawIntBits(tess.midTextureU);
rawBuffer[rbi + (13 - vertexStride * 3)] = rawBuffer[rbi + (13 - vertexStride * 2)] =
rawBuffer[rbi + (13 - vertexStride * 1)] = Float.floatToRawIntBits(tess.midTextureV);
}
}
// end normal and mid UV calculation
++tess.addedVertices;
rawBuffer[rbi + 0] = Float.floatToRawIntBits((float) fx);
rawBuffer[rbi + 1] = Float.floatToRawIntBits((float) fy);
rawBuffer[rbi + 2] = Float.floatToRawIntBits((float) fz);
rawBuffer[rbi + 3] = Float.floatToRawIntBits((float) tess.textureU);
rawBuffer[rbi + 4] = Float.floatToRawIntBits((float) tess.textureV);
rawBuffer[rbi + 5] = tess.color;
rawBuffer[rbi + 6] = tess.brightness;
rawBuffer[rbi + 7] = Shaders.getEntityData();
rawBuffer[rbi + 8] = Shaders.getEntityData2();
rawBuffer[rbi + 9] = Float.floatToRawIntBits((float) tess.normalX);
rawBuffer[rbi + 10] = Float.floatToRawIntBits((float) tess.normalY);
rawBuffer[rbi + 11] = Float.floatToRawIntBits((float) tess.normalZ);
rawBuffer[rbi + 12] = Float.floatToRawIntBits((float) tess.midTextureU);
rawBuffer[rbi + 13] = Float.floatToRawIntBits((float) tess.midTextureV);
tess.rawBufferIndex = rbi += vertexStride;
++tess.vertexCount;
}
}
@@ -1,988 +0,0 @@
package com.gtnewhorizons.angelica.client;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.imageio.ImageIO;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.texture.AbstractTexture;
import net.minecraft.client.renderer.texture.DynamicTexture;
import net.minecraft.client.renderer.texture.ITextureObject;
import net.minecraft.client.renderer.texture.LayeredTexture;
import net.minecraft.client.renderer.texture.Stitcher;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.client.renderer.texture.TextureUtil;
import net.minecraft.client.resources.IResource;
import net.minecraft.client.resources.IResourceManager;
import net.minecraft.util.ResourceLocation;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;
import org.lwjgl.opengl.GL13;
import org.lwjgl.opengl.GL30.*;
public class ShadersTex {
public static final int initialBufferSize = 1048576;
public static ByteBuffer byteBuffer = BufferUtils.createByteBuffer(initialBufferSize * 4);
public static IntBuffer intBuffer = byteBuffer.asIntBuffer();
public static int[] intArray = new int[initialBufferSize];
public static final int defBaseTexColor = 0x00000000;
public static final int defNormTexColor = 0xFF7F7FFF;
public static final int defSpecTexColor = 0x00000000;
public static Map<Integer, MultiTexID> multiTexMap = new HashMap();
public static TextureMap updatingTextureMap = null;
public static TextureAtlasSprite updatingSprite = null;
public static MultiTexID updatingTex = null;
public static MultiTexID boundTex = null;
public static int updatingPage = 0;
public static String iconName = null;
public static IntBuffer getIntBuffer(int size) {
if (intBuffer.capacity() < size) {
int bufferSize = roundUpPOT(size);
byteBuffer = BufferUtils.createByteBuffer(bufferSize * 4);
intBuffer = byteBuffer.asIntBuffer();
}
return intBuffer;
}
public static int[] getIntArray(int size) {
if (intArray.length < size) {
intArray = null;
intArray = new int[roundUpPOT(size)];
}
return intArray;
}
public static int roundUpPOT(int x) {
int i = x - 1;
i |= (i >> 1);
i |= (i >> 2);
i |= (i >> 4);
i |= (i >> 8);
i |= (i >> 16);
return i + 1;
}
public static IntBuffer fillIntBuffer(int size, int value) {
int[] aint = getIntArray(size);
IntBuffer intBuf = getIntBuffer(size);
Arrays.fill(intArray, 0, size, value);
intBuffer.put(intArray, 0, size);
return intBuffer;
}
public static int[] createAIntImage(int size) {
int[] aint = new int[size * 3];
Arrays.fill(aint, 0, size, defBaseTexColor);
Arrays.fill(aint, size, size * 2, defNormTexColor);
Arrays.fill(aint, size * 2, size * 3, defSpecTexColor);
return aint;
}
public static int[] createAIntImage(int size, int color) {
int[] aint = new int[size * 3];
Arrays.fill(aint, 0, size, color);
Arrays.fill(aint, size, size * 2, defNormTexColor);
Arrays.fill(aint, size * 2, size * 3, defSpecTexColor);
return aint;
}
public static MultiTexID getMultiTexID(AbstractTexture tex) {
MultiTexID multiTex = tex.multiTex;
if (multiTex == null) {
int baseTex = tex.getGlTextureId();
multiTex = multiTexMap.get(Integer.valueOf(baseTex));
if (multiTex == null) {
multiTex = new MultiTexID(baseTex, GL11.glGenTextures(), GL11.glGenTextures());
multiTexMap.put(baseTex, multiTex);
}
tex.multiTex = multiTex;
}
return multiTex;
}
public static void deleteTextures(AbstractTexture atex) {
int texid = atex.glTextureId;
if (texid != -1) {
GL11.glDeleteTextures(texid);
atex.glTextureId = -1;
}
MultiTexID multiTex = atex.multiTex;
if (multiTex != null) {
atex.multiTex = null;
multiTexMap.remove(Integer.valueOf(multiTex.base));
GL11.glDeleteTextures(multiTex.norm);
GL11.glDeleteTextures(multiTex.spec);
if (multiTex.base != texid) {
System.err.println("Error : MultiTexID.base mismatch.");
GL11.glDeleteTextures(multiTex.base);
}
}
}
/** Remove MultiTexID object reference and delete textures */
public static int deleteMultiTex(ITextureObject tex) {
if (tex instanceof AbstractTexture) {
deleteTextures((AbstractTexture) tex);
} else {
GL11.glDeleteTextures(tex.getGlTextureId());
}
return 0;
}
public static void bindNSTextures(int normTex, int specTex) {
// Shaders.checkGLError("pre bindNSTextures");
if (Shaders.isRenderingWorld && Shaders.activeTexUnit == GL13.GL_TEXTURE0) {
GL13.glActiveTexture(GL13.GL_TEXTURE2);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, normTex);
GL13.glActiveTexture(GL13.GL_TEXTURE3);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, specTex);
GL13.glActiveTexture(GL13.GL_TEXTURE0);
}
// Shaders.checkGLError("bindNSTextures");
}
public static void bindNSTextures(MultiTexID multiTex) {
bindNSTextures(multiTex.norm, multiTex.spec);
}
public static void bindTextures(int baseTex, int normTex, int specTex) {
// Shaders.checkGLError("pre bindTextures");
if (Shaders.isRenderingWorld && Shaders.activeTexUnit == GL13.GL_TEXTURE0) {
GL13.glActiveTexture(GL13.GL_TEXTURE2);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, normTex);
GL13.glActiveTexture(GL13.GL_TEXTURE3);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, specTex);
GL13.glActiveTexture(GL13.GL_TEXTURE0);
}
GL11.glBindTexture(GL11.GL_TEXTURE_2D, baseTex);
// Shaders.checkGLError("bindTextures");
}
public static void bindTextures(MultiTexID multiTex) {
boundTex = multiTex;
if (Shaders.isRenderingWorld && Shaders.activeTexUnit == GL13.GL_TEXTURE0) {
if (Shaders.configNormalMap) {
GL13.glActiveTexture(GL13.GL_TEXTURE2);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.norm);
}
if (Shaders.configSpecularMap) {
GL13.glActiveTexture(GL13.GL_TEXTURE3);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.spec);
}
GL13.glActiveTexture(GL13.GL_TEXTURE0);
}
GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.base);
}
public static void bindTexture(ITextureObject tex) {
if (tex instanceof TextureMap) {
Shaders.atlasSizeX = ((TextureMap) tex).atlasWidth;
Shaders.atlasSizeY = ((TextureMap) tex).atlasHeight;
} else {
Shaders.atlasSizeX = 0;
Shaders.atlasSizeY = 0;
}
bindTextures(tex.getMultiTexID());
}
/** not used */
public static void bindTextures(int baseTex) {
MultiTexID multiTex = multiTexMap.get(Integer.valueOf(baseTex));
bindTextures(multiTex);
}
public static void allocTexStorage(int width, int height, int maxLevel) {
Shaders.checkGLError("pre allocTexStorage");
int level;
for (level = 0; (width >> level) > 0 && (height >> level) > 0 /*&& level<=maxLevel*/; ++level) {
GL11.glTexImage2D(
GL11.GL_TEXTURE_2D,
level,
GL11.GL_RGBA,
(width >> level),
(height >> level),
0,
GL12.GL_BGRA,
GL12.GL_UNSIGNED_INT_8_8_8_8_REV,
(IntBuffer) null);
}
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL12.GL_TEXTURE_MAX_LEVEL, level - 1);
Shaders.checkGLError("allocTexStorage");
// clear unused level otherwise glTexSubImage2D will crash on AMD when reallocation texture of different size.
// for ( ; level < 16 ; ++level) {
// GL11.glTexImage2D(GL11.GL_TEXTURE_2D, level, GL11.GL_RGBA, 0, 0, 0, GL12.GL_BGRA,
// GL12.GL_UNSIGNED_INT_8_8_8_8_REV, (IntBuffer)null);
// }
GL11.glGetError(); // It usually returns error 0x0501 Invalid value for width 0 height 0. Ignore it.
}
// for Dynamic Texture
public static void initDynamicTexture(int texID, int width, int height, DynamicTexture tex) {
MultiTexID multiTex = tex.getMultiTexID();
int[] aint = tex.getTextureData();
int size = width * height;
Arrays.fill(aint, size, size * 2, defNormTexColor);
Arrays.fill(aint, size * 2, size * 3, defSpecTexColor);
// base texture
GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.base);
allocTexStorage(width, height, 0);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_REPEAT);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_REPEAT);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL12.GL_TEXTURE_MAX_LEVEL, 0);
// norm texture
GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.norm);
allocTexStorage(width, height, 0);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_REPEAT);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_REPEAT);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL12.GL_TEXTURE_MAX_LEVEL, 0);
// spec texture
GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.spec);
allocTexStorage(width, height, 0);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_REPEAT);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_REPEAT);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL12.GL_TEXTURE_MAX_LEVEL, 0);
// base texture
GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.base);
}
public static ITextureObject createDefaultTexture() {
DynamicTexture tex = new DynamicTexture(1, 1);
tex.getTextureData()[0] = 0xffffffff;
tex.updateDynamicTexture();
return tex;
}
// for TextureMap
public static void allocateTextureMap(
int texID, int mipmapLevels, int width, int height, float anisotropy, Stitcher stitcher, TextureMap tex) {
System.out.println("allocateTextureMap " + tex.getTextureType() + " " + mipmapLevels + " " + width + " "
+ height + " " + anisotropy + " ");
updatingTextureMap = tex;
tex.atlasWidth = width;
tex.atlasHeight = height;
MultiTexID multiTex = getMultiTexID(tex);
updatingTex = multiTex;
TextureUtil.allocateTextureImpl(multiTex.base, mipmapLevels, width, height, anisotropy);
if (Shaders.configNormalMap)
TextureUtil.allocateTextureImpl(multiTex.norm, mipmapLevels, width, height, anisotropy);
if (Shaders.configSpecularMap)
TextureUtil.allocateTextureImpl(multiTex.spec, mipmapLevels, width, height, anisotropy);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, texID);
}
public static TextureAtlasSprite setSprite(TextureAtlasSprite tas) {
return updatingSprite = tas;
}
public static String setIconName(String name) {
return iconName = name;
}
public static void uploadTexSubForLoadAtlas(
int[][] data, int width, int height, int xoffset, int yoffset, boolean linear, boolean clamp) {
TextureUtil.uploadTextureMipmap(data, width, height, xoffset, yoffset, linear, clamp);
boolean border = updatingSprite.useAnisotropicFiltering;
int[][] aaint;
//
if (Shaders.configNormalMap) {
aaint = readImageAndMipmaps(iconName + "_n", width, height, data.length, border, defNormTexColor);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, updatingTex.norm);
TextureUtil.uploadTextureMipmap(aaint, width, height, xoffset, yoffset, linear, clamp);
}
//
if (Shaders.configSpecularMap) {
aaint = readImageAndMipmaps(iconName + "_s", width, height, data.length, border, defSpecTexColor);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, updatingTex.spec);
TextureUtil.uploadTextureMipmap(aaint, width, height, xoffset, yoffset, linear, clamp);
}
//
GL11.glBindTexture(GL11.GL_TEXTURE_2D, updatingTex.base);
}
public static int[][] readImageAndMipmaps(
String name, int width, int height, int numLevels, boolean border, int defColor) {
int[][] aaint = new int[numLevels][];
int[] aint;
aaint[0] = aint = new int[width * height];
boolean goodImage = false;
BufferedImage image = readImage(updatingTextureMap.completeResourceLocation(new ResourceLocation(name), 0));
if (image != null) {
int imageWidth = image.getWidth();
int imageHeight = image.getHeight();
if (imageWidth + (border ? 16 : 0) == width) {
goodImage = true;
image.getRGB(0, 0, imageWidth, imageWidth, aint, 0, imageWidth);
if (border) TextureUtil.prepareAnisotropicData(aint, imageWidth, imageWidth, 8);
}
}
if (!goodImage) {
Arrays.fill(aint, defColor);
}
GL11.glBindTexture(GL11.GL_TEXTURE_2D, updatingTex.spec);
aaint = genMipmapsSimple(aaint.length - 1, width, aaint);
return aaint;
}
public static BufferedImage readImage(ResourceLocation resLoc) {
BufferedImage image = null;
InputStream istr = null;
if (resManager != null) {
try {
istr = resManager.getResource(resLoc).getInputStream();
image = ImageIO.read(istr);
} catch (IOException e) {
}
if (istr != null) {
try {
istr.close();
} catch (IOException e) {
}
istr = null;
}
}
return image;
}
public static int[][] genMipmapsSimple(int maxLevel, int width, int[][] data) {
int level;
for (level = 1; level <= maxLevel; ++level) {
if (data[level] == null) {
int cw = width >> level;
int pw = cw * 2;
int[] aintp = data[level - 1];
int[] aintc = data[level] = new int[cw * cw];
int x, y;
for (y = 0; y < cw; ++y) {
for (x = 0; x < cw; ++x) {
int ppos = y * 2 * pw + x * 2;
aintc[y * cw + x] =
blend4Simple(aintp[ppos], aintp[ppos + 1], aintp[ppos + pw], aintp[ppos + pw + 1]);
}
}
}
}
return data;
}
public static void uploadTexSub(
int[][] data, int width, int height, int xoffset, int yoffset, boolean linear, boolean clamp) {
TextureUtil.uploadTextureMipmap(data, width, height, xoffset, yoffset, linear, clamp);
}
public static int blend4Alpha(int c0, int c1, int c2, int c3) {
int a0 = (c0 >>> 24) & 255;
int a1 = (c1 >>> 24) & 255;
int a2 = (c2 >>> 24) & 255;
int a3 = (c3 >>> 24) & 255;
int as = a0 + a1 + a2 + a3;
int an = (as + 2) / 4;
// int an = Math.min(Math.min(Math.min(a0,a1),a2),a3);
int dv;
if (as != 0) {
dv = as;
} else {
dv = 4;
a3 = a2 = a1 = a0 = 1;
}
int frac = (dv + 1) / 2;
// return (((Math.min(Math.min(Math.min(a0,a1),a2),a3)/ 4) << 24) |
int color = (an << 24)
| (((((c0 >>> 16) & 255) * a0
+ ((c1 >>> 16) & 255) * a1
+ ((c2 >>> 16) & 255) * a2
+ ((c3 >>> 16) & 255) * a3
+ frac)
/ dv)
<< 16)
| (((((c0 >>> 8) & 255) * a0
+ ((c1 >>> 8) & 255) * a1
+ ((c2 >>> 8) & 255) * a2
+ ((c3 >>> 8) & 255) * a3
+ frac)
/ dv)
<< 8)
| (((((c0 >>> 0) & 255) * a0
+ ((c1 >>> 0) & 255) * a1
+ ((c2 >>> 0) & 255) * a2
+ ((c3 >>> 0) & 255) * a3
+ frac)
/ dv)
<< 0);
return color;
}
public static int blend4Simple(int c0, int c1, int c2, int c3) {
int color = (((((c0 >>> 24) & 255) + ((c1 >>> 24) & 255) + ((c2 >>> 24) & 255) + ((c3 >>> 24) & 255) + 2) / 4)
<< 24)
| (((((c0 >>> 16) & 255) + ((c1 >>> 16) & 255) + ((c2 >>> 16) & 255) + ((c3 >>> 16) & 255) + 2) / 4)
<< 16)
| (((((c0 >>> 8) & 255) + ((c1 >>> 8) & 255) + ((c2 >>> 8) & 255) + ((c3 >>> 8) & 255) + 2) / 4) << 8)
| (((((c0 >>> 0) & 255) + ((c1 >>> 0) & 255) + ((c2 >>> 0) & 255) + ((c3 >>> 0) & 255) + 2) / 4) << 0);
return color;
}
public static void genMipmapAlpha(int[] aint, int offset, int width, int height) {
int minwh = Math.min(width, height);
int level;
int w1, w2, h1, h2, o1, o2;
w1 = w2 = width;
h1 = h2 = height;
o1 = o2 = offset;
// generate mipmap from big to small
o2 = offset;
w2 = width;
h2 = height;
o1 = 0;
w1 = 0;
h1 = 0;
for (level = 0; w2 > 1 && h2 > 1; ++level, w2 = w1, h2 = h1, o2 = o1) {
o1 = o2 + w2 * h2;
w1 = w2 / 2;
h1 = h2 / 2;
for (int y = 0; y < h1; ++y) {
int p1 = o1 + y * w1;
int p2 = o2 + y * 2 * w2;
for (int x = 0; x < w1; ++x) {
aint[p1 + x] = blend4Alpha(
aint[p2 + (x * 2)],
aint[p2 + (x * 2 + 1)],
aint[p2 + w2 + (x * 2)],
aint[p2 + w2 + (x * 2 + 1)]);
}
}
}
// fix black pixels from small to big
while (level > 0) {
--level;
w2 = width >> level;
h2 = height >> level;
o2 = o1 - w2 * h2;
int p2 = o2;
for (int y = 0; y < h2; ++y) {
for (int x = 0; x < w2; ++x) {
// p2 = o2 + y*w2 + x;
if (aint[p2] == 0) {
aint[p2] = aint[o1 + (y / 2) * w1 + (x / 2)] & 0x00ffffff;
}
++p2;
}
}
o1 = o2;
w1 = w2;
h1 = h2;
}
}
public static void genMipmapSimple(int[] aint, int offset, int width, int height) {
int minwh = Math.min(width, height);
int level;
int w1, w2, h1, h2, o1, o2;
w1 = w2 = width;
h1 = h2 = height;
o1 = o2 = offset;
// generate mipmap from big to small
o2 = offset;
w2 = width;
h2 = height;
o1 = 0;
w1 = 0;
h1 = 0;
for (level = 0; w2 > 1 && h2 > 1; ++level, w2 = w1, h2 = h1, o2 = o1) {
o1 = o2 + w2 * h2;
w1 = w2 / 2;
h1 = h2 / 2;
for (int y = 0; y < h1; ++y) {
int p1 = o1 + y * w1;
int p2 = o2 + y * 2 * w2;
for (int x = 0; x < w1; ++x) {
aint[p1 + x] = blend4Simple(
aint[p2 + (x * 2)],
aint[p2 + (x * 2 + 1)],
aint[p2 + w2 + (x * 2)],
aint[p2 + w2 + (x * 2 + 1)]);
}
}
}
// fix black pixels from small to big
while (level > 0) {
--level;
w2 = width >> level;
h2 = height >> level;
o2 = o1 - w2 * h2;
int p2 = o2;
for (int y = 0; y < h2; ++y) {
for (int x = 0; x < w2; ++x) {
// p2 = o2 + y*w2 + x;
if (aint[p2] == 0) {
aint[p2] = aint[o1 + (y / 2) * w1 + (x / 2)] & 0x00ffffff;
}
++p2;
}
}
o1 = o2;
w1 = w2;
h1 = h2;
}
}
public static boolean isSemiTransparent(int[] aint, int width, int height) {
int size = width * height;
// grass side texture ?;
if (aint[0] >>> 24 == 255 && aint[size - 1] == 0) return true;
for (int i = 0; i < size; ++i) {
int alpha = aint[i] >>> 24;
if (alpha != 0 && alpha != 255) return true;
}
return false;
}
public static void updateSubImage1(int[] src, int width, int height, int posX, int posY, int page, int color) {
int size = width * height;
IntBuffer intBuf = getIntBuffer(size);
int[] aint = getIntArray((size * 4 + 2) / 3);
if (src.length >= size * (page + 1)) {
System.arraycopy(src, size * page, aint, 0, size);
} else {
Arrays.fill(aint, color);
}
//
// if (page == 0)
genMipmapAlpha(aint, 0, width, height);
// else
// genMipmapSimple(aint,0,width,height);
//
for (int level = 0, offset = 0, lw = width, lh = height, px = posX, py = posY; lw > 0 && lh > 0; ++level) {
int lsize = lw * lh;
intBuf.clear();
intBuf.put(aint, offset, lsize).position(0).limit(lsize);
GL11.glTexSubImage2D(
GL11.GL_TEXTURE_2D, level, px, py, lw, lh, GL12.GL_BGRA, GL12.GL_UNSIGNED_INT_8_8_8_8_REV, intBuf);
offset += lsize;
lw /= 2;
lh /= 2;
px /= 2;
py /= 2;
}
intBuf.clear();
}
public static void updateSubTex1(int[] src, int width, int height, int posX, int posY) {
int level;
int cw;
int ch;
int cx;
int cy;
for (level = 0, cw = width, ch = height, cx = posX, cy = posY;
cw > 0 && ch > 0;
++level, cw /= 2, ch /= 2, cx /= 2, cy /= 2) {
GL11.glCopyTexSubImage2D(GL11.GL_TEXTURE_2D, level, cx, cy, 0, 0, cw, ch);
}
}
/* updateSubImage for single Texture with mipmap */
public static void updateSubImage1(int[][] src, int width, int height, int posX, int posY, int page, int color) {
int size = width * height;
IntBuffer intBuf = getIntBuffer(size);
int numLevel = src.length;
for (int level = 0, // offset=0,
lw = width,
lh = height,
px = posX,
py = posY;
lw > 0 && lh > 0 && level < numLevel;
++level) {
int lsize = lw * lh;
intBuf.clear();
intBuf.put(src[level], 0 /*offset*/, lsize).position(0).limit(lsize);
GL11.glTexSubImage2D(
GL11.GL_TEXTURE_2D, level, px, py, lw, lh, GL12.GL_BGRA, GL12.GL_UNSIGNED_INT_8_8_8_8_REV, intBuf);
// offset += lsize;
lw /= 2;
lh /= 2;
px /= 2;
py /= 2;
}
intBuf.clear();
}
public static void setupTextureMipmap(TextureMap tex) {
/*
MultiTexID multiTex = tex.getMultiTexID();
GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.norm);
GL30.glGenerateMipmap(GL11.GL_TEXTURE_2D);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.spec);
GL30.glGenerateMipmap(GL11.GL_TEXTURE_2D);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.base);
GL30.glGenerateMipmap(GL11.GL_TEXTURE_2D);
*/
}
public static void updateDynamicTexture(int texID, int[] src, int width, int height, DynamicTexture tex) {
MultiTexID multiTex = tex.getMultiTexID();
GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.norm);
updateSubImage1(src, width, height, 0, 0, 1, defNormTexColor);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.spec);
updateSubImage1(src, width, height, 0, 0, 2, defSpecTexColor);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.base);
updateSubImage1(src, width, height, 0, 0, 0, defBaseTexColor);
}
public static void updateSubImage(
int[] src, int width, int height, int posX, int posY, boolean linear, boolean clamp) {
if (updatingTex != null) {
GL11.glBindTexture(GL11.GL_TEXTURE_2D, updatingTex.norm);
updateSubImage1(src, width, height, posX, posY, 1, defNormTexColor);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, updatingTex.spec);
updateSubImage1(src, width, height, posX, posY, 2, defSpecTexColor);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, updatingTex.base);
}
updateSubImage1(src, width, height, posX, posY, 0, defBaseTexColor);
}
// not used
public static void updateAnimationTextureMap(TextureMap tex, List tasList) {
Iterator<TextureAtlasSprite> iterator;
MultiTexID multiTex = tex.getMultiTexID();
GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.norm);
for (iterator = tasList.iterator(); iterator.hasNext(); ) {
TextureAtlasSprite tas = iterator.next();
tas.updateAnimation();
}
GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.norm);
for (iterator = tasList.iterator(); iterator.hasNext(); ) {
TextureAtlasSprite tas = iterator.next();
tas.updateAnimation();
}
GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.norm);
for (iterator = tasList.iterator(); iterator.hasNext(); ) {
TextureAtlasSprite tas = iterator.next();
tas.updateAnimation();
}
}
public static void setupTexture(
MultiTexID multiTex, int[] src, int width, int height, boolean linear, boolean clamp) {
int mmfilter = linear ? GL11.GL_LINEAR : GL11.GL_NEAREST;
int wraptype = clamp ? GL11.GL_CLAMP : GL11.GL_REPEAT;
int size = width * height;
IntBuffer intBuf = getIntBuffer(size);
//
intBuf.clear();
intBuf.put(src, 0, size).position(0).limit(size);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.base);
GL11.glTexImage2D(
GL11.GL_TEXTURE_2D,
0,
GL11.GL_RGBA,
width,
height,
0,
GL12.GL_BGRA,
GL12.GL_UNSIGNED_INT_8_8_8_8_REV,
intBuf);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, mmfilter);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, mmfilter);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, wraptype);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, wraptype);
//
intBuf.put(src, size, size).position(0).limit(size);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.norm);
GL11.glTexImage2D(
GL11.GL_TEXTURE_2D,
0,
GL11.GL_RGBA,
width,
height,
0,
GL12.GL_BGRA,
GL12.GL_UNSIGNED_INT_8_8_8_8_REV,
intBuf);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, mmfilter);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, mmfilter);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, wraptype);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, wraptype);
//
intBuf.put(src, size * 2, size).position(0).limit(size);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.spec);
GL11.glTexImage2D(
GL11.GL_TEXTURE_2D,
0,
GL11.GL_RGBA,
width,
height,
0,
GL12.GL_BGRA,
GL12.GL_UNSIGNED_INT_8_8_8_8_REV,
intBuf);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, mmfilter);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, mmfilter);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, wraptype);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, wraptype);
//
GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.base);
}
/* currently not used */
public static void updateSubImage(
MultiTexID multiTex, int[] src, int width, int height, int posX, int posY, boolean linear, boolean clamp) {
int size = width * height;
IntBuffer intBuf = getIntBuffer(size);
//
intBuf.clear();
intBuf.put(src, 0, size);
intBuf.position(0).limit(size);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.base);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_REPEAT);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_REPEAT);
GL11.glTexSubImage2D(
GL11.GL_TEXTURE_2D,
0,
posX,
posY,
width,
height,
GL12.GL_BGRA,
GL12.GL_UNSIGNED_INT_8_8_8_8_REV,
intBuf);
if (src.length == size * 3) {
intBuf.clear();
intBuf.put(src, size, size).position(0);
intBuf.position(0).limit(size);
}
GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.norm);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_REPEAT);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_REPEAT);
GL11.glTexSubImage2D(
GL11.GL_TEXTURE_2D,
0,
posX,
posY,
width,
height,
GL12.GL_BGRA,
GL12.GL_UNSIGNED_INT_8_8_8_8_REV,
intBuf);
if (src.length == size * 3) {
intBuf.clear();
intBuf.put(src, size * 2, size);
intBuf.position(0).limit(size);
}
GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.spec);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_REPEAT);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_REPEAT);
GL11.glTexSubImage2D(
GL11.GL_TEXTURE_2D,
0,
posX,
posY,
width,
height,
GL12.GL_BGRA,
GL12.GL_UNSIGNED_INT_8_8_8_8_REV,
intBuf);
GL13.glActiveTexture(GL13.GL_TEXTURE0);
}
public static ResourceLocation getNSMapLocation(ResourceLocation location, String mapName) {
String basename = location.getResourcePath();
String[] basenameParts = basename.split(".png");
String basenameNoFileType = basenameParts[0];
return new ResourceLocation(location.getResourceDomain(), basenameNoFileType + "_" + mapName + ".png");
}
public static void loadNSMap(
IResourceManager manager, ResourceLocation location, int width, int height, int[] aint) {
if (Shaders.configNormalMap)
ShadersTex.loadNSMap1(
manager, getNSMapLocation(location, "n"), width, height, aint, width * height, defNormTexColor);
if (Shaders.configSpecularMap)
ShadersTex.loadNSMap1(
manager, getNSMapLocation(location, "s"), width, height, aint, width * height * 2, defSpecTexColor);
}
public static void loadNSMap1(
IResourceManager manager,
ResourceLocation location,
int width,
int height,
int[] aint,
int offset,
int defaultColor) {
boolean good = false;
try {
IResource res = manager.getResource(location);
BufferedImage bufferedimage = ImageIO.read(res.getInputStream());
if (bufferedimage.getWidth() == width && bufferedimage.getHeight() == height) {
bufferedimage.getRGB(0, 0, width, height, aint, offset, width);
good = true;
}
} catch (IOException ex) {
}
if (!good) {
java.util.Arrays.fill(aint, offset, offset + width * height, defaultColor);
}
}
/** init and upload from BufferedImage */
/* Replacement for TextureUtil.func_110989_a call in SimpleTexture.func_110551_a.
Keep par0...par5 the same as func_110989_a for easy patching.
More parameters added for reading N-S-Map. */
public static int loadSimpleTexture(
int textureID,
BufferedImage bufferedimage,
boolean linear,
boolean clamp,
IResourceManager resourceManager,
ResourceLocation location,
MultiTexID multiTex) {
int width = bufferedimage.getWidth();
int height = bufferedimage.getHeight();
int size = width * height;
int[] aint = getIntArray(size * 3);
bufferedimage.getRGB(0, 0, width, height, aint, 0, width);
loadNSMap(resourceManager, location, width, height, aint);
setupTexture(multiTex, aint, width, height, linear, clamp);
return textureID;
}
public static void mergeImage(int[] aint, int dstoff, int srcoff, int size) {}
public static int blendColor(int color1, int color2, int factor1) {
int factor2 = 255 - factor1;
return (((((color1 >>> 24) & 255) * factor1 + ((color2 >>> 24) & 255) * factor2) / 255) << 24)
| (((((color1 >>> 16) & 255) * factor1 + ((color2 >>> 16) & 255) * factor2) / 255) << 16)
| (((((color1 >>> 8) & 255) * factor1 + ((color2 >>> 8) & 255) * factor2) / 255) << 8)
| (((((color1 >>> 0) & 255) * factor1 + ((color2 >>> 0) & 255) * factor2) / 255) << 0);
}
public static void loadLayeredTexture(LayeredTexture tex, IResourceManager manager, List list) {
int width = 0;
int height = 0;
int size = 0;
int[] image = null;
Iterator<String> iterator;
for (iterator = list.iterator(); iterator.hasNext(); ) {
String s = iterator.next();
if (s != null) {
try {
ResourceLocation location = new ResourceLocation(s);
InputStream inputstream = manager.getResource(location).getInputStream();
BufferedImage bufimg = ImageIO.read(inputstream);
if (size == 0) {
width = bufimg.getWidth();
height = bufimg.getHeight();
size = width * height;
image = createAIntImage(size, 0x00000000);
}
int[] aint = getIntArray(size * 3);
bufimg.getRGB(0, 0, width, height, aint, 0, width);
loadNSMap(manager, location, width, height, aint);
// merge
for (int i = 0; i < size; ++i) {
int alpha = (aint[i] >>> 24) & 255;
image[size * 0 + i] = blendColor(aint[size * 0 + i], image[size * 0 + i], alpha);
image[size * 1 + i] = blendColor(aint[size * 1 + i], image[size * 1 + i], alpha);
image[size * 2 + i] = blendColor(aint[size * 2 + i], image[size * 2 + i], alpha);
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
// init and upload
setupTexture(tex.getMultiTexID(), image, width, height, false, false);
}
/* update block texture filter +/- items texture */
static void updateTextureMinMagFilter() {
TextureManager texman = Minecraft.getMinecraft().getTextureManager();
ITextureObject texObj = texman.getTexture(TextureMap.locationBlocksTexture);
if (texObj != null) {
MultiTexID multiTex = texObj.getMultiTexID();
// base texture
GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.base);
GL11.glTexParameteri(
GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, Shaders.texMinFilValue[Shaders.configTexMinFilB]);
GL11.glTexParameteri(
GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, Shaders.texMagFilValue[Shaders.configTexMagFilB]);
// norm texture
GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.norm);
GL11.glTexParameteri(
GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, Shaders.texMinFilValue[Shaders.configTexMinFilN]);
GL11.glTexParameteri(
GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, Shaders.texMagFilValue[Shaders.configTexMagFilN]);
// spec texture
GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.spec);
GL11.glTexParameteri(
GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, Shaders.texMinFilValue[Shaders.configTexMinFilS]);
GL11.glTexParameteri(
GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, Shaders.texMagFilValue[Shaders.configTexMagFilS]);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);
}
}
static IResourceManager resManager = null;
static ResourceLocation resLocation = null;
static int imageSize = 0;
public static IResource loadResource(IResourceManager manager, ResourceLocation location) throws IOException {
resManager = manager;
resLocation = location;
return manager.getResource(location);
}
public static int[] loadAtlasSprite(
BufferedImage bufferedimage, int startX, int startY, int w, int h, int[] aint, int offset, int scansize) {
imageSize = w * h;
bufferedimage.getRGB(startX, startY, w, h, aint, offset, scansize);
loadNSMap(resManager, resLocation, w, h, aint);
return aint;
}
public static int[] extractFrame(int[] src, int width, int height, int frameIndex) {
int srcSize = imageSize;
int frameSize = width * height;
int[] dst = new int[frameSize * 3];
int srcPos = frameSize * frameIndex;
int dstPos = 0;
System.arraycopy(src, srcPos, dst, dstPos, frameSize);
srcPos += srcSize;
dstPos += frameSize;
System.arraycopy(src, srcPos, dst, dstPos, frameSize);
srcPos += srcSize;
dstPos += frameSize;
System.arraycopy(src, srcPos, dst, dstPos, frameSize);
return dst;
}
public static void fixTransparentColor(TextureAtlasSprite tas, int[] aint) {}
}
@@ -0,0 +1,577 @@
package com.gtnewhorizons.angelica.client.font;
import com.gtnewhorizons.angelica.compat.lwjgl.CompatMemoryUtil;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.mixins.interfaces.FontRendererAccessor;
import it.unimi.dsi.fastutil.chars.Char2ShortOpenHashMap;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import jss.util.RandomXoshiro256StarStar;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.util.MathHelper;
import net.minecraft.util.ResourceLocation;
import org.lwjgl.BufferUtils;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Objects;
import static org.lwjgl.opengl.GL11.*;
/**
* A batching replacement for {@code FontRenderer}
*
* @author eigenraven
*/
public class BatchingFontRenderer {
/** The underlying FontRenderer object that's being accelerated */
protected FontRenderer underlying;
/** Cached locations for each unicode page atlas */
private final ResourceLocation[] unicodePageLocations;
/** Array of width of all the characters in default.png */
protected int[] charWidth = new int[256];
/** Array of the start/end column (in upper/lower nibble) for every glyph in the /font directory. */
protected byte[] glyphWidth;
/**
* Array of RGB triplets defining the 16 standard chat colors followed by 16 darker version of the same colors for
* drop shadows.
*/
private int[] colorCode;
/** Location of the primary font atlas to bind. */
protected final ResourceLocation locationFontTexture;
/** The RenderEngine used to load and setup glyph textures. */
private final TextureManager renderEngine;
private final RandomXoshiro256StarStar fontRandom = new RandomXoshiro256StarStar();
/** The full list of characters present in the default Minecraft font, excluding the Unicode font */
@SuppressWarnings("UnnecessaryUnicodeEscape")
private static final String MCFONT_CHARS = "\u00c0\u00c1\u00c2\u00c8\u00ca\u00cb\u00cd\u00d3\u00d4\u00d5\u00da\u00df\u00e3\u00f5\u011f\u0130\u0131\u0152\u0153\u015e\u015f\u0174\u0175\u017e\u0207\u0000\u0000\u0000\u0000\u0000\u0000\u0000 !\"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u0000\u00c7\u00fc\u00e9\u00e2\u00e4\u00e0\u00e5\u00e7\u00ea\u00eb\u00e8\u00ef\u00ee\u00ec\u00c4\u00c5\u00c9\u00e6\u00c6\u00f4\u00f6\u00f2\u00fb\u00f9\u00ff\u00d6\u00dc\u00f8\u00a3\u00d8\u00d7\u0192\u00e1\u00ed\u00f3\u00fa\u00f1\u00d1\u00aa\u00ba\u00bf\u00ae\u00ac\u00bd\u00bc\u00a1\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u255e\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256b\u256a\u2518\u250c\u2588\u2584\u258c\u2590\u2580\u03b1\u03b2\u0393\u03c0\u03a3\u03c3\u03bc\u03c4\u03a6\u0398\u03a9\u03b4\u221e\u2205\u2208\u2229\u2261\u00b1\u2265\u2264\u2320\u2321\u00f7\u2248\u00b0\u2219\u00b7\u221a\u207f\u00b2\u25a0\u0000";
private static final short[] MCFONT_ASCII_LUT = new short[512];
private static final Char2ShortOpenHashMap MCFONT_UNI_LUT = new Char2ShortOpenHashMap();
static {
Arrays.fill(MCFONT_ASCII_LUT, (short) -1);
for (short i = 0; i < MCFONT_CHARS.length(); i++) {
char ch = MCFONT_CHARS.charAt(i);
if (ch < MCFONT_ASCII_LUT.length) {
MCFONT_ASCII_LUT[ch] = i;
} else {
MCFONT_UNI_LUT.put(ch, i);
}
}
}
public static int lookupMcFontPosition(char ch) {
if (ch < MCFONT_ASCII_LUT.length) {
return MCFONT_ASCII_LUT[ch];
} else {
return MCFONT_UNI_LUT.getOrDefault(ch, (short) -1);
}
}
public BatchingFontRenderer(FontRenderer underlying, ResourceLocation[] unicodePageLocations, int[] charWidth,
byte[] glyphWidth, int[] colorCode, ResourceLocation locationFontTexture, TextureManager renderEngine) {
this.underlying = underlying;
this.unicodePageLocations = unicodePageLocations;
this.charWidth = charWidth;
this.glyphWidth = glyphWidth;
this.colorCode = colorCode;
this.locationFontTexture = locationFontTexture;
this.renderEngine = renderEngine;
for (int i = 0; i < 64; i++) {
batchCommandPool.add(new FontDrawCmd());
}
}
// === Batched rendering
private int batchDepth = 0;
private int vtxWriterIndex = 0;
private int idxWriterIndex = 0;
private static final int INITIAL_BATCH_SIZE = 256;
private static final ResourceLocation DUMMY_RESOURCE_LOCATION = new ResourceLocation("angelica$dummy",
"this is invalid!");
private FloatBuffer batchVtxPositions = BufferUtils.createFloatBuffer(INITIAL_BATCH_SIZE * 2);
private ByteBuffer batchVtxColors = BufferUtils.createByteBuffer(INITIAL_BATCH_SIZE * 4);
private FloatBuffer batchVtxTexCoords = BufferUtils.createFloatBuffer(INITIAL_BATCH_SIZE * 2);
private IntBuffer batchIndices = BufferUtils.createIntBuffer(INITIAL_BATCH_SIZE / 2 * 3);
private final ObjectArrayList<FontDrawCmd> batchCommands = ObjectArrayList.wrap(new FontDrawCmd[64], 0);
private final ObjectArrayList<FontDrawCmd> batchCommandPool = ObjectArrayList.wrap(new FontDrawCmd[64], 0);
/** */
private void pushVtx(float x, float y, int rgba, float u, float v) {
final int oldCap = batchVtxPositions.capacity() / 2;
if (vtxWriterIndex >= oldCap) {
final int newCap = oldCap * 2;
batchVtxPositions = CompatMemoryUtil.memReallocDirect(batchVtxPositions, newCap * 2);
batchVtxColors = CompatMemoryUtil.memReallocDirect(batchVtxColors, newCap * 4);
batchVtxTexCoords = CompatMemoryUtil.memReallocDirect(batchVtxTexCoords, newCap * 2);
final int oldIdxCap = batchIndices.capacity();
final int newIdxCap = oldIdxCap * 2;
batchIndices = CompatMemoryUtil.memReallocDirect(batchIndices, newIdxCap);
}
final int idx = vtxWriterIndex;
final int idx2 = idx * 2;
final int idx4 = idx * 4;
batchVtxPositions.put(idx2, x);
batchVtxPositions.put(idx2 + 1, y);
// 0xAARRGGBB
batchVtxColors.put(idx4, (byte) ((rgba >> 16) & 0xFF));
batchVtxColors.put(idx4 + 1, (byte) ((rgba >> 8) & 0xFF));
batchVtxColors.put(idx4 + 2, (byte) (rgba & 0xFF));
batchVtxColors.put(idx4 + 3, (byte) ((rgba >> 24) & 0xFF));
batchVtxTexCoords.put(idx2, u);
batchVtxTexCoords.put(idx2 + 1, v);
vtxWriterIndex++;
}
private void pushUntexRect(float x, float y, float w, float h, int rgba) {
final int vtxId = vtxWriterIndex;
pushVtx(x, y, rgba, 0, 0);
pushVtx(x, y + h, rgba, 0, 0);
pushVtx(x + w, y, rgba, 0, 0);
pushVtx(x + w, y + h, rgba, 0, 0);
pushQuadIdx(vtxId);
}
private int pushQuadIdx(int startV) {
final int idx = idxWriterIndex;
batchIndices.put(idx, startV);
batchIndices.put(idx + 1, startV + 1);
batchIndices.put(idx + 2, startV + 2);
//
batchIndices.put(idx + 3, startV + 2);
batchIndices.put(idx + 4, startV + 1);
batchIndices.put(idx + 5, startV + 3);
idxWriterIndex += 6;
return idx;
}
private void pushDrawCmd(int startIdx, int idxCount, ResourceLocation texture) {
if (!batchCommands.isEmpty()) {
final FontDrawCmd lastCmd = batchCommands.get(batchCommands.size() - 1);
final int prevEndVtx = lastCmd.startVtx + lastCmd.idxCount;
if (prevEndVtx == startIdx && lastCmd.texture == texture) {
// Coalesce into one
lastCmd.idxCount += idxCount;
return;
}
}
if (batchCommandPool.isEmpty()) {
for (int i = 0; i < 64; i++) {
batchCommandPool.add(new FontDrawCmd());
}
}
final FontDrawCmd cmd = batchCommandPool.pop();
cmd.reset(startIdx, idxCount, texture);
batchCommands.add(cmd);
}
private static final class FontDrawCmd {
public int startVtx;
public int idxCount;
public ResourceLocation texture;
public void reset(int startVtx, int vtxCount, ResourceLocation texture) {
this.startVtx = startVtx;
this.idxCount = vtxCount;
this.texture = texture;
}
@Override
public boolean equals(Object obj) {
if (obj == this) return true;
if (obj == null || obj.getClass() != this.getClass()) return false;
var that = (FontDrawCmd) obj;
return this.startVtx == that.startVtx && this.idxCount == that.idxCount && Objects.equals(this.texture,
that.texture);
}
@Override
public int hashCode() {
return Objects.hash(startVtx, idxCount, texture);
}
@Override
public String toString() {
return "FontDrawCmd["
+ "startVtx="
+ startVtx
+ ", "
+ "vtxCount="
+ idxCount
+ ", "
+ "texture="
+ texture
+ ']';
}
public static final Comparator<FontDrawCmd> DRAW_ORDER_COMPARATOR = Comparator.comparing((FontDrawCmd fdc) -> fdc.texture,
Comparator.nullsLast(Comparator.comparing(ResourceLocation::getResourceDomain)
.thenComparing(ResourceLocation::getResourcePath))).thenComparing(fdc -> fdc.startVtx);
}
/**
* Starts a new batch of font rendering operations. Can be called from within another batch with a matching end, to
* allow for easier optimizing of blocks of font rendering code.
*/
public void beginBatch() {
if (batchDepth == Integer.MAX_VALUE) {
throw new StackOverflowError("More than Integer.MAX_VALUE nested font rendering batch operations");
}
batchDepth++;
}
public void endBatch() {
if (batchDepth <= 0) {
batchDepth = 0;
return;
}
batchDepth--;
if (batchDepth == 0) {
// We finished any nested batches
flushBatch();
}
}
private void flushBatch() {
// Sort&Draw
batchCommands.sort(FontDrawCmd.DRAW_ORDER_COMPARATOR);
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);
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);
// Use plain for loop to avoid allocations
final FontDrawCmd[] cmdsData = batchCommands.elements();
final int cmdsSize = batchCommands.size();
for (int i = 0; i < cmdsSize; i++) {
final FontDrawCmd cmd = cmdsData[i];
if (!Objects.equals(lastTexture, cmd.texture)) {
if (lastTexture == null) {
GLStateManager.enableTexture();
} else if (cmd.texture == null) {
GLStateManager.disableTexture();
}
if (cmd.texture != null) {
((FontRendererAccessor) (Object) underlying).angelica$bindTexture(cmd.texture);
}
lastTexture = cmd.texture;
}
batchIndices.limit(cmd.startVtx + cmd.idxCount);
batchIndices.position(cmd.startVtx);
glDrawElements(GL_TRIANGLES, batchIndices);
}
glPopClientAttrib();
// Clear for the next batch
batchCommandPool.addAll(batchCommands);
batchCommands.clear();
vtxWriterIndex = 0;
idxWriterIndex = 0;
batchIndices.limit(batchIndices.capacity());
batchIndices.position(0);
}
// === Actual text mesh generation
public static boolean charInRange(char what, char fromInclusive, char toInclusive) {
return (what >= fromInclusive) && (what <= toInclusive);
}
private ResourceLocation getUnicodePageLocation(int page) {
final ResourceLocation lookup = unicodePageLocations[page];
if (lookup == null) {
final ResourceLocation rl = new ResourceLocation(String.format(
"textures/font/unicode_page_%02x.png",
page));
unicodePageLocations[page] = rl;
return rl;
} else {
return lookup;
}
}
private static final char FORMATTING_CHAR = 167; // §
public float drawString(final float anchorX, final float anchorY, final int color, final boolean enableShadow,
final boolean unicodeFlag, final CharSequence string, int stringOffset, int stringLength) {
// noinspection SizeReplaceableByIsEmpty
if (string == null || string.length() == 0) {
return 0.0f;
}
final int shadowColor = (color & 0xfcfcfc) >> 2 | color & 0xff000000;
this.beginBatch();
float curX = anchorX;
try {
final int totalStringLength = string.length();
stringOffset = MathHelper.clamp_int(stringOffset, 0, totalStringLength);
stringLength = MathHelper.clamp_int(stringLength, 0, totalStringLength - stringOffset);
if (stringLength <= 0) {
return 0;
}
final int stringEnd = stringOffset + stringLength;
int curColor = color;
int curShadowColor = shadowColor;
boolean curItalic = false;
boolean curRandom = false;
boolean curBold = false;
boolean curStrikethrough = false;
boolean curUnderline = false;
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);
float strikethroughStartX = 0.0f;
float strikethroughEndX = 0.0f;
for (int charIdx = stringOffset; charIdx < stringEnd; charIdx++) {
char chr = string.charAt(charIdx);
if (chr == FORMATTING_CHAR && (charIdx + 1) < stringEnd) {
final char fmtCode = Character.toLowerCase(string.charAt(charIdx + 1));
charIdx++;
if (curUnderline && underlineStartX != underlineEndX) {
final int ulIdx = idxWriterIndex;
pushUntexRect(underlineStartX, underlineY, underlineEndX - underlineStartX, 1.0f, curColor);
pushDrawCmd(ulIdx, 6, null);
underlineStartX = underlineEndX;
}
if (curStrikethrough && strikethroughStartX != strikethroughEndX) {
final int ulIdx = idxWriterIndex;
pushUntexRect(
strikethroughStartX,
strikethroughY,
strikethroughEndX - strikethroughStartX,
1.0f,
curColor);
pushDrawCmd(ulIdx, 6, null);
strikethroughStartX = strikethroughEndX;
}
final boolean is09 = charInRange(fmtCode, '0', '9');
final boolean isAF = charInRange(fmtCode, 'a', 'f');
if (is09 || isAF) {
curRandom = false;
curBold = false;
curStrikethrough = false;
curUnderline = false;
curItalic = false;
final int colorIdx = is09 ? (fmtCode - '0') : (fmtCode - 'a' + 10);
final int rgb = this.colorCode[colorIdx];
curColor = (curColor & 0xFF000000) | (rgb & 0x00FFFFFF);
final int shadowRgb = this.colorCode[colorIdx + 16];
curShadowColor = (curShadowColor & 0xFF000000) | (shadowRgb & 0x00FFFFFF);
} else if (fmtCode == 'k') {
curRandom = true;
} else if (fmtCode == 'l') {
curBold = true;
} else if (fmtCode == 'm') {
curStrikethrough = true;
strikethroughStartX = curX - 1.0f;
strikethroughEndX = strikethroughStartX;
} else if (fmtCode == 'n') {
curUnderline = true;
underlineStartX = curX - 1.0f;
underlineEndX = underlineStartX;
} else if (fmtCode == 'o') {
curItalic = true;
} else if (fmtCode == 'r') {
curRandom = false;
curBold = false;
curStrikethrough = false;
curUnderline = false;
curItalic = false;
curColor = color;
curShadowColor = shadowColor;
}
continue;
}
int lutIndex = lookupMcFontPosition(chr);
if (curRandom && lutIndex != -1) {
int randomReplacementIndex;
do {
randomReplacementIndex = fontRandom.nextInt(this.charWidth.length);
} while (this.charWidth[lutIndex] != this.charWidth[randomReplacementIndex]);
lutIndex = randomReplacementIndex;
chr = MCFONT_CHARS.charAt(lutIndex);
}
final float shadowOffset = unicodeFlag ? 0.5F : 1.0F;
// Check ASCII space, NBSP, NNBSP
if (chr == ' ' || chr == '\u00A0' || chr == '\u202F') {
curX += 4;
continue;
}
final float uStart;
final float vStart;
final float xAdvance;
final float glyphW;
final float uSz;
final float vSz;
final float itOff = curItalic ? 1.0F : 0.0F; // italic offset
final ResourceLocation texture;
if (lutIndex == -1 || unicodeFlag) {
if (glyphWidth[chr] == 0) {
continue;
}
// Draw unicode char
final int uniPage = chr / 256;
texture = getUnicodePageLocation(uniPage);
final int startColumn = this.glyphWidth[chr] >>> 4;
final int endColumn = this.glyphWidth[chr] & 15;
final float startColumnF = (float) startColumn;
final float endColumnF = (float) (endColumn + 1);
uStart = ((float) (chr % 16 * 16) + startColumnF) / 256.0f;
vStart = ((float) ((chr & 255) / 16 * 16)) / 256.0f;
final float chrWidth = endColumnF - startColumnF - 0.02F;
glyphW = chrWidth / 2.0f + 1.0f;
xAdvance = (endColumnF - startColumnF) / 2.0F + 1.0F;
uSz = chrWidth / 256.0f;
vSz = 15.98f / 256.0f;
} else {
// Draw "ASCII" char
uStart = ((lutIndex % 16) * 8) / 128.0F;
vStart = (float) ((lutIndex / 16) * 8) / 128.0F;
xAdvance = this.charWidth[lutIndex];
if (xAdvance == 0) {
continue;
}
glyphW = xAdvance - 0.01F;
uSz = (glyphW - 1.0F) / 128.0F;
vSz = 7.99F / 128.0F;
texture = locationFontTexture;
}
final int vtxId = vtxWriterIndex;
final int idxId = idxWriterIndex;
int vtxCount = 0;
if (enableShadow) {
pushVtx(curX + itOff + shadowOffset, anchorY + shadowOffset, curShadowColor, uStart, vStart);
pushVtx(
curX - itOff + shadowOffset,
anchorY + 7.99F + shadowOffset,
curShadowColor,
uStart,
vStart + vSz);
pushVtx(curX + glyphW - 1.0F + itOff + shadowOffset,
anchorY + shadowOffset,
curShadowColor,
uStart + uSz,
vStart);
pushVtx(curX + glyphW - 1.0F - itOff + shadowOffset,
anchorY + 7.99F + shadowOffset,
curShadowColor,
uStart + uSz,
vStart + vSz);
pushQuadIdx(vtxId + vtxCount);
vtxCount += 4;
if (curBold) {
final float shadowOffset2 = 2.0f * shadowOffset;
pushVtx(curX + itOff + shadowOffset2, anchorY + shadowOffset, curShadowColor, uStart, vStart);
pushVtx(
curX - itOff + shadowOffset2,
anchorY + 7.99F + shadowOffset,
curShadowColor,
uStart,
vStart + vSz);
pushVtx(
curX + glyphW - 1.0F + itOff + shadowOffset2,
anchorY + shadowOffset,
curShadowColor,
uStart + uSz,
vStart);
pushVtx(curX + glyphW - 1.0F - itOff + shadowOffset2,
anchorY + 7.99F + shadowOffset,
curShadowColor,
uStart + uSz,
vStart + vSz);
pushQuadIdx(vtxId + vtxCount);
vtxCount += 4;
}
}
pushVtx(curX + itOff, anchorY, curColor, uStart, vStart);
pushVtx(curX - itOff, anchorY + 7.99F, curColor, uStart, vStart + vSz);
pushVtx(curX + glyphW - 1.0F + itOff, anchorY, curColor, uStart + uSz, vStart);
pushVtx(curX + glyphW - 1.0F - itOff, anchorY + 7.99F, curColor, uStart + uSz, vStart + vSz);
pushQuadIdx(vtxId + vtxCount);
vtxCount += 4;
if (curBold) {
pushVtx(shadowOffset + curX + itOff, anchorY, curColor, uStart, vStart);
pushVtx(shadowOffset + curX - itOff, anchorY + 7.99F, curColor, uStart, vStart + vSz);
pushVtx(shadowOffset + curX + glyphW - 1.0F + itOff, anchorY, curColor, uStart + uSz, vStart);
pushVtx(shadowOffset + curX + glyphW - 1.0F - itOff,
anchorY + 7.99F,
curColor,
uStart + uSz,
vStart + vSz);
pushQuadIdx(vtxId + vtxCount);
vtxCount += 4;
}
pushDrawCmd(idxId, vtxCount / 2 * 3, texture);
curX += xAdvance + (curBold ? shadowOffset : 0.0f);
underlineEndX = curX;
strikethroughEndX = curX;
}
if (curUnderline && underlineStartX != underlineEndX) {
final int ulIdx = idxWriterIndex;
pushUntexRect(underlineStartX, underlineY, underlineEndX - underlineStartX, 1.0f, curColor);
pushDrawCmd(ulIdx, 6, null);
}
if (curStrikethrough && strikethroughStartX != strikethroughEndX) {
final int ulIdx = idxWriterIndex;
pushUntexRect(
strikethroughStartX,
strikethroughY,
strikethroughEndX - strikethroughStartX,
1.0f,
curColor);
pushDrawCmd(ulIdx, 6, null);
}
} finally {
this.endBatch();
}
return curX;
}
}
@@ -0,0 +1,69 @@
package com.gtnewhorizons.angelica.compat;
import com.gtnewhorizons.angelica.AngelicaMod;
import com.gtnewhorizons.angelica.mixins.early.sodium.MixinExtendedBlockStorage;
import com.gtnewhorizons.angelica.mixins.interfaces.ExtendedNibbleArray;
import com.gtnewhorizons.neid.mixins.interfaces.IExtendedBlockStorageMixin;
import net.minecraft.world.chunk.NibbleArray;
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
import ru.fewizz.idextender.Hooks;
public class ExtendedBlockStorageExt extends ExtendedBlockStorage {
public boolean hasSky;
public ExtendedBlockStorageExt(int yBase, boolean hasSky) {
super(yBase, hasSky);
this.hasSky = hasSky;
}
public ExtendedBlockStorageExt(ExtendedBlockStorage storage) {
super(((MixinExtendedBlockStorage) storage).getYBase(), storage.getSkylightArray() != null);
int arrayLen;
if (AngelicaMod.isNEIDLoaded){
final short[] block16BArray = ((IExtendedBlockStorageMixin)(Object)this).getBlock16BArray();
System.arraycopy(((IExtendedBlockStorageMixin)(Object)storage).getBlock16BArray(), 0, block16BArray, 0, block16BArray.length);
if(storage.getBlockMSBArray() != null) {
this.setBlockMSBArray(new NibbleArray(block16BArray.length, 4));
copyNibbleArray((ExtendedNibbleArray) storage.getBlockMSBArray(), (ExtendedNibbleArray) this.getBlockMSBArray());
}
arrayLen = block16BArray.length;
}
else if (AngelicaMod.isOldNEIDLoaded){
final short[] blockLSBArray = Hooks.get(this);
System.arraycopy(Hooks.get(storage), 0, blockLSBArray, 0, blockLSBArray.length);
// getBlockMSBArray is nuked in asm version
arrayLen = blockLSBArray.length;
}
else {
final byte[] blockLSBArray = this.getBlockLSBArray();
System.arraycopy(storage.getBlockLSBArray(), 0, blockLSBArray, 0, blockLSBArray.length);
if(storage.getBlockMSBArray() != null) {
this.setBlockMSBArray(new NibbleArray(blockLSBArray.length, 4));
copyNibbleArray((ExtendedNibbleArray) storage.getBlockMSBArray(), (ExtendedNibbleArray) this.getBlockMSBArray());
}
arrayLen = blockLSBArray.length;
}
copyNibbleArray((ExtendedNibbleArray) storage.getMetadataArray(), (ExtendedNibbleArray)this.getMetadataArray());
copyNibbleArray((ExtendedNibbleArray) storage.getBlocklightArray(), (ExtendedNibbleArray)this.getBlocklightArray());
if(storage.getSkylightArray() != null) {
hasSky = true;
if(this.getSkylightArray() == null) {
this.setSkylightArray(new NibbleArray(arrayLen, 4));
}
copyNibbleArray((ExtendedNibbleArray) storage.getSkylightArray(), (ExtendedNibbleArray) this.getSkylightArray());
}
((MixinExtendedBlockStorage) this).setBlockRefCount(((MixinExtendedBlockStorage) storage).getBlockRefCount());
}
private static void copyNibbleArray(ExtendedNibbleArray srcArray, ExtendedNibbleArray dstArray) {
if (srcArray == null || dstArray == null) {
throw new RuntimeException("NibbleArray is null src: " + (srcArray == null) + " dst: " + (dstArray == null));
}
final byte[] data = srcArray.getData();
System.arraycopy(data, 0, dstArray.getData(), 0, data.length);
}
}
@@ -0,0 +1,102 @@
package com.gtnewhorizons.angelica.compat.lwjgl;
import org.lwjgl.BufferUtils;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
public class CompatMemoryUtil {
public static ByteBuffer memReallocDirect(ByteBuffer old, int capacity) {
ByteBuffer newBuf = BufferUtils.createByteBuffer(capacity);
int oldPos = old.position();
old.rewind();
newBuf.put(old);
newBuf.position(Math.min(capacity, oldPos));
return newBuf;
}
public static IntBuffer memReallocDirect(IntBuffer old, int capacity) {
IntBuffer newBuf = BufferUtils.createIntBuffer(capacity);
int oldPos = old.position();
old.rewind();
newBuf.put(old);
newBuf.position(Math.min(capacity, oldPos));
return newBuf;
}
public static FloatBuffer memReallocDirect(FloatBuffer old, int capacity) {
FloatBuffer newBuf = BufferUtils.createFloatBuffer(capacity);
int oldPos = old.position();
old.rewind();
newBuf.put(old);
newBuf.position(Math.min(capacity, oldPos));
return newBuf;
}
/**
* 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>
*/
static final sun.misc.Unsafe UNSAFE;
static {
UNSAFE = getUnsafeInstance();
}
private static sun.misc.Unsafe getUnsafeInstance() {
java.lang.reflect.Field[] fields = sun.misc.Unsafe.class.getDeclaredFields();
/*
Different runtimes use different names for the Unsafe singleton,
so we cannot use .getDeclaredField and we scan instead. For example:
Oracle: theUnsafe
PERC : m_unsafe_instance
Android: THE_ONE
*/
for (java.lang.reflect.Field field : fields) {
if (!field.getType().equals(sun.misc.Unsafe.class)) {
continue;
}
int modifiers = field.getModifiers();
if (!(java.lang.reflect.Modifier.isStatic(modifiers) && java.lang.reflect.Modifier.isFinal(modifiers))) {
continue;
}
try {
field.setAccessible(true);
return (sun.misc.Unsafe)field.get(null);
} catch (Exception ignored) {
}
break;
}
throw new UnsupportedOperationException("LWJGL requires sun.misc.Unsafe to be available.");
}
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); }
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); }
}
@@ -0,0 +1,15 @@
package com.gtnewhorizons.angelica.compat.mojang;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import net.minecraft.client.renderer.texture.AbstractTexture;
import org.lwjgl.opengl.GL11;
public abstract class AutoClosableAbstractTexture extends AbstractTexture implements AutoCloseable {
@Override
public void close() throws Exception {}
// TODO: Is this needed?
public void bind() {
GLStateManager.glBindTexture(GL11.GL_TEXTURE_2D, getGlTextureId());
}
}
@@ -0,0 +1,19 @@
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;
};
}
}
@@ -0,0 +1,99 @@
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 {
}
}
@@ -0,0 +1,35 @@
package com.gtnewhorizons.angelica.compat.mojang;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
public class ByteBufferBackedInputStream extends InputStream {
ByteBuffer buf;
public ByteBufferBackedInputStream(ByteBuffer buf) {
this.buf = buf;
}
public int read() throws IOException {
if (!buf.hasRemaining()) {
return -1;
}
return buf.get() & 0xFF;
}
@Override
public int read(byte @NotNull [] bytes, int off, int len) throws IOException {
if (!buf.hasRemaining()) {
return -1;
}
len = Math.min(len, buf.remaining());
buf.get(bytes, off, len);
return len;
}
}
@@ -0,0 +1,40 @@
package com.gtnewhorizons.angelica.compat.mojang;
import com.gtnewhorizons.angelica.rendering.RenderingState;
import lombok.Getter;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.EntityLivingBase;
import org.joml.Matrix4f;
import org.joml.Vector3d;
import org.joml.Vector4f;
@Getter
public class Camera {
final Vector3d pos = new Vector3d();
final BlockPos.Mutable blockPos = new BlockPos.Mutable();
float pitch;
float yaw;
EntityLivingBase entity;
boolean thirdPerson;
final float partialTicks;
public Camera(EntityLivingBase entity, float partialTicks) {
this.partialTicks = partialTicks;
final Vector4f offset = new Vector4f(); // third person offset
final Matrix4f inverseModelView = new Matrix4f(RenderingState.INSTANCE.getModelViewMatrix()).invert();
inverseModelView.transform(offset);
final double camX = entity.lastTickPosX + (entity.posX - entity.lastTickPosX) * partialTicks + offset.x;
final double camY = entity.lastTickPosY + (entity.posY - entity.lastTickPosY) * partialTicks + offset.y;
final double camZ = entity.lastTickPosZ + (entity.posZ - entity.lastTickPosZ) * partialTicks + offset.z;
this.entity = entity;
pos.set(camX, camY, camZ);
blockPos.set((int)entity.posX, (int)entity.posY, (int)entity.posZ);
pitch = entity.cameraPitch;
yaw = entity.rotationYaw;
thirdPerson = Minecraft.getMinecraft().gameSettings.thirdPersonView == 1;
}
}
@@ -0,0 +1,39 @@
package com.gtnewhorizons.angelica.compat.mojang;
import net.minecraftforge.common.util.ForgeDirection;
import java.util.BitSet;
import java.util.Set;
public class ChunkOcclusionData {
private static final int DIRECTION_COUNT = ForgeDirection.values().length;
private final BitSet visibility;
public ChunkOcclusionData() {
this.visibility = new BitSet(DIRECTION_COUNT * DIRECTION_COUNT);
}
public void addOpenEdgeFaces(Set<ForgeDirection> faces) {
for (ForgeDirection dirFrom : faces) {
for (ForgeDirection dirTo : faces) {
this.setVisibleThrough(dirFrom, dirTo, true);
}
}
for (ForgeDirection direction : faces) {
this.visibility.set(direction.ordinal() * DIRECTION_COUNT + direction.ordinal());
}
}
public void setVisibleThrough(ForgeDirection from, ForgeDirection to, boolean visible) {
this.visibility.set(from.ordinal() + to.ordinal() * DIRECTION_COUNT, visible);
this.visibility.set(to.ordinal() + from.ordinal() * DIRECTION_COUNT, visible);
}
public boolean isVisibleThrough(ForgeDirection from, ForgeDirection to) {
return this.visibility.get(from.ordinal() + to.ordinal() * DIRECTION_COUNT);
}
public void fill(boolean visible) {
this.visibility.set(0, this.visibility.size(), visible);
}
}
@@ -0,0 +1,155 @@
package com.gtnewhorizons.angelica.compat.mojang;
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;
import java.util.EnumSet;
import java.util.Set;
/**
* WARNING: Minecraft 1.16 code rip!!
*/
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 final BitSet closed = new BitSet(4096);
private static final int[] EDGE_POINTS = new int[1352];
static {
int k = 0;
for(int l = 0; l < 16; ++l) {
for(int m = 0; m < 16; ++m) {
for(int n = 0; n < 16; ++n) {
if (l == 0 || l == 15 || m == 0 || m == 15 || n == 0 || n == 15) {
EDGE_POINTS[k++] = pack(l, m, n);
}
}
}
}
}
private int openCount = 4096;
public void markClosed(BlockPos pos) {
this.closed.set(pack(pos), true);
--this.openCount;
}
private static int pack(BlockPos pos) {
return pack(pos.getX() & 15, pos.getY() & 15, pos.getZ() & 15);
}
private static int pack(int x, int y, int z) {
return x << 0 | y << 8 | z << 4;
}
public ChunkOcclusionData build() {
final ChunkOcclusionData lv = new ChunkOcclusionData();
if (4096 - this.openCount < 256) {
lv.fill(true);
} else if (this.openCount == 0) {
lv.fill(false);
} else {
for(int i : EDGE_POINTS) {
if (!this.closed.get(i)) {
lv.addOpenEdgeFaces(this.getOpenFaces(i));
}
}
}
return lv;
}
private Set<ForgeDirection> getOpenFaces(int pos) {
final Set<ForgeDirection> set = EnumSet.noneOf(ForgeDirection.class);
final IntPriorityQueue intPriorityQueue = new IntArrayFIFOQueue();
intPriorityQueue.enqueue(pos);
this.closed.set(pos, true);
while(!intPriorityQueue.isEmpty()) {
final int j = intPriorityQueue.dequeueInt();
this.addEdgeFaces(j, set);
for(ForgeDirection lv : DIRECTIONS) {
final int k = this.offset(j, lv);
if (k >= 0 && !this.closed.get(k)) {
this.closed.set(k, true);
intPriorityQueue.enqueue(k);
}
}
}
return set;
}
private void addEdgeFaces(int pos, Set<ForgeDirection> openFaces) {
final int j = pos >> 0 & 15;
if (j == 0) {
openFaces.add(ForgeDirection.WEST);
} else if (j == 15) {
openFaces.add(ForgeDirection.EAST);
}
final int k = pos >> 8 & 15;
if (k == 0) {
openFaces.add(ForgeDirection.DOWN);
} else if (k == 15) {
openFaces.add(ForgeDirection.UP);
}
final int l = pos >> 4 & 15;
if (l == 0) {
openFaces.add(ForgeDirection.NORTH);
} else if (l == 15) {
openFaces.add(ForgeDirection.SOUTH);
}
}
private int offset(int pos, ForgeDirection arg) {
return switch (arg) {
case DOWN -> {
if ((pos >> 8 & 15) == 0) {
yield -1;
}
yield pos - STEP_Y;
}
case UP -> {
if ((pos >> 8 & 15) == 15) {
yield -1;
}
yield pos + STEP_Y;
}
case NORTH -> {
if ((pos >> 4 & 15) == 0) {
yield -1;
}
yield pos - STEP_Z;
}
case SOUTH -> {
if ((pos >> 4 & 15) == 15) {
yield -1;
}
yield pos + STEP_Z;
}
case WEST -> {
if ((pos >> 0 & 15) == 0) {
yield -1;
}
yield pos - STEP_X;
}
case EAST -> {
if ((pos >> 0 & 15) == 15) {
yield -1;
}
yield pos + STEP_X;
}
default -> -1;
};
}
}
@@ -0,0 +1,57 @@
package com.gtnewhorizons.angelica.compat.mojang;
// See if we can merge/mixin/extend ChunkCoordIntPair?
public class ChunkPos {
public static long INT_MASK = (1L << Integer.SIZE) - 1;
public final int x;
public final int z;
public ChunkPos(int x, int z) {
this.x = x;
this.z = z;
}
public ChunkPos(BlockPos pos) {
this.x = pos.getX() >> 4;
this.z = pos.getZ() >> 4;
}
public ChunkPos(long pos) {
this.x = (int)pos;
this.z = (int)(pos >> 32);
}
public static int getPackedX(long pos) {
return (int)(pos & INT_MASK);
}
public static int getPackedZ(long pos) {
return (int)(pos >>> 32 & INT_MASK);
}
public long toLong() {
return toLong(this.x, this.z);
}
public static long toLong(int x, int z) {
return (long)x & 4294967295L | ((long)z & 4294967295L) << 32;
}
public int hashCode()
{
final int i = 1664525 * this.x + 1013904223;
final int j = 1664525 * (this.z ^ -559038737) + 1013904223;
return i ^ j;
}
public boolean equals(Object object) {
if (this == object) {
return true;
}
if (object instanceof ChunkPos lv) {
return this.x == lv.x && this.z == lv.z;
}
return false;
}
}
@@ -0,0 +1,88 @@
package com.gtnewhorizons.angelica.compat.mojang;
import org.joml.Vector3i;
// See if we can merge/mixin/extend ChunkPosition maybe?
public class ChunkSectionPos extends Vector3i {
public static int getSectionCoord(int coord) {
return coord >> 4;
}
public static int getBlockCoord(int sectionCoord) {
return sectionCoord << 4;
}
private ChunkSectionPos(int x, int y, int z) {
super(x, y, z);
}
public static ChunkSectionPos from(int x, int y, int z) {
return new ChunkSectionPos(x, y, z);
}
public static ChunkSectionPos from(BlockPos pos) {
return new ChunkSectionPos(getSectionCoord(pos.getX()), getSectionCoord(pos.getY()), getSectionCoord(pos.getZ()));
}
public static long asLong(int x, int y, int z) {
long l = 0L;
l |= ((long)x & 4194303L) << 42;
l |= ((long)y & 1048575L) << 0;
l |= ((long)z & 4194303L) << 20;
return l;
}
public static int getLocalCoord(int coord) {
return coord & 15;
}
public static short packLocal(BlockPos pos) {
int i = getLocalCoord(pos.x);
int j = getLocalCoord(pos.y);
int k = getLocalCoord(pos.z);
return (short)(i << 8 | k << 4 | j << 0);
}
public long asLong() {
return asLong(this.x, this.y, this.z);
}
public int getSectionX() {
return this.x;
}
public int getSectionY() {
return this.y;
}
public int getSectionZ() {
return this.z;
}
public int getMinX() {
return this.x << 4;
}
public int getMinY() {
return this.y << 4;
}
public int getMinZ() {
return this.z << 4;
}
public int getMaxX() {
return (this.x << 4) + 15;
}
public int getMaxY() {
return (this.y << 4) + 15;
}
public int getMaxZ() {
return (this.z << 4) + 15;
}
public ChunkPos toChunkPos() {
return new ChunkPos(this.getSectionX(), this.getSectionZ());
}
}
@@ -0,0 +1,27 @@
package com.gtnewhorizons.angelica.compat.mojang;
public class CompatMathHelper {
public static int smallestEncompassingPowerOfTwo(int value) {
int j = value - 1;
j |= j >> 1;
j |= j >> 2;
j |= j >> 4;
j |= j >> 8;
j |= j >> 16;
return j + 1;
}
public static int roundUpToMultiple(int value, int divisor) {
if (divisor == 0) {
return 0;
} else if (value == 0) {
return divisor;
} else {
if (value < 0) {
divisor *= -1;
}
int k = value % divisor;
return k == 0 ? value : value + divisor - k;
}
}
}
@@ -0,0 +1,5 @@
package com.gtnewhorizons.angelica.compat.mojang;
public class Constants {
public static final float DEGREES_TO_RADIANS = (float)Math.PI / 180.0F;
}
@@ -0,0 +1,10 @@
package com.gtnewhorizons.angelica.compat.mojang;
public enum InteractionHand {
MAIN_HAND,
OFF_HAND;
InteractionHand() {
}
}
@@ -0,0 +1,121 @@
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 java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
// TBD
public class NativeImage extends BufferedImage {
@Getter
private final Format format;
@Getter
private final int width;
@Getter
private final int height;
@Getter
private final int size;
public NativeImage(int width, int height, boolean useStb) {
this(NativeImage.Format.RGBA, width, height, useStb);
}
public NativeImage(Format format, int width, int height, boolean useStb) {
super(width, height, BufferedImage.TYPE_INT_ARGB);
this.format = format;
this.width = width;
this.height = height;
this.size = width * height * format.components;
}
public NativeImage(Format format, int width, int height, BufferedImage image) {
super(image.getColorModel(), image.getRaster(), image.isAlphaPremultiplied(), null);
this.format = format;
this.width = width;
this.height = height;
this.size = width * height * format.components;
}
public static NativeImage read(ByteBuffer buf) throws IOException {
return read(new ByteBufferBackedInputStream(buf));
}
public static NativeImage read(InputStream inputStream) throws IOException {
BufferedImage image = ImageIO.read(inputStream);
return new NativeImage(Format.RGBA, image.getWidth(), image.getHeight(), image);
}
public void downloadTexture(int level, boolean bl) {
// this.checkAllocated();
GL11.glPixelStorei(GL11.GL_PACK_ALIGNMENT, format.components);
// GlStateManager._getTexImage(3553, level, format.glFormat, GL11.GL_UNSIGNED_BYTE, this.pixels);
// 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];
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);
}
public void writeToFile(File file) throws IOException{
try {
ImageIO.write(this, "png", file);
} catch(IOException ioexception) {
Iris.logger.info("[TextureDump] Unable to write: ", ioexception);
}
}
public static int combine(int i, int j, int k, int l) {
return (i & 255) << 24 | (j & 255) << 16 | (k & 255) << 8 | (l & 255);
}
public static int getA(int i) {
return i >> 24 & 255;
}
public static int getR(int i) {
return i >> 0 & 255;
}
public static int getG(int i) {
return i >> 8 & 255;
}
public static int getB(int i) {
return i >> 16 & 255;
}
public int getPixelRGBA(int x, int y) {
return getRGB(x, y);
}
public void setPixelRGBA(int x, int y, int rgb) {
setRGB(x, y, rgb);
}
public enum Format {
RGBA(4, GL11.GL_RGBA, BufferedImage.TYPE_INT_ARGB),
RGB(3, GL11.GL_RGB, BufferedImage.TYPE_INT_RGB);
private final int components;
private final int glFormat;
private final int imageType;
Format(int components, int glFormat, int imageType) {
this.components = components;
this.glFormat = glFormat;
this.imageType = imageType;
}
}
}
@@ -0,0 +1,48 @@
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;
public VertexBuffer() {
this.id = GL15.glGenBuffers();
}
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 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);
GL11.glDrawArrays(mode, 0, this.vertexCount);
GL11.glPopMatrix();
}
}
@@ -0,0 +1,107 @@
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;
}
}
}
@@ -0,0 +1,63 @@
package com.gtnewhorizons.angelica.compat.nd;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.ShortBuffer;
public class BufferWriter {
// Adapted from Neodymium
private final ByteBuffer buf;
private final FloatBuffer floatBuffer;
private final ShortBuffer shortBuffer;
private final IntBuffer intBuffer;
public BufferWriter(ByteBuffer buf) {
this.buf = buf;
this.floatBuffer = buf.asFloatBuffer();
this.shortBuffer = buf.asShortBuffer();
this.intBuffer = buf.asIntBuffer();
}
private void incrementPosition(int add) {
buf.position(buf.position() + add);
floatBuffer.position(buf.position() / 4);
shortBuffer.position(buf.position() / 2);
intBuffer.position(buf.position() / 4);
}
public void writeFloat(float x) {
try {
floatBuffer.put(x);
incrementPosition(4);
} catch(Exception e){
e.printStackTrace();
}
}
public void writeInt(int x) {
intBuffer.put(x);
incrementPosition(4);
}
public void writeByte(byte x) {
buf.put(x); // this increments the buffer position by 1
incrementPosition(0);
}
public int position() {
return buf.position();
}
public void writeShort(short s) {
shortBuffer.put(s);
incrementPosition(2);
}
}
@@ -0,0 +1,337 @@
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.io.IOException;
import java.util.Arrays;
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 minX = Float.POSITIVE_INFINITY;
public float minY = Float.POSITIVE_INFINITY;
public float minZ = Float.POSITIVE_INFINITY;
public float maxX = Float.NEGATIVE_INFINITY;
public float maxY = Float.NEGATIVE_INFINITY;
public float maxZ = Float.NEGATIVE_INFINITY;
public float[] us = new float[4];
public float[] vs = new float[4];
public int[] bs = new int[4];
public int[] cs = new int[4];
// TODO normals?
public boolean deleted;
public ModelQuadFacing normal;
public int offset;
public BlockRenderer.Flags flags;
// Is positive U direction parallel to edge 0-1?
public boolean uDirectionIs01;
public boolean isRectangle;
// 0: quads glued together on edge 1-2 or 3-0 ("megaquad row length")
// 1: quads glued together on edge 0-1 or 2-3 ("megaquad column length")
private final int[] quadCountByDirection = {1, 1};
private final Vector3f vectorA = new Vector3f(), vectorB = new Vector3f(), vectorC = new Vector3f();
private boolean hasColor;
private boolean hasShade;
public boolean hasColor() {
return this.hasColor;
}
public int[] getColors() {
return this.cs;
}
public boolean hasShade() {
return this.hasShade;
}
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 0;
}
@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]);
bs[vi] = flags.hasBrightness ? rawBuffer[i + 7] : DEFAULT_BRIGHTNESS;
cs[vi] = flags.hasColor ? rawBuffer[i + 5] : DEFAULT_COLOR;
this.hasColor |= flags.hasColor;
this.hasShade |= flags.hasBrightness;
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];
}
}
public void setState(int[] rawBuffer, int offset, BlockRenderer.Flags flags, int drawMode, float offsetX, float offsetY, float offsetZ) {
resetState();
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;
}
uDirectionIs01 = us[0] != us[1];
updateMinMaxXYZ();
updateIsRectangle();
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);
}
private void resetState() {
Arrays.fill(xs, 0);
Arrays.fill(ys, 0);
Arrays.fill(zs, 0);
Arrays.fill(us, 0);
Arrays.fill(vs, 0);
Arrays.fill(bs, 0);
Arrays.fill(cs, 0);
minX = Float.POSITIVE_INFINITY;
minY = Float.POSITIVE_INFINITY;
minZ = Float.POSITIVE_INFINITY;
maxX = Float.NEGATIVE_INFINITY;
maxY = Float.NEGATIVE_INFINITY;
maxZ = Float.NEGATIVE_INFINITY;
deleted = false;
normal = null;
offset = 0;
flags = null;
uDirectionIs01 = false;
Arrays.fill(quadCountByDirection, 1);
}
public void writeToBuffer(BufferWriter out) throws IOException {
for(int vertexI = 0; vertexI < 4; vertexI++) {
int vi = vertexI;
int provokingI = 3;
float x = xs[vi];
float y = ys[vi];
float z = zs[vi];
out.writeFloat(x);
out.writeFloat(y);
out.writeFloat(z);
float u = us[vi];
float v = vs[vi];
out.writeFloat(u);
out.writeFloat(v);
int b = bs[vi];
out.writeInt(b);
int c = cs[vi];
out.writeInt(c);
assert out.position() % getStride() == 0;
//System.out.println("[" + vertexI + "] x: " + x + ", y: " + y + " z: " + z + ", u: " + u + ", v: " + v + ", b: " + b + ", c: " + c);
}
}
public int quadCountByUVDirection(boolean v) {
if(v) {
return quadCountByDirection[uDirectionIs01 ? 0 : 1];
} else {
return quadCountByDirection[uDirectionIs01 ? 1 : 0];
}
}
public static int getStride() {
return
3 * 4 // XYZ (float)
+ 2 * (/*Config.shortUV*/false ? 2 : 4) // UV (float)
+ 4 // B (int)
+ 4 // C (int)
;
}
private boolean isTranslatedCopyOf(Quad o, boolean checkValid) {
if((!isValid(this) && checkValid) || !isValid(o) || normal != o.normal) return false;
for(int i = 1; i < 4; i++) {
double relX = xs[i] - xs[0];
double relY = ys[i] - ys[0];
double relZ = zs[i] - zs[0];
if(o.xs[i] != o.xs[0] + relX || o.ys[i] != o.ys[0] + relY || o.zs[i] != o.zs[0] + relZ) {
return false;
}
}
for(int i = 0; i < 4; i++) {
if(us[i] != o.us[i] || vs[i] != o.vs[i] || bs[i] != o.bs[i] || cs[i] != o.cs[i]) {
return false;
}
}
return true;
}
private void copyVertexFrom(Quad o, int src, int dest) {
xs[dest] = o.xs[src];
ys[dest] = o.ys[src];
zs[dest] = o.zs[src];
us[dest] = o.us[src];
vs[dest] = o.vs[src];
bs[dest] = o.bs[src];
cs[dest] = o.cs[src];
updateMinMaxXYZ(); // TODO isn't doing this a waste? I should get rid of the min/maxXYZ variables entirely.
}
private void updateMinMaxXYZ() {
for(int i = 0; i < 4; i++) {
minX = Math.min(minX, xs[i]);
minY = Math.min(minY, ys[i]);
minZ = Math.min(minZ, zs[i]);
maxX = Math.max(maxX, xs[i]);
maxY = Math.max(maxY, ys[i]);
maxZ = Math.max(maxZ, zs[i]);
}
}
private void updateIsRectangle() {
isRectangle =
vertexExists(minX, minY, minZ) &&
vertexExists(minX, minY, maxZ) &&
vertexExists(minX, maxY, minZ) &&
vertexExists(minX, maxY, maxZ) &&
vertexExists(maxX, minY, minZ) &&
vertexExists(maxX, minY, maxZ) &&
vertexExists(maxX, maxY, minZ) &&
vertexExists(maxX, maxY, maxZ);
}
private boolean vertexExists(float x, float y, float z) {
for(int i = 0; i < 4; i++) {
if(xs[i] == x && ys[i] == y && zs[i] == z) {
return true;
}
}
return false;
}
public static boolean isValid(Quad q) {
return q != null && !q.deleted;
}
public boolean isClockwiseXZ() {
return (xs[1] - xs[0]) * (zs[2] - zs[0]) - (xs[2] - xs[0]) * (zs[1] - zs[0]) < 0;
}
@Override
public String toString() {
return String.format(Locale.ENGLISH, "%s(%.1f, %.1f, %.1f -- %.1f, %.1f, %.1f)", deleted ? "XXX " : "", minX, minY, minZ, maxX, maxY, maxZ);
//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]);
}
}
@@ -0,0 +1,49 @@
package com.gtnewhorizons.angelica.compat.nd;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;
public class RecyclingList<T> {
// Adapted from Neodymium
private Supplier<T> constructor;
int nextIndex;
private final List<T> list;
public RecyclingList(Supplier<T> constructor) {
this.constructor = constructor;
this.list = new ArrayList<>();
}
public T get(int i) {
while(list.size() <= i) {
list.add(constructor.get());
}
return list.get(i);
}
public T next() {
return get(nextIndex++);
}
public void remove() {
if(nextIndex == 0) {
throw new IllegalStateException("Tried to remove from empty list");
}
nextIndex--;
}
public boolean isEmpty() {
return nextIndex == 0;
}
public void reset() {
nextIndex = 0;
}
public List<T> getAsList() {
return list.subList(0, nextIndex);
}
}
@@ -0,0 +1,32 @@
package com.gtnewhorizons.angelica.compat.toremove;
import com.google.common.collect.ImmutableList;
import com.gtnewhorizons.angelica.compat.mojang.VertexFormatElement;
import com.gtnewhorizons.angelica.compat.mojang.VertexFormatElement.Type;
import com.gtnewhorizons.angelica.compat.mojang.VertexFormatElement.Usage;
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_0_ELEMENT = new VertexFormatElement(0, Type.FLOAT, Usage.UV, 2);
public static final VertexFormatElement OVERLAY_ELEMENT = new VertexFormatElement(1, Type.SHORT, Usage.UV, 2);
public static final VertexFormatElement LIGHT_ELEMENT = new VertexFormatElement(2, 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_COLOR_TEXTURE_LIGHT_NORMAL = new VertexFormat(new ImmutableList.Builder<VertexFormatElement>().add(POSITION_ELEMENT).add(COLOR_ELEMENT).add(TEXTURE_0_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_0_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_0_ELEMENT).add(COLOR_ELEMENT).add(LIGHT_ELEMENT).build());
public static final VertexFormat POSITION = new VertexFormat(new ImmutableList.Builder<VertexFormatElement>().add(POSITION_ELEMENT).build());
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_0_ELEMENT).build());
public static final VertexFormat POSITION_COLOR_TEXTURE = new VertexFormat(new ImmutableList.Builder<VertexFormatElement>().add(POSITION_ELEMENT).add(COLOR_ELEMENT).add(TEXTURE_0_ELEMENT).build());
public static final VertexFormat POSITION_TEXTURE_COLOR = new VertexFormat(new ImmutableList.Builder<VertexFormatElement>().add(POSITION_ELEMENT).add(TEXTURE_0_ELEMENT).add(COLOR_ELEMENT).build());
public static final VertexFormat POSITION_COLOR_TEX_LIGHTMAP = new VertexFormat(new ImmutableList.Builder<VertexFormatElement>().add(POSITION_ELEMENT).add(COLOR_ELEMENT).add(TEXTURE_0_ELEMENT).add(LIGHT_ELEMENT).build());
public static final VertexFormat POSITION_TEXTURE_LIGHT_COLOR = new VertexFormat(new ImmutableList.Builder<VertexFormatElement>().add(POSITION_ELEMENT).add(TEXTURE_0_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_0_ELEMENT).add(COLOR_ELEMENT).add(NORMAL_ELEMENT).add(PADDING_ELEMENT).build());
}
@@ -0,0 +1,20 @@
package com.gtnewhorizons.angelica.compat.toremove;
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;
}
}
@@ -0,0 +1,110 @@
package com.gtnewhorizons.angelica.compat.toremove;
import com.google.common.collect.Queues;
import org.joml.Matrix3f;
import org.joml.Matrix4f;
import java.util.Deque;
public class MatrixStack {
private final Deque<Entry> matrixStack;
public MatrixStack() {
this.matrixStack = Queues.newArrayDeque();
matrixStack.add(new Entry(new Matrix4f().identity(), new Matrix3f().identity()));
}
public MatrixStack(Matrix4f initial) {
this.matrixStack = Queues.newArrayDeque();
Matrix3f normal = new Matrix3f();
matrixStack.add(new Entry(initial, initial.normal(normal)));
}
public Entry peek() {
return (Entry)this.matrixStack.getLast();
}
public void push() {
final Entry lv = (Entry)this.matrixStack.getLast();
this.matrixStack.addLast(new Entry(new Matrix4f(lv.model), new Matrix3f(lv.normal)));
}
public void pop() {
this.matrixStack.removeLast();
}
public boolean clear() {
return this.matrixStack.size() == 1;
}
public void translate(double d, double e, double f) {
final Entry lv = (Entry)this.matrixStack.getLast();
lv.model.translate((float)d, (float)e, (float)f);
}
public void rotateX(float f) {
final Entry lv = (Entry)this.matrixStack.getLast();
lv.model.rotateX(f);
lv.normal.rotateX(f);
}
public void rotateY(float f) {
final Entry lv = (Entry)this.matrixStack.getLast();
lv.model.rotateY(f);
lv.normal.rotateY(f);
}
public void rotateZ(float f) {
final Entry lv = (Entry)this.matrixStack.getLast();
lv.model.rotateZ(f);
lv.normal.rotateZ(f);
}
public void scale(float f, float g, float h) {
final Entry lv = (Entry)this.matrixStack.getLast();
lv.model.scale(f, g, h);
if (f == g && g == h) {
if (f > 0.0F) {
return;
}
lv.normal.scale(-1.0F);
}
float i = 1.0F / f;
float j = 1.0F / g;
float k = 1.0F / h;
float l = invSqrt(i * j * k);
lv.normal.scale(l * i, l * j, l * k);
}
private static float invSqrt(float x) {
float xhalf = 0.5f * x;
int i = Float.floatToIntBits(x);
i = 0x5f3759df - (i >> 1);
x = Float.intBitsToFloat(i);
x *= (1.5f - xhalf * x * x);
return x;
}
public static final class Entry {
private final Matrix4f model;
private final Matrix3f normal;
private Entry(Matrix4f model, Matrix3f normal) {
this.model = model;
this.normal = normal;
}
public Matrix4f getModel() {
return model;
}
public Matrix3f getNormal() {
return normal;
}
}
}
@@ -0,0 +1,8 @@
package com.gtnewhorizons.angelica.compat.toremove;
@Deprecated
public class OverlayTexture {
// This is definitely wrong
public static final int NO_OVERLAY = 0;
}
@@ -0,0 +1,311 @@
package com.gtnewhorizons.angelica.compat.toremove;
import com.google.common.collect.ImmutableList;
import it.unimi.dsi.fastutil.Hash;
import it.unimi.dsi.fastutil.objects.ObjectOpenCustomHashSet;
import lombok.Getter;
import net.minecraft.util.ResourceLocation;
import javax.annotation.Nullable;
import java.util.Objects;
import java.util.Optional;
public abstract class RenderLayer extends RenderPhase { // Aka: RenderType (Iris)
private static final RenderLayer SOLID = of("solid", DefaultVertexFormat.POSITION_COLOR_TEXTURE_LIGHT_NORMAL, 7, 2097152, true, false, RenderLayer.MultiPhaseParameters.builder().shadeModel(SMOOTH_SHADE_MODEL).lightmap(ENABLE_LIGHTMAP).texture(MIPMAP_BLOCK_ATLAS_TEXTURE).build(true));
private static final RenderLayer CUTOUT = of("cutout", DefaultVertexFormat.POSITION_COLOR_TEXTURE_LIGHT_NORMAL, 7, 131072, true, false, RenderLayer.MultiPhaseParameters.builder().shadeModel(SMOOTH_SHADE_MODEL).lightmap(ENABLE_LIGHTMAP).texture(BLOCK_ATLAS_TEXTURE).alpha(HALF_ALPHA).build(true));
private static final RenderLayer TRANSLUCENT = of("translucent", DefaultVertexFormat.POSITION_COLOR_TEXTURE_LIGHT_NORMAL, 7, 262144, true, true, createTranslucentPhaseData());
@Getter
private final VertexFormat vertexFormat;
@Getter
private final int drawMode;
@Getter
private final int expectedBufferSize;
public RenderLayer(String name, VertexFormat vertexFormat, int drawMode, int expectedBufferSize, Runnable startAction, Runnable endAction) {
super(name, startAction, endAction);
this.vertexFormat = vertexFormat;
this.drawMode = drawMode;
this.expectedBufferSize = expectedBufferSize;
}
public static MultiPhase of(String name, VertexFormat vertexFormat, int drawMode, int expectedBufferSize, MultiPhaseParameters phaseData) {
return of(name, vertexFormat, drawMode, expectedBufferSize, false, false, phaseData);
}
public static MultiPhase of(String name, VertexFormat vertexFormat, int drawMode, int expectedBufferSize, boolean hasCrumbling, boolean translucent, MultiPhaseParameters phases) {
return RenderLayer.MultiPhase.of(name, vertexFormat, drawMode, expectedBufferSize, hasCrumbling, translucent, phases);
}
public static RenderLayer solid() {
return SOLID;
}
public static RenderLayer cutout() {
return CUTOUT;
}
private static MultiPhaseParameters createTranslucentPhaseData() {
return RenderLayer.MultiPhaseParameters.builder().shadeModel(SMOOTH_SHADE_MODEL).lightmap(ENABLE_LIGHTMAP).texture(MIPMAP_BLOCK_ATLAS_TEXTURE).transparency(TRANSLUCENT_TRANSPARENCY).target(TRANSLUCENT_TARGET).build(true);
}
public static RenderLayer translucent() {
return TRANSLUCENT;
}
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));
}
public int mode() {
return this.drawMode;
}
static final class MultiPhase extends RenderLayer {
private static final ObjectOpenCustomHashSet<MultiPhase> CACHE;
private final MultiPhaseParameters phases;
private final int hash;
private final Optional<RenderLayer> affectedOutline;
private final boolean outline;
private MultiPhase(String name, VertexFormat vertexFormat, int drawMode, int expectedBufferSize, boolean hasCrumbling, boolean translucent, MultiPhaseParameters phases) {
super(name, vertexFormat, drawMode, expectedBufferSize, () -> {
phases.phases.forEach(RenderPhase::startDrawing);
}, () -> {
phases.phases.forEach(RenderPhase::endDrawing);
});
this.phases = phases;
this.affectedOutline = phases.outlineMode == RenderLayer.OutlineMode.AFFECTS_OUTLINE ? phases.texture.getId().map((arg2) -> {
return getOutline(arg2, phases.cull);
}) : Optional.empty();
this.outline = phases.outlineMode == RenderLayer.OutlineMode.IS_OUTLINE;
this.hash = Objects.hash(new Object[]{super.hashCode(), phases});
}
public static MultiPhase of(String name, VertexFormat vertexFormat, int drawMode, int expectedBufferSize, boolean hasCrumbling, boolean translucent,
MultiPhaseParameters phases) {
return (MultiPhase)CACHE.addOrGet(new MultiPhase(name, vertexFormat, drawMode, expectedBufferSize, hasCrumbling, translucent, phases));
}
public Optional<RenderLayer> getAffectedOutline() {
return this.affectedOutline;
}
public boolean equals(@Nullable Object object) {
return this == object;
}
public int hashCode() {
return this.hash;
}
public String toString() {
return "RenderType[" + this.phases + ']';
}
static {
CACHE = new ObjectOpenCustomHashSet(RenderLayer.MultiPhase.HashStrategy.INSTANCE);
}
static enum HashStrategy implements Hash.Strategy<MultiPhase> {
INSTANCE;
private HashStrategy() {
}
public int hashCode(@Nullable MultiPhase arg) {
return arg == null ? 0 : arg.hash;
}
public boolean equals(@Nullable MultiPhase arg, @Nullable MultiPhase arg2) {
if (arg == arg2) {
return true;
} else {
return arg != null && arg2 != null ? Objects.equals(arg.phases, arg2.phases) : false;
}
}
}
}
public static final class MultiPhaseParameters {
private final RenderPhase.Texture texture;
private final RenderPhase.Transparency transparency;
private final RenderPhase.DiffuseLighting diffuseLighting;
private final RenderPhase.ShadeModel shadeModel;
private final RenderPhase.Alpha alpha;
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) {
this.texture = texture;
this.transparency = transparency;
this.diffuseLighting = diffuseLighting;
this.shadeModel = shadeModel;
this.alpha = alpha;
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});
}
public boolean equals(Object object) {
if (this == object) {
return true;
} else if (object != null && this.getClass() == object.getClass()) {
MultiPhaseParameters rendertype$state = (MultiPhaseParameters)object;
return this.outlineMode == rendertype$state.outlineMode && this.phases.equals(rendertype$state.phases);
} else {
return false;
}
}
public int hashCode() {
return Objects.hash(new Object[]{this.phases, this.outlineMode});
}
public String toString() {
return "CompositeState[" + this.phases + ", outlineProperty=" + this.outlineMode + ']';
}
public static Builder builder() {
return new Builder();
}
public static class Builder {
private RenderPhase.Texture texture;
private RenderPhase.Transparency transparency;
private RenderPhase.DiffuseLighting diffuseLighting;
private RenderPhase.ShadeModel shadeModel;
private RenderPhase.Alpha alpha;
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 ;
this.transparency = RenderPhase.NO_TRANSPARENCY;
this.diffuseLighting = RenderPhase.DISABLE_DIFFUSE_LIGHTING;
this.shadeModel = RenderPhase.SHADE_MODEL;
this.alpha = RenderPhase.ZERO_ALPHA;
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) {
this.texture = texture;
return this;
}
public Builder transparency(RenderPhase.Transparency transparency) {
this.transparency = transparency;
return this;
}
public Builder shadeModel(RenderPhase.ShadeModel shadeModel) {
this.shadeModel = shadeModel;
return this;
}
public Builder alpha(RenderPhase.Alpha alpha) {
this.alpha = alpha;
return this;
}
public Builder depthTest(RenderPhase.DepthTest depthTest) {
this.depthTest = depthTest;
return this;
}
public Builder cull(RenderPhase.Cull cull) {
this.cull = cull;
return this;
}
public Builder lightmap(RenderPhase.Lightmap lightmap) {
this.lightmap = lightmap;
return this;
}
public Builder overlay(RenderPhase.Overlay overlay) {
this.overlay = overlay;
return this;
}
public Builder fog(RenderPhase.Fog fog) {
this.fog = fog;
return this;
}
public Builder target(RenderPhase.Target target) {
this.target = target;
return this;
}
public Builder texturing(RenderPhase.Texturing texturing) {
this.texturing = texturing;
return this;
}
public MultiPhaseParameters build(boolean affectsOutline) {
return this.build(affectsOutline ? RenderLayer.OutlineMode.AFFECTS_OUTLINE : RenderLayer.OutlineMode.NONE);
}
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);
}
}
}
enum OutlineMode {
NONE("none"),
IS_OUTLINE("is_outline"),
AFFECTS_OUTLINE("affects_outline");
private final String name;
OutlineMode(String name) {
this.name = name;
}
public String toString() {
return this.name;
}
}
}
@@ -0,0 +1,816 @@
package com.gtnewhorizons.angelica.compat.toremove;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import me.jellysquid.mods.sodium.client.SodiumClientMod;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.util.ResourceLocation;
import org.lwjgl.opengl.GL11;
import javax.annotation.Nullable;
import java.util.Objects;
import java.util.Optional;
import java.util.OptionalDouble;
public abstract class RenderPhase {
protected final String name;
protected Runnable beginAction;
private final Runnable endAction;
protected static final Transparency NO_TRANSPARENCY = new Transparency("no_transparency", GLStateManager::disableBlend, () -> {
});
protected static final Transparency ADDITIVE_TRANSPARENCY = new Transparency("additive_transparency", () -> {
GLStateManager.enableBlend();
GLStateManager.glBlendFunc(GL11.GL_ONE, GL11.GL_ONE);
}, () -> {
GLStateManager.disableBlend();
GLStateManager.defaultBlendFunc();
});
protected static final Transparency LIGHTNING_TRANSPARENCY = new Transparency("lightning_transparency", () -> {
GLStateManager.enableBlend();
GLStateManager.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE);
}, () -> {
GLStateManager.disableBlend();
GLStateManager.defaultBlendFunc();
});
protected static final Transparency GLINT_TRANSPARENCY = new Transparency("glint_transparency", () -> {
GLStateManager.enableBlend();
GLStateManager.tryBlendFuncSeparate(GL11.GL_SRC_COLOR, GL11.GL_ONE, GL11.GL_ZERO, GL11.GL_ONE);
}, () -> {
GLStateManager.disableBlend();
GLStateManager.defaultBlendFunc();
});
protected static final Transparency CRUMBLING_TRANSPARENCY = new Transparency("crumbling_transparency", () -> {
GLStateManager.enableBlend();
GLStateManager.tryBlendFuncSeparate(GL11.GL_DST_COLOR, GL11.GL_SRC_COLOR, GL11.GL_ONE, GL11.GL_ZERO);
}, () -> {
GLStateManager.disableBlend();
GLStateManager.defaultBlendFunc();
});
protected static final Transparency TRANSLUCENT_TRANSPARENCY = new Transparency("translucent_transparency", () -> {
GLStateManager.enableBlend();
GLStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
}, () -> {
GLStateManager.disableBlend();
GLStateManager.defaultBlendFunc();
});
protected static final Alpha ZERO_ALPHA = new Alpha(0.0F);
protected static final Alpha ONE_TENTH_ALPHA = new Alpha(0.003921569F);
protected static final Alpha HALF_ALPHA = new Alpha(0.5F);
protected static final ShadeModel SHADE_MODEL = new ShadeModel(false);
protected static final ShadeModel SMOOTH_SHADE_MODEL = new ShadeModel(true);
protected static final Texture MIPMAP_BLOCK_ATLAS_TEXTURE;
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;
protected static final Cull DISABLE_CULLING;
protected static final DepthTest ALWAYS_DEPTH_TEST;
protected static final DepthTest EQUAL_DEPTH_TEST;
protected static final DepthTest LEQUAL_DEPTH_TEST;
protected static final WriteMaskState ALL_MASK;
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;
this.beginAction = beginAction;
this.endAction = endAction;
}
public void startDrawing() {
this.beginAction.run();
}
public void endDrawing() {
this.endAction.run();
}
public boolean equals(@Nullable Object object) {
if (this == object) {
return true;
} else if (object != null && this.getClass() == object.getClass()) {
RenderPhase lv = (RenderPhase)object;
return this.name.equals(lv.name);
} else {
return false;
}
}
public int hashCode() {
return this.name.hashCode();
}
public String toString() {
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
MIPMAP_BLOCK_ATLAS_TEXTURE = new Texture(ATLAS, false, true);
BLOCK_ATLAS_TEXTURE = new Texture(ATLAS, false, false);
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);
DISABLE_CULLING = new Cull(false);
ALWAYS_DEPTH_TEST = new DepthTest("always", GL11.GL_ALWAYS);
EQUAL_DEPTH_TEST = new DepthTest("==", GL11.GL_EQUAL);
LEQUAL_DEPTH_TEST = new DepthTest("<=", GL11.GL_LEQUAL);
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_FOG = new Fog("no_fog", () -> {
}, () -> {
});
FOG = new Fog("fog", () -> {
// Unclear what this should do
// BackgroundRenderer.setFogBlack(), also levelFogColor()
SodiumClientMod.LOGGER.debug("Fog - Not setting level fog color");
GLStateManager.enableFog();
}, GLStateManager::disableFog);
BLACK_FOG = new Fog("black_fog", () -> {
GLStateManager.fogColor(0.0F, 0.0F, 0.0F, 1.0F);
GLStateManager.enableFog();
}, () -> {
// Unclear what this should do
// BackgroundRenderer.setFogBlack(), also levelFogColor()
SodiumClientMod.LOGGER.debug("Fog - Not setting level fog color");
GLStateManager.disableFog();
});
MAIN_TARGET = new Target("main_target", () -> {
}, () -> {
});
OUTLINE_TARGET = new Target("outline_target", () -> {
// TODO: Sodium
SodiumClientMod.LOGGER.debug("NOT enabling the entity outline framebuffer");
//MinecraftClient.getInstance().worldRenderer.getEntityOutlinesFramebuffer().beginWrite(false);
}, () -> {
Minecraft.getMinecraft().getFramebuffer().bindFramebuffer(false);
});
TRANSLUCENT_TARGET = new Target("translucent_target", () -> {
if (Minecraft.isFancyGraphicsEnabled()) {
// TODO: Sodium
SodiumClientMod.LOGGER.debug("NOT enabling the translucent framebuffer");
// MinecraftClient.getInstance().worldRenderer.getTranslucentFramebuffer().beginWrite(false);
}
}, () -> {
if (Minecraft.isFancyGraphicsEnabled()) {
Minecraft.getMinecraft().getFramebuffer().bindFramebuffer(false);
}
});
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") + ']';
}
}
public static class Target extends RenderPhase {
public Target(String string, Runnable runnable, Runnable runnable2) {
super(string, runnable, runnable2);
}
}
public static class Fog extends RenderPhase {
public Fog(String string, Runnable runnable, Runnable runnable2) {
super(string, runnable, runnable2);
}
}
public static class Layering extends RenderPhase {
public Layering(String string, Runnable runnable, Runnable runnable2) {
super(string, runnable, runnable2);
}
}
public static class WriteMaskState extends RenderPhase {
private final boolean color;
private final boolean depth;
public WriteMaskState(boolean color, boolean depth) {
super("write_mask_state", () -> {
if (!depth) {
GLStateManager.glDepthMask(depth);
}
if (!color) {
GLStateManager.glColorMask(color, color, color, color);
}
}, () -> {
if (!depth) {
GLStateManager.glDepthMask(true);
}
if (!color) {
GLStateManager.glColorMask(true, true, true, true);
}
});
this.color = color;
this.depth = depth;
}
@Override
public boolean equals(Object object) {
if (this == object) {
return true;
} else if (object != null && this.getClass() == object.getClass()) {
WriteMaskState lv = (WriteMaskState)object;
return this.color == lv.color && this.depth == lv.depth;
} else {
return false;
}
}
@Override
public int hashCode() {
return Objects.hash(this.color, this.depth);
}
@Override
public String toString() {
return this.name + "[writeColor=" + this.color + ", writeDepth=" + this.depth + ']';
}
}
public static class DepthTest extends RenderPhase {
private final String depthFunction;
private final int func;
public DepthTest(String string, int i) {
super("depth_test", () -> {
if (i != GL11.GL_ALWAYS) {
GLStateManager.enableDepthTest();
GLStateManager.glDepthFunc(i);
}
}, () -> {
if (i != GL11.GL_ALWAYS) {
GLStateManager.disableDepthTest();
GLStateManager.glDepthFunc(GL11.GL_LEQUAL);
}
});
this.depthFunction = string;
this.func = i;
}
@Override
public boolean equals(Object object) {
if (this == object) {
return true;
} else if (object != null && this.getClass() == object.getClass()) {
DepthTest lv = (DepthTest)object;
return this.func == lv.func;
} else {
return false;
}
}
@Override
public int hashCode() {
return Integer.hashCode(this.func);
}
@Override
public String toString() {
return this.name + '[' + this.depthFunction + ']';
}
}
public static class Cull extends Toggleable {
public Cull(boolean culling) {
super("cull", () -> {
if (!culling) {
GLStateManager.disableCull();
}
}, () -> {
if (!culling) {
GLStateManager.enableCull();
}
}, culling);
}
}
public static class DiffuseLighting extends Toggleable {
public DiffuseLighting(boolean guiLighting) {
super("diffuse_lighting", () -> {
if (guiLighting) {
throw new RuntimeException("Not Implemented Yet");
// net.minecraft.client.drawScreen.DiffuseLighting.enable();
}
}, () -> {
if (guiLighting) {
throw new RuntimeException("Not Implemented Yet");
// net.minecraft.client.drawScreen.DiffuseLighting.disable();
}
}, guiLighting);
}
}
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", () -> {
if (lightmap) {
// TODO: Sodium - LightmapTextureManager
SodiumClientMod.LOGGER.debug("Lightmap - enable (not implemented)");
// throw new RuntimeException("Not Implemented Yet");
// MinecraftClient.getInstance().gameRenderer.getLightmapTextureManager().enable();
}
}, () -> {
if (lightmap) {
// TODO: Sodium - LightmapTextureManager
SodiumClientMod.LOGGER.debug("Lightmap - disable (not implemented)");
// throw new RuntimeException("Not Implemented Yet");
// MinecraftClient.getInstance().gameRenderer.getLightmapTextureManager().disable();
}
}, lightmap);
}
}
static class Toggleable extends RenderPhase {
private final boolean enabled;
public Toggleable(String string, Runnable runnable, Runnable runnable2, boolean bl) {
super(string, runnable, runnable2);
this.enabled = bl;
}
@Override
public boolean equals(Object object) {
if (this == object) {
return true;
} else if (object != null && this.getClass() == object.getClass()) {
Toggleable lv = (Toggleable)object;
return this.enabled == lv.enabled;
} else {
return false;
}
}
@Override
public int hashCode() {
return Boolean.hashCode(this.enabled);
}
@Override
public String toString() {
return this.name + '[' + this.enabled + ']';
}
}
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);
}
}
public static class Texture extends RenderPhase {
private final Optional<ResourceLocation> id;
protected boolean bilinear;
protected boolean mipmap;
public Texture(ResourceLocation id, boolean bilinear, boolean mipmap) {
super("texture", () -> {
GLStateManager.enableTexture();
TextureManager lv = Minecraft.getMinecraft().getTextureManager();
lv.bindTexture(id);
//GLStateManager.setFilter(bilinear, mipmap); // breaks textures. TODO find out why
}, () -> {
});
this.id = Optional.of(id);
this.bilinear = bilinear;
this.mipmap = mipmap;
}
public Texture() {
super("texture", GLStateManager::disableTexture, GLStateManager::enableTexture);
this.id = Optional.empty();
this.bilinear = false;
this.mipmap = false;
}
@Override
public boolean equals(Object object) {
if (this == object) {
return true;
} else if (object != null && this.getClass() == object.getClass()) {
Texture lv = (Texture)object;
return this.id.equals(lv.id) && this.bilinear == lv.bilinear && this.mipmap == lv.mipmap;
} else {
return false;
}
}
@Override
public int hashCode() {
return this.id.hashCode();
}
@Override
public String toString() {
return this.name + '[' + this.id + "(blur=" + this.bilinear + ", mipmap=" + this.mipmap + ")]";
}
protected Optional<ResourceLocation> getId() {
return this.id;
}
}
public static class ShadeModel extends RenderPhase {
private final boolean smooth;
public ShadeModel(boolean smooth) {
super("shade_model",
() -> GLStateManager.glShadeModel(smooth ? GL11.GL_SMOOTH : GL11.GL_FLAT),
() -> GLStateManager.glShadeModel(GL11.GL_FLAT));
this.smooth = smooth;
}
@Override
public boolean equals(Object object) {
if (this == object) {
return true;
} else if (object != null && this.getClass() == object.getClass()) {
ShadeModel lv = (ShadeModel)object;
return this.smooth == lv.smooth;
} else {
return false;
}
}
@Override
public int hashCode() {
return Boolean.hashCode(this.smooth);
}
@Override
public String toString() {
return this.name + '[' + (this.smooth ? "smooth" : "flat") + ']';
}
}
public static class Alpha extends RenderPhase {
private final float alpha;
public Alpha(float alpha) {
super("alpha", () -> {
if (alpha > 0.0F) {
GLStateManager.enableAlphaTest();
GLStateManager.glAlphaFunc(GL11.GL_GREATER, alpha);
} else {
GLStateManager.disableAlphaTest();
}
}, () -> {
GLStateManager.disableAlphaTest();
GLStateManager.glAlphaFunc(GL11.GL_GREATER, 0.1F);
});
this.alpha = alpha;
}
@Override
public boolean equals(@Nullable Object object) {
if (this == object) {
return true;
} else if (object != null && this.getClass() == object.getClass()) {
if (!super.equals(object)) {
return false;
} else {
return this.alpha == ((Alpha)object).alpha;
}
} else {
return false;
}
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), this.alpha);
}
@Override
public String toString() {
return this.name + '[' + this.alpha + ']';
}
}
public static class Transparency extends RenderPhase {
public Transparency(String string, Runnable runnable, Runnable runnable2) {
super(string, runnable, runnable2);
}
}
}
@@ -0,0 +1,48 @@
package com.gtnewhorizons.angelica.compat.toremove;
import javax.annotation.Nonnull;
public interface VertexConsumer {
VertexConsumer vertex(double d, double e, double f);
@Nonnull
VertexConsumer color(int r, int g, int b, int a);
@Nonnull
VertexConsumer texture(float u, float v);
@Nonnull
VertexConsumer overlay(int u, int v);
@Nonnull
VertexConsumer light(int u, int v);
@Nonnull
VertexConsumer normal(float x, float y, float z);
void next();
default VertexConsumer overlay(int overlay) {
return this.overlay(overlay & 0xFFFF, overlay >> 16 & 0xFFFF);
}
default VertexConsumer light(int light) {
return this.light(light & 0xFFFF, light >> 16 & 0xFFFF);
}
default VertexConsumer 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));
}
default void vertex(float x, float y, float z, float red, float green, float blue, float alpha, float u, float v, int overlay, int light, float normalX, float normalY, float normalZ) {
this.vertex((double)x, (double)y, (double)z);
this.color(red, green, blue, alpha);
this.texture(u, v);
this.overlay(overlay);
this.light(light);
this.normal(normalX, normalY, normalZ);
this.next();
}
}
@@ -0,0 +1,67 @@
package com.gtnewhorizons.angelica.compat.toremove;
import com.google.common.collect.ImmutableList;
import com.gtnewhorizons.angelica.compat.mojang.VertexFormatElement;
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.util.List;
public class VertexFormat {
@Getter
protected final ImmutableList<VertexFormatElement> elements;
protected final IntList offsets = new IntArrayList();
@Getter
protected final int vertexSize;
public VertexFormat(ImmutableList<VertexFormatElement> elements) {
this.elements = elements;
int i = 0;
for (VertexFormatElement element : elements) {
offsets.add(i);
i += element.getByteSize();
}
vertexSize = i;
}
@Deprecated
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) {
((VertexFormatElement)list.get(j)).setupBufferState(l + (long)this.offsets.getInt(j), i);
}
}
@Deprecated
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();
}
}
}
@@ -0,0 +1,76 @@
package com.gtnewhorizons.angelica.config;
@Config(modid = "angelica")
public class AngelicaConfig {
@Config.Comment("Enable Sodium rendering")
@Config.DefaultBoolean(true)
@Config.RequiresMcRestart
public static boolean enableSodium;
@Config.Comment("Enable Sodium fluid rendering")
@Config.DefaultBoolean(false)
@Config.RequiresMcRestart
public static boolean enableSodiumFluidRendering;
@Config.Comment("Enable Iris Shaders [Requires Sodium]")
@Config.DefaultBoolean(false)
@Config.RequiresMcRestart
public static boolean enableIris;
@Config.Comment("Enable MCPatcherForge features, still in Alpha. Individual features are toggled in mcpatcher.json")
@Config.DefaultBoolean(false)
@Config.RequiresMcRestart
public static boolean enableMCPatcherForgeFeatures;
@Config.Comment("Enable NotFine optimizations")
@Config.DefaultBoolean(true)
@Config.RequiresMcRestart
public static boolean enableNotFineOptimizations;
@Config.Comment("Enable NotFine features")
@Config.DefaultBoolean(true)
@Config.RequiresMcRestart
public static boolean enableNotFineFeatures;
@Config.Comment("Tweak F3 screen to be closer to modern versions. [From ArchaicFix]")
@Config.DefaultBoolean(true)
public static boolean modernizeF3Screen;
@Config.Comment("Show block registry name and meta value in F3, similar to 1.8+. [From ArchaicFix]")
@Config.DefaultBoolean(true)
public static boolean showBlockDebugInfo;
@Config.DefaultBoolean(true)
@Config.Comment("Hide downloading terrain screen. [From ArchaicFix]")
public static boolean hideDownloadingTerrainScreen;
@Config.Comment("Show memory usage during game load. [From ArchaicFix]")
@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.DefaultBoolean(true)
@Config.RequiresMcRestart
public static boolean enableHudCaching;
@Config.Comment("Batch drawScreen fonts [Experimental]")
@Config.DefaultBoolean(true)
@Config.RequiresMcRestart
public static boolean enableFontRenderer;
@Config.Comment("Optimize world update light. [From Hodgepodge]")
@Config.DefaultBoolean(true)
@Config.RequiresMcRestart
public static boolean optimizeWorldUpdateLight;
@Config.Comment("Speedup Animations. [From Hodgepodge]")
@Config.DefaultBoolean(true)
@Config.RequiresMcRestart
public static boolean speedupAnimations;
@Config.Comment("Optimize Texture Loading. [From Hodgepodge]")
@Config.DefaultBoolean(true)
@Config.RequiresMcRestart
public static boolean optimizeTextureLoading;
}
@@ -0,0 +1,9 @@
package com.gtnewhorizons.angelica.config;
import net.minecraft.client.gui.GuiScreen;
public class AngelicaGuiConfig extends SimpleGuiConfig {
public AngelicaGuiConfig(GuiScreen parent) throws ConfigException {
super(parent, AngelicaConfig.class, "archaicfix", "ArchaicFix");
}
}
@@ -0,0 +1,10 @@
package com.gtnewhorizons.angelica.config;
import net.minecraft.client.gui.GuiScreen;
public class AngelicaGuiConfigFactory implements SimpleGuiFactory {
@Override
public Class<? extends GuiScreen> mainConfigGuiClass() {
return AngelicaGuiConfig.class;
}
}
@@ -0,0 +1,113 @@
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 {
}
}
@@ -0,0 +1,15 @@
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,267 @@
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();
}
});
}
}
@@ -0,0 +1,158 @@
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();
}
}
@@ -0,0 +1,13 @@
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");
}
}
@@ -0,0 +1,26 @@
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,42 @@
package com.gtnewhorizons.angelica.glsm;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;
public class Dirty {
private Dirty() {}
public static final long
ALPHA_TEST = 1L << 0,
BLEND = 1L << 1,
DEPTH_TEST = 1L << 2,
CULL = 1L << 3,
LIGHTING = 1L << 4,
RESCALE_NORMAL = 1L << 5,
TEXTURE_2D = 1L << 6,
FOG = 1L << 7,
BLEND_STATE = 1L << 8,
DEPTH_FUNC = 1L << 9,
DEPTH_MASK = 1L << 10,
COLOR = 1L << 11,
COLOR_MASK = 1L << 12,
CLEAR_COLOR = 1L << 13,
ACTIVE_TEXTURE = 1L << 14,
BOUND_TEXTURE = 1L << 15,
SHADE_MODEL = 1L << 16,
ALL = ALPHA_TEST | BLEND | DEPTH_TEST | CULL | LIGHTING | RESCALE_NORMAL | TEXTURE_2D | FOG | BLEND_STATE | DEPTH_FUNC | DEPTH_MASK | COLOR | COLOR_MASK | CLEAR_COLOR | ACTIVE_TEXTURE | BOUND_TEXTURE | SHADE_MODEL;
public static long getFlagFromCap(int cap) {
return switch (cap) {
case GL11.GL_ALPHA_TEST -> ALPHA_TEST;
case GL11.GL_BLEND -> BLEND;
case GL11.GL_DEPTH_TEST -> DEPTH_TEST;
case GL11.GL_CULL_FACE -> CULL;
case GL11.GL_LIGHTING -> LIGHTING;
case GL12.GL_RESCALE_NORMAL -> RESCALE_NORMAL;
case GL11.GL_TEXTURE_2D -> TEXTURE_2D;
case GL11.GL_FOG -> FOG;
default -> throw new RuntimeException("Invalid cap: " + cap);
};
}
}
@@ -0,0 +1,697 @@
package com.gtnewhorizons.angelica.glsm;
import com.gtnewhorizons.angelica.config.AngelicaConfig;
import com.gtnewhorizons.angelica.glsm.states.AlphaState;
import com.gtnewhorizons.angelica.glsm.states.BlendState;
import com.gtnewhorizons.angelica.glsm.states.BooleanState;
import com.gtnewhorizons.angelica.glsm.states.Color4;
import com.gtnewhorizons.angelica.glsm.states.DepthState;
import com.gtnewhorizons.angelica.glsm.states.FogState;
import com.gtnewhorizons.angelica.glsm.states.GLColorMask;
import com.gtnewhorizons.angelica.glsm.states.TextureState;
import com.gtnewhorizons.angelica.hudcaching.HUDCaching;
import lombok.Getter;
import net.coderbot.iris.Iris;
import net.coderbot.iris.gbuffer_overrides.state.StateTracker;
import net.coderbot.iris.gl.blending.AlphaTestStorage;
import net.coderbot.iris.gl.blending.BlendModeStorage;
import net.coderbot.iris.gl.blending.DepthColorStorage;
import net.coderbot.iris.gl.sampler.SamplerLimits;
import net.coderbot.iris.gl.state.StateUpdateNotifiers;
import net.coderbot.iris.pipeline.WorldRenderingPipeline;
import net.coderbot.iris.samplers.IrisSamplers;
import net.coderbot.iris.texture.TextureInfoCache;
import net.coderbot.iris.texture.TextureTracker;
import net.coderbot.iris.texture.pbr.PBRTextureManager;
import net.minecraft.client.renderer.OpenGlHelper;
import org.joml.Vector3d;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.ARBMultitexture;
import org.lwjgl.opengl.Drawable;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;
import org.lwjgl.opengl.GL13;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.util.stream.IntStream;
import static com.gtnewhorizons.angelica.loading.AngelicaTweaker.LOGGER;
@SuppressWarnings("unused") // Used in ASM
public class GLStateManager {
public static final boolean BYPASS_CACHE = Boolean.parseBoolean(System.getProperty("angelica.disableGlCache", "false"));
// GLStateManager State Trackers
@Getter private static int activeTexture;
@Getter private static final BlendState blendState = new BlendState();
@Getter private static final DepthState depthState = new DepthState();
@Getter private static final FogState fogState = new FogState();
@Getter private static final Color4 Color = new Color4();
@Getter private static final Color4 ClearColor = new Color4();
@Getter private static final GLColorMask ColorMask = new GLColorMask();
@Getter private static final BooleanState cullState = new BooleanState(GL11.GL_CULL_FACE);
@Getter private static final AlphaState alphaState = new AlphaState();
@Getter private static final BooleanState lightingState = new BooleanState(GL11.GL_LIGHTING);
@Getter private static final BooleanState rescaleNormalState = new BooleanState(GL12.GL_RESCALE_NORMAL);
private static long dirty = 0;
private static int modelShadeMode;
@Getter
private static TextureState[] Textures;
// Iris Listeners
private static Runnable blendFuncListener = null;
private static Runnable fogToggleListener = null;
private static Runnable fogModeListener = null;
private static Runnable fogStartListener = null;
private static Runnable fogEndListener = null;
private static Runnable fogDensityListener = null;
// Thread Checking
@Getter
private static final Thread MainThread = Thread.currentThread();
private static Thread CurrentThread = MainThread;
private static boolean runningSplash = false;
private static boolean inGLNewList = false;
private static boolean hudCaching$blendEnabled;
public static void init() {
if (AngelicaConfig.enableIris) {
StateUpdateNotifiers.blendFuncNotifier = listener -> blendFuncListener = listener;
StateUpdateNotifiers.fogToggleNotifier = listener -> fogToggleListener = listener;
StateUpdateNotifiers.fogModeNotifier = listener -> fogModeListener = listener;
StateUpdateNotifiers.fogStartNotifier = listener -> fogStartListener = listener;
StateUpdateNotifiers.fogEndNotifier = listener -> fogEndListener = listener;
StateUpdateNotifiers.fogDensityNotifier = listener -> fogDensityListener = listener;
}
// We want textures regardless of Iris being initialized, and using SamplerLimits is isolated enough
Textures = IntStream.range(0, SamplerLimits.get().getMaxTextureUnits()).mapToObj(i -> new TextureState()).toArray(TextureState[]::new);
}
public static void assertMainThread() {
if (Thread.currentThread() != CurrentThread && !runningSplash) {
LOGGER.info("Call from not the Current Thread! - " + Thread.currentThread().getName() + " Current thread: " + CurrentThread.getName());
}
}
// LWJGL Overrides
public static void glEnable(int cap) {
switch (cap) {
case GL11.GL_ALPHA_TEST -> enableAlphaTest();
case GL11.GL_BLEND -> enableBlend();
case GL11.GL_DEPTH_TEST -> enableDepthTest();
case GL11.GL_CULL_FACE -> enableCull();
case GL11.GL_LIGHTING -> enableLighting();
case GL12.GL_RESCALE_NORMAL -> enableRescaleNormal();
case GL11.GL_TEXTURE_2D -> enableTexture();
case GL11.GL_FOG -> enableFog();
default -> GL11.glEnable(cap);
}
}
public static void glDisable(int cap) {
switch (cap) {
case GL11.GL_ALPHA_TEST -> disableAlphaTest();
case GL11.GL_BLEND -> disableBlend();
case GL11.GL_DEPTH_TEST -> disableDepthTest();
case GL11.GL_CULL_FACE -> disableCull();
case GL11.GL_LIGHTING -> disableLighting();
case GL12.GL_RESCALE_NORMAL -> disableRescaleNormal();
case GL11.GL_TEXTURE_2D -> disableTexture();
case GL11.GL_FOG -> disableFog();
default -> GL11.glDisable(cap);
}
}
// GLStateManager Functions
public static void enableBlend() {
if (AngelicaConfig.enableIris) {
if (BlendModeStorage.isBlendLocked()) {
BlendModeStorage.deferBlendModeToggle(true);
return;
}
}
hudCaching$blendEnabled = true;
blendState.mode.enable();
}
public static void disableBlend() {
if (AngelicaConfig.enableIris) {
if (BlendModeStorage.isBlendLocked()) {
BlendModeStorage.deferBlendModeToggle(false);
return;
}
}
hudCaching$blendEnabled = false;
blendState.mode.disable();
}
public static void glBlendFunc(int srcFactor, int dstFactor) {
if (AngelicaConfig.enableIris) {
if (BlendModeStorage.isBlendLocked()) {
BlendModeStorage.deferBlendFunc(srcFactor, dstFactor, srcFactor, dstFactor);
return;
}
}
if (HUDCaching.renderingCacheOverride) {
blendState.srcRgb = srcFactor;
blendState.dstRgb = dstFactor;
blendState.srcAlpha = GL11.GL_ONE;
blendState.dstAlpha = GL11.GL_ONE_MINUS_SRC_ALPHA;
OpenGlHelper.glBlendFunc(srcFactor, dstFactor, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
clean(Dirty.BLEND_STATE);
return;
}
if (GLStateManager.BYPASS_CACHE || blendState.srcRgb != srcFactor || blendState.dstRgb != dstFactor || checkDirty(Dirty.BLEND_STATE)) {
blendState.srcRgb = srcFactor;
blendState.dstRgb = dstFactor;
GL11.glBlendFunc(srcFactor, dstFactor);
}
// Iris
if (blendFuncListener != null) blendFuncListener.run();
}
public static void tryBlendFuncSeparate(int srcRgb, int dstRgb, int srcAlpha, int dstAlpha) {
if (AngelicaConfig.enableIris) {
if (BlendModeStorage.isBlendLocked()) {
BlendModeStorage.deferBlendFunc(srcRgb, dstRgb, srcAlpha, dstAlpha);
return;
}
}
if (HUDCaching.renderingCacheOverride && dstAlpha != GL11.GL_ONE_MINUS_SRC_ALPHA) {
srcAlpha = GL11.GL_ONE;
dstAlpha = GL11.GL_ONE_MINUS_SRC_ALPHA;
}
if (GLStateManager.BYPASS_CACHE || blendState.srcRgb != srcRgb || blendState.dstRgb != dstRgb || blendState.srcAlpha != srcAlpha || blendState.dstAlpha != dstAlpha || checkDirty(Dirty.BLEND_STATE)) {
blendState.srcRgb = srcRgb;
blendState.dstRgb = dstRgb;
blendState.srcAlpha = srcAlpha;
blendState.dstAlpha = dstAlpha;
OpenGlHelper.glBlendFunc(srcRgb, dstRgb, srcAlpha, dstAlpha);
}
// Iris
if (blendFuncListener != null) blendFuncListener.run();
}
public static void glDepthFunc(int func) {
// Hacky workaround for now, need to figure out why this isn't being applied...
if (GLStateManager.BYPASS_CACHE || func != depthState.func || GLStateManager.runningSplash || checkDirty(Dirty.DEPTH_FUNC)) {
depthState.func = func;
GL11.glDepthFunc(func);
}
}
public static void glDepthMask(boolean mask) {
if (AngelicaConfig.enableIris) {
if (DepthColorStorage.isDepthColorLocked()) {
DepthColorStorage.deferDepthEnable(mask);
return;
}
}
if (mask != depthState.mask || checkDirty(Dirty.DEPTH_MASK)) {
depthState.mask = mask;
GL11.glDepthMask(mask);
}
}
public static void glColor4f(float red, float green, float blue, float alpha) {
if (!hudCaching$blendEnabled && HUDCaching.renderingCacheOverride && alpha < 1f) {
alpha = 1f;
}
if (changeColor(red, green, blue, alpha)) {
GL11.glColor4f(red, green, blue, alpha);
}
}
public static void glColor4d(double red, double green, double blue, double alpha) {
if (!hudCaching$blendEnabled && HUDCaching.renderingCacheOverride && alpha < 1d) {
alpha = 1d;
}
if (changeColor((float) red, (float) green, (float) blue, (float) alpha)) {
GL11.glColor4d(red, green, blue, alpha);
}
}
public static void glColor4b(byte red, byte green, byte blue, byte alpha) {
if (!hudCaching$blendEnabled && HUDCaching.renderingCacheOverride && alpha < Byte.MAX_VALUE) {
alpha = Byte.MAX_VALUE;
}
if (changeColor(b2f(red), b2f(green), b2f(blue), b2f(alpha))) {
GL11.glColor4b(red, green, blue, alpha);
}
}
public static void glColor4ub(byte red, byte green, byte blue, byte alpha) {
if (!hudCaching$blendEnabled && HUDCaching.renderingCacheOverride && alpha < Byte.MAX_VALUE) {
alpha = Byte.MAX_VALUE;
}
if (changeColor(ub2f(red), ub2f(green), ub2f(blue), ub2f(alpha))) {
GL11.glColor4ub(red, green, blue, alpha);
}
}
public static void glColor3f(float red, float green, float blue) {
if (changeColor(red, green, blue, 1.0F)) {
GL11.glColor3f(red, green, blue);
}
}
public static void glColor3d(double red, double green, double blue) {
if (changeColor((float) red, (float) green, (float) blue, 1.0F)) {
GL11.glColor3d(red, green, blue);
}
}
public static void glColor3b(byte red, byte green, byte blue) {
if (changeColor(b2f(red), b2f(green), b2f(blue), 1.0F)) {
GL11.glColor3b(red, green, blue);
}
}
public static void glColor3ub(byte red, byte green, byte blue) {
if (changeColor(ub2f(red), ub2f(green), ub2f(blue), 1.0F)) {
GL11.glColor3ub(red, green, blue);
}
}
private static float ub2f(byte b) {
return (b & 0xFF) / 255.0F;
}
private static float b2f(byte b) {
return ((b - Byte.MIN_VALUE) & 0xFF) / 255.0F;
}
private static boolean changeColor(float red, float green, float blue, float alpha) {
// Helper function for glColor*
if (GLStateManager.BYPASS_CACHE || red != Color.red || green != Color.green || blue != Color.blue || alpha != Color.alpha || checkDirty(Dirty.COLOR)) {
Color.red = red;
Color.green = green;
Color.blue = blue;
Color.alpha = alpha;
return true;
}
return false;
}
public static void clearCurrentColor() {
// Marks the cache dirty, doesn't actually reset the color
dirty(Dirty.COLOR);
}
public static void glColorMask(boolean red, boolean green, boolean blue, boolean alpha) {
if (AngelicaConfig.enableIris) {
if (DepthColorStorage.isDepthColorLocked()) {
DepthColorStorage.deferColorMask(red, green, blue, alpha);
return;
}
}
if (GLStateManager.BYPASS_CACHE || red != ColorMask.red || green != ColorMask.green || blue != ColorMask.blue || alpha != ColorMask.alpha || checkDirty(Dirty.COLOR_MASK)) {
ColorMask.red = red;
ColorMask.green = green;
ColorMask.blue = blue;
ColorMask.alpha = alpha;
GL11.glColorMask(red, green, blue, alpha);
}
}
// Clear Color
public static void glClearColor(float red, float green, float blue, float alpha) {
if (GLStateManager.BYPASS_CACHE || red != ClearColor.red || green != ClearColor.green || blue != ClearColor.blue || alpha != ClearColor.alpha || checkDirty(Dirty.CLEAR_COLOR)) {
ClearColor.red = red;
ClearColor.green = green;
ClearColor.blue = blue;
ClearColor.alpha = alpha;
GL11.glClearColor(red, green, blue, alpha);
}
}
// ALPHA
public static void enableAlphaTest() {
if (AngelicaConfig.enableIris) {
if (AlphaTestStorage.isAlphaTestLocked()) {
AlphaTestStorage.deferAlphaTestToggle(true);
return;
}
}
alphaState.mode.enable();
}
public static void disableAlphaTest() {
if (AngelicaConfig.enableIris) {
if (AlphaTestStorage.isAlphaTestLocked()) {
AlphaTestStorage.deferAlphaTestToggle(false);
return;
}
}
alphaState.mode.disable();
}
public static void glAlphaFunc(int function, float reference) {
if (AngelicaConfig.enableIris) {
if (AlphaTestStorage.isAlphaTestLocked()) {
AlphaTestStorage.deferAlphaFunc(function, reference);
return;
}
}
alphaState.function = function;
alphaState.reference = reference;
GL11.glAlphaFunc(function, reference);
}
// Textures
public static void glActiveTexture(int texture) {
final int newTexture = texture - GL13.GL_TEXTURE0;
if (GLStateManager.BYPASS_CACHE || activeTexture != newTexture || checkDirty(Dirty.ACTIVE_TEXTURE)) {
activeTexture = newTexture;
GL13.glActiveTexture(texture);
}
}
public static void glActiveTextureARB(int texture) {
final int newTexture = texture - GL13.GL_TEXTURE0;
if (GLStateManager.BYPASS_CACHE || activeTexture != newTexture || checkDirty(Dirty.ACTIVE_TEXTURE)) {
activeTexture = newTexture;
ARBMultitexture.glActiveTextureARB(texture);
}
}
public static void glBindTexture(int target, int texture) {
if(inGLNewList) {
// Binding a texture, while building a list, is not allowed and is a silent noop
Throwable throwable = new Throwable();
LOGGER.info("Naughty naughty, someone's making a texture binding in a display list!", throwable);
return;
}
// TODO: Do we need to do the check dirty for each bound texture?
if (GLStateManager.BYPASS_CACHE || Textures[activeTexture].binding != texture || runningSplash || checkDirty(Dirty.BOUND_TEXTURE)) {
GL11.glBindTexture(target, texture);
Textures[activeTexture].binding = texture;
if (AngelicaConfig.enableIris) {
TextureTracker.INSTANCE.onBindTexture(texture);
}
}
}
public static void glTexImage2D(int target, int level, int internalformat, int width, int height, int border, int format, int type, IntBuffer pixels) {
if (AngelicaConfig.enableIris) {
// Iris
TextureInfoCache.INSTANCE.onTexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
}
GL11.glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
}
public static void glTexImage2D(int target, int level, int internalformat, int width, int height, int border, int format, int type, ByteBuffer pixels) {
if (AngelicaConfig.enableIris) {
TextureInfoCache.INSTANCE.onTexImage2D(target, level, internalformat, width, height, border, format, type, pixels != null ? pixels.asIntBuffer() : (IntBuffer) null);
}
GL11.glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
}
public static void glTexImage2D(int target, int level, int internalformat, int width, int height, int border, int format, int type, long pixels_buffer_offset) {
if (AngelicaConfig.enableIris) {
TextureInfoCache.INSTANCE.onTexImage2D(target, level, internalformat, width, height, border, format, type, pixels_buffer_offset);
}
GL11.glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels_buffer_offset);
}
public static void glDeleteTextures(int id) {
if (AngelicaConfig.enableIris) {
iris$onDeleteTexture(id);
}
Textures[activeTexture].binding = -1;
GL11.glDeleteTextures(id);
}
public static void glDeleteTextures(IntBuffer ids) {
if (AngelicaConfig.enableIris) {
for(int i = 0; i < ids.capacity(); i++) {
iris$onDeleteTexture(ids.get(i));
}
}
Textures[activeTexture].binding = -1;
GL11.glDeleteTextures(ids);
}
public static void enableTexture() {
if (AngelicaConfig.enableIris) {
// Iris
boolean updatePipeline = false;
if (activeTexture == IrisSamplers.ALBEDO_TEXTURE_UNIT) {
StateTracker.INSTANCE.albedoSampler = true;
updatePipeline = true;
} else if (activeTexture == IrisSamplers.LIGHTMAP_TEXTURE_UNIT) {
StateTracker.INSTANCE.lightmapSampler = true;
updatePipeline = true;
} else if (activeTexture == IrisSamplers.OVERLAY_TEXTURE_UNIT) {
StateTracker.INSTANCE.overlaySampler = true;
updatePipeline = true;
}
if (updatePipeline) {
Iris.getPipelineManager().getPipeline().ifPresent(p -> p.setInputs(StateTracker.INSTANCE.getInputs()));
}
}
Textures[activeTexture].mode.enable();
}
public static void disableTexture() {
if (AngelicaConfig.enableIris) {
// Iris
boolean updatePipeline = false;
if (activeTexture == IrisSamplers.ALBEDO_TEXTURE_UNIT) {
StateTracker.INSTANCE.albedoSampler = false;
updatePipeline = true;
} else if (activeTexture == IrisSamplers.LIGHTMAP_TEXTURE_UNIT) {
StateTracker.INSTANCE.lightmapSampler = false;
updatePipeline = true;
} else if (activeTexture == IrisSamplers.OVERLAY_TEXTURE_UNIT) {
StateTracker.INSTANCE.overlaySampler = false;
updatePipeline = true;
}
if (updatePipeline) {
Iris.getPipelineManager().getPipeline().ifPresent(p -> p.setInputs(StateTracker.INSTANCE.getInputs()));
}
}
Textures[activeTexture].mode.disable();
}
public static void setFilter(boolean bilinear, boolean mipmap) {
int i, j;
if (bilinear) {
i = mipmap ? GL11.GL_LINEAR_MIPMAP_LINEAR : GL11.GL_LINEAR;
j = GL11.GL_LINEAR;
} else {
i = mipmap ? GL11.GL_NEAREST_MIPMAP_LINEAR : GL11.GL_NEAREST;
j = GL11.GL_NEAREST;
}
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, i);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, j);
}
public static void glDrawArrays(int mode, int first, int count) {
// Iris -- TODO: This doesn't seem to work and is related to matchPass()
Iris.getPipelineManager().getPipeline().ifPresent(WorldRenderingPipeline::syncProgram);
GL11.glDrawArrays(mode, first, count);
}
public static void defaultBlendFunc() {
tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ZERO);
}
public static void enableCull() {
cullState.enable();
}
public static void disableCull() {
cullState.disable();
}
public static void enableDepthTest() {
depthState.mode.enable();
}
public static void disableDepthTest() {
depthState.mode.disable();
}
public static void enableLighting() {
lightingState.enable();
}
public static void disableLighting() {
lightingState.disable();
}
public static void enableRescaleNormal() {
rescaleNormalState.enable();
}
public static void disableRescaleNormal() {
rescaleNormalState.disable();
}
public static void enableFog() {
fogState.mode.enable();
if (fogToggleListener != null) {
fogToggleListener.run();
}
}
public static void disableFog() {
fogState.mode.disable();
if (fogToggleListener != null) {
fogToggleListener.run();
}
}
public static void glFog(int pname, FloatBuffer param) {
// TODO: Iris Notifier
GL11.glFog(pname, param);
if (pname == GL11.GL_FOG_COLOR) {
final float red = param.get(0);
final float green = param.get(1);
final float blue = param.get(2);
fogState.fogColor.set(red, green, blue);
fogState.fogAlpha = param.get(3);
fogState.fogColorBuffer.clear();
fogState.fogColorBuffer.put((FloatBuffer) param.position(0)).flip();
}
}
public static Vector3d getFogColor() {
return fogState.fogColor;
}
public static void fogColor(float red, float green, float blue, float alpha) {
if (GLStateManager.BYPASS_CACHE || red != fogState.fogColor.x || green != fogState.fogColor.y || blue != fogState.fogColor.z || alpha != fogState.fogAlpha) {
fogState.fogColor.set(red, green, blue);
fogState.fogAlpha = alpha;
fogState.fogColorBuffer.clear();
fogState.fogColorBuffer.put(red).put(green).put(blue).put(alpha).flip();
GL11.glFog(GL11.GL_FOG_COLOR, fogState.fogColorBuffer);
}
}
public static void glFogf(int pname, float param) {
GL11.glFogf(pname, param);
switch (pname) {
case GL11.GL_FOG_DENSITY -> {
fogState.density = param;
if (fogDensityListener != null) {
fogDensityListener.run();
}
}
case GL11.GL_FOG_START -> {
fogState.start = param;
if (fogStartListener != null) {
fogStartListener.run();
}
}
case GL11.GL_FOG_END -> {
fogState.end = param;
if (fogEndListener != null) {
fogEndListener.run();
}
}
}
}
public static void glFogi(int pname, int param) {
GL11.glFogi(pname, param);
if (pname == GL11.GL_FOG_MODE) {
fogState.fogMode = param;
if (fogModeListener != null) {
fogModeListener.run();
}
}
}
public static void setFogBlack() {
glFogf(GL11.GL_FOG_COLOR, 0.0F);
}
public static void glShadeModel(int mode) {
if (GLStateManager.BYPASS_CACHE || modelShadeMode != mode || checkDirty(Dirty.SHADE_MODEL)) {
modelShadeMode = mode;
GL11.glShadeModel(mode);
}
}
// Iris Functions
private static void iris$onDeleteTexture(int id) {
if (AngelicaConfig.enableIris) {
TextureTracker.INSTANCE.onDeleteTexture(id);
TextureInfoCache.INSTANCE.onDeleteTexture(id);
PBRTextureManager.INSTANCE.onDeleteTexture(id);
}
}
public static void setRunningSplash(boolean runningSplash) {
GLStateManager.runningSplash = runningSplash;
}
public static void makeCurrent(Drawable drawable) throws LWJGLException {
drawable.makeCurrent();
final Thread currentThread = Thread.currentThread();
CurrentThread = currentThread;
LOGGER.info("Current thread: {}", currentThread.getName());
}
public static void glNewList(int list, int mode) {
if(inGLNewList) {
throw new RuntimeException("glNewList called inside of a display list!");
}
inGLNewList = true;
GL11.glNewList(list, mode);
}
public static void glEndList() {
if(!inGLNewList) {
throw new RuntimeException("glEndList called outside of a display list!");
}
inGLNewList = false;
GL11.glEndList();
}
public static void glPushAttrib(int mask) {
// TODO: Proper state tracking; but at least for now the current cases of this didn't do anything related to textures and
// just overly broadly set ALL_BITS :facepalm:
GL11.glPushAttrib(mask & ~(GL11.GL_TEXTURE_BIT));
}
public static void glPopAttrib() {
dirty = Dirty.ALL;
GL11.glPopAttrib();
}
public static boolean checkDirty(long flag) {
if((dirty & flag ) == flag) {
dirty &= ~flag;
return true;
}
return false;
}
public static void clean(long dirtyFlag) {
dirty &= ~dirtyFlag;
}
public static void dirty(long dirtyFlag) {
dirty |= dirtyFlag;
}
}
@@ -0,0 +1,26 @@
package com.gtnewhorizons.angelica.glsm;
import net.minecraft.client.renderer.Tessellator;
public class TessellatorManager {
private static final ThreadLocal<Tessellator> theTessellator = ThreadLocal.withInitial(Tessellator::new);
private static final Thread mainThread = Thread.currentThread();
public static Tessellator get() {
if(isOnMainThread())
return Tessellator.instance;
return theTessellator.get();
}
public static boolean isOnMainThread() {
return Thread.currentThread() == mainThread;
}
public static boolean isMainInstance(Object instance) {
return instance == Tessellator.instance;
}
static {
System.out.println("[TessellatorManager] Initialized on thread " + mainThread.getName());
}
}
@@ -0,0 +1,30 @@
package com.gtnewhorizons.angelica.glsm;
import net.minecraft.block.Block;
/**
* Used to store the block bounds fields in a thread-safe manner, as instance fields don't work correctly
* on multiple threads.
*/
public class ThreadedBlockData {
public double minX, minY, minZ, maxX, maxY, maxZ;
public ThreadedBlockData() {}
public ThreadedBlockData(ThreadedBlockData other) {
this.minX = other.minX;
this.minY = other.minY;
this.minZ = other.minZ;
this.maxX = other.maxX;
this.maxY = other.maxY;
this.maxZ = other.maxZ;
}
public static ThreadedBlockData get(Block block) {
return ((Getter)block).angelica$getThreadData();
}
public interface Getter {
ThreadedBlockData angelica$getThreadData();
}
}
@@ -0,0 +1,9 @@
package com.gtnewhorizons.angelica.glsm.states;
import org.lwjgl.opengl.GL11;
public class AlphaState {
public final BooleanState mode = new BooleanState(GL11.GL_ALPHA_TEST);
public int function = GL11.GL_ALWAYS;
public float reference = -1.0F;
}
@@ -0,0 +1,13 @@
package com.gtnewhorizons.angelica.glsm.states;
import org.lwjgl.opengl.GL11;
public class BlendState {
public final BooleanState mode = new BooleanState(GL11.GL_BLEND);
public int srcRgb = GL11.GL_ONE;
public int dstRgb = GL11.GL_ZERO;
public int srcAlpha = GL11.GL_ONE;
public int dstAlpha = GL11.GL_ZERO;
}
@@ -0,0 +1,39 @@
package com.gtnewhorizons.angelica.glsm.states;
import com.gtnewhorizons.angelica.glsm.Dirty;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import lombok.Getter;
import org.lwjgl.opengl.GL11;
public class BooleanState {
private final int cap;
private final long dirtyFlag;
@Getter
private boolean enabled;
public BooleanState(int cap) {
this.cap = cap;
this.dirtyFlag = Dirty.getFlagFromCap(this.cap);
}
public void disable() {
this.setEnabled(false);
}
public void enable() {
this.setEnabled(true);
}
public void setEnabled(boolean enabled) {
if (GLStateManager.BYPASS_CACHE || enabled != this.enabled || GLStateManager.checkDirty(this.dirtyFlag)) {
this.enabled = enabled;
if (enabled) {
GL11.glEnable(this.cap);
} else {
GL11.glDisable(this.cap);
}
}
}
}
@@ -0,0 +1,9 @@
package com.gtnewhorizons.angelica.glsm.states;
public class Color4 {
public float red = 1.0F;
public float green = 1.0F;
public float blue = 1.0F;
public float alpha = 1.0F;
}
Loaded 100 of 1187 files, more files were not shown because too many files have changed in this diff. Show more