mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2025-01-28 22:04:57 +01:00
Pre-port tasks I
- Rename Client to FlywheelClient - Remove Shadow plugin - Remove generated source set - Remove unused properties in gradle.properties - Organize all imports - Thanks for the list pepper!
This commit is contained in:
parent
f89673a79e
commit
f615825846
85 changed files with 555 additions and 651 deletions
|
@ -19,4 +19,4 @@ indent_style = tab
|
||||||
ij_continuation_indent_size = 8
|
ij_continuation_indent_size = 8
|
||||||
ij_java_class_count_to_use_import_on_demand = 99
|
ij_java_class_count_to_use_import_on_demand = 99
|
||||||
ij_java_names_count_to_use_import_on_demand = 99
|
ij_java_names_count_to_use_import_on_demand = 99
|
||||||
ij_java_imports_layout = $*,|,java.**,|,javax.**,|,org.**,|,com.**,|,*
|
ij_java_imports_layout = $*, |, java.**, |, javax.**, |, org.**, |, com.**, |, *
|
||||||
|
|
169
LICENCE.md
169
LICENCE.md
|
@ -2,99 +2,75 @@
|
||||||
Version 3, 29 June 2007
|
Version 3, 29 June 2007
|
||||||
|
|
||||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
|
||||||
of this license document, but changing it is not allowed.
|
|
||||||
|
|
||||||
|
This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU
|
||||||
This version of the GNU Lesser General Public License incorporates
|
General Public License, supplemented by the additional permissions listed below.
|
||||||
the terms and conditions of version 3 of the GNU General Public
|
|
||||||
License, supplemented by the additional permissions listed below.
|
|
||||||
|
|
||||||
0. Additional Definitions.
|
0. Additional Definitions.
|
||||||
|
|
||||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
As used herein, "this License" refers to version 3 of the GNU Lesser General Public License, and the "GNU GPL" refers to
|
||||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
version 3 of the GNU General Public License.
|
||||||
General Public License.
|
|
||||||
|
|
||||||
"The Library" refers to a covered work governed by this License,
|
"The Library" refers to a covered work governed by this License, other than an Application or a Combined Work as defined
|
||||||
other than an Application or a Combined Work as defined below.
|
below.
|
||||||
|
|
||||||
An "Application" is any work that makes use of an interface provided
|
An "Application" is any work that makes use of an interface provided by the Library, but which is not otherwise based on
|
||||||
by the Library, but which is not otherwise based on the Library.
|
the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by
|
||||||
Defining a subclass of a class defined by the Library is deemed a mode
|
the Library.
|
||||||
of using an interface provided by the Library.
|
|
||||||
|
|
||||||
A "Combined Work" is a work produced by combining or linking an
|
A "Combined Work" is a work produced by combining or linking an Application with the Library. The particular version of
|
||||||
Application with the Library. The particular version of the Library
|
the Library with which the Combined Work was made is also called the "Linked Version".
|
||||||
with which the Combined Work was made is also called the "Linked
|
|
||||||
Version".
|
|
||||||
|
|
||||||
The "Minimal Corresponding Source" for a Combined Work means the
|
The "Minimal Corresponding Source" for a Combined Work means the Corresponding Source for the Combined Work, excluding
|
||||||
Corresponding Source for the Combined Work, excluding any source code
|
any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not
|
||||||
for portions of the Combined Work that, considered in isolation, are
|
on the Linked Version.
|
||||||
based on the Application, and not on the Linked Version.
|
|
||||||
|
|
||||||
The "Corresponding Application Code" for a Combined Work means the
|
The "Corresponding Application Code" for a Combined Work means the object code and/or source code for the Application,
|
||||||
object code and/or source code for the Application, including any data
|
including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the
|
||||||
and utility programs needed for reproducing the Combined Work from the
|
System Libraries of the Combined Work.
|
||||||
Application, but excluding the System Libraries of the Combined Work.
|
|
||||||
|
|
||||||
1. Exception to Section 3 of the GNU GPL.
|
1. Exception to Section 3 of the GNU GPL.
|
||||||
|
|
||||||
You may convey a covered work under sections 3 and 4 of this License
|
You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL.
|
||||||
without being bound by section 3 of the GNU GPL.
|
|
||||||
|
|
||||||
2. Conveying Modified Versions.
|
2. Conveying Modified Versions.
|
||||||
|
|
||||||
If you modify a copy of the Library, and, in your modifications, a
|
If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied
|
||||||
facility refers to a function or data to be supplied by an Application
|
by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may
|
||||||
that uses the facility (other than as an argument passed when the
|
convey a copy of the modified version:
|
||||||
facility is invoked), then you may convey a copy of the modified
|
|
||||||
version:
|
|
||||||
|
|
||||||
a) under this License, provided that you make a good faith effort to
|
a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not
|
||||||
ensure that, in the event an Application does not supply the
|
supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful,
|
||||||
function or data, the facility still operates, and performs
|
or
|
||||||
whatever part of its purpose remains meaningful, or
|
|
||||||
|
|
||||||
b) under the GNU GPL, with none of the additional permissions of
|
b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy.
|
||||||
this License applicable to that copy.
|
|
||||||
|
|
||||||
3. Object Code Incorporating Material from Library Header Files.
|
3. Object Code Incorporating Material from Library Header Files.
|
||||||
|
|
||||||
The object code form of an Application may incorporate material from
|
The object code form of an Application may incorporate material from a header file that is part of the Library. You may
|
||||||
a header file that is part of the Library. You may convey such object
|
convey such object code under terms of your choice, provided that, if the incorporated material is not limited to
|
||||||
code under terms of your choice, provided that, if the incorporated
|
numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates
|
||||||
material is not limited to numerical parameters, data structure
|
|
||||||
layouts and accessors, or small macros, inline functions and templates
|
|
||||||
(ten or fewer lines in length), you do both of the following:
|
(ten or fewer lines in length), you do both of the following:
|
||||||
|
|
||||||
a) Give prominent notice with each copy of the object code that the
|
a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its
|
||||||
Library is used in it and that the Library and its use are
|
use are covered by this License.
|
||||||
covered by this License.
|
|
||||||
|
|
||||||
b) Accompany the object code with a copy of the GNU GPL and this license
|
b) Accompany the object code with a copy of the GNU GPL and this license document.
|
||||||
document.
|
|
||||||
|
|
||||||
4. Combined Works.
|
4. Combined Works.
|
||||||
|
|
||||||
You may convey a Combined Work under terms of your choice that,
|
You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification
|
||||||
taken together, effectively do not restrict modification of the
|
of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications,
|
||||||
portions of the Library contained in the Combined Work and reverse
|
if you also do each of the following:
|
||||||
engineering for debugging such modifications, if you also do each of
|
|
||||||
the following:
|
|
||||||
|
|
||||||
a) Give prominent notice with each copy of the Combined Work that
|
a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its
|
||||||
the Library is used in it and that the Library and its use are
|
use are covered by this License.
|
||||||
covered by this License.
|
|
||||||
|
|
||||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
b) Accompany the Combined Work with a copy of the GNU GPL and this license document.
|
||||||
document.
|
|
||||||
|
|
||||||
c) For a Combined Work that displays copyright notices during
|
c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library
|
||||||
execution, include the copyright notice for the Library among
|
among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document.
|
||||||
these notices, as well as a reference directing the user to the
|
|
||||||
copies of the GNU GPL and this license document.
|
|
||||||
|
|
||||||
d) Do one of the following:
|
d) Do one of the following:
|
||||||
|
|
||||||
|
@ -113,53 +89,38 @@ d) Do one of the following:
|
||||||
of the Library that is interface-compatible with the Linked
|
of the Library that is interface-compatible with the Linked
|
||||||
Version.
|
Version.
|
||||||
|
|
||||||
e) Provide Installation Information, but only if you would otherwise
|
e) Provide Installation Information, but only if you would otherwise be required to provide such information under
|
||||||
be required to provide such information under section 6 of the
|
section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified
|
||||||
GNU GPL, and only to the extent that such information is
|
version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked
|
||||||
necessary to install and execute a modified version of the
|
Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and
|
||||||
Combined Work produced by recombining or relinking the
|
Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner
|
||||||
Application with a modified version of the Linked Version. (If
|
specified by section 6 of the GNU GPL for conveying Corresponding Source.)
|
||||||
you use option 4d0, the Installation Information must accompany
|
|
||||||
the Minimal Corresponding Source and Corresponding Application
|
|
||||||
Code. If you use option 4d1, you must provide the Installation
|
|
||||||
Information in the manner specified by section 6 of the GNU GPL
|
|
||||||
for conveying Corresponding Source.)
|
|
||||||
|
|
||||||
5. Combined Libraries.
|
5. Combined Libraries.
|
||||||
|
|
||||||
You may place library facilities that are a work based on the
|
You may place library facilities that are a work based on the Library side by side in a single library together with
|
||||||
Library side by side in a single library together with other library
|
other library facilities that are not Applications and are not covered by this License, and convey such a combined
|
||||||
facilities that are not Applications and are not covered by this
|
library under terms of your choice, if you do both of the following:
|
||||||
License, and convey such a combined library under terms of your
|
|
||||||
choice, if you do both of the following:
|
|
||||||
|
|
||||||
a) Accompany the combined library with a copy of the same work based
|
a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library
|
||||||
on the Library, uncombined with any other library facilities,
|
facilities, conveyed under the terms of this License.
|
||||||
conveyed under the terms of this License.
|
|
||||||
|
|
||||||
b) Give prominent notice with the combined library that part of it
|
b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where
|
||||||
is a work based on the Library, and explaining where to find the
|
to find the accompanying uncombined form of the same work.
|
||||||
accompanying uncombined form of the same work.
|
|
||||||
|
|
||||||
6. Revised Versions of the GNU Lesser General Public License.
|
6. Revised Versions of the GNU Lesser General Public License.
|
||||||
|
|
||||||
The Free Software Foundation may publish revised and/or new versions
|
The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time
|
||||||
of the GNU Lesser General Public License from time to time. Such new
|
to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new
|
||||||
versions will be similar in spirit to the present version, but may
|
problems or concerns.
|
||||||
differ in detail to address new problems or concerns.
|
|
||||||
|
|
||||||
Each version is given a distinguishing version number. If the
|
Each version is given a distinguishing version number. If the Library as you received it specifies that a certain
|
||||||
Library as you received it specifies that a certain numbered version
|
numbered version of the GNU Lesser General Public License "or any later version"
|
||||||
of the GNU Lesser General Public License "or any later version"
|
applies to it, you have the option of following the terms and conditions either of that published version or of any
|
||||||
applies to it, you have the option of following the terms and
|
later version published by the Free Software Foundation. If the Library as you received it does not specify a version
|
||||||
conditions either of that published version or of any later version
|
number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License
|
||||||
published by the Free Software Foundation. If the Library as you
|
ever published by the Free Software Foundation.
|
||||||
received it does not specify a version number of the GNU Lesser
|
|
||||||
General Public License, you may choose any version of the GNU Lesser
|
|
||||||
General Public License ever published by the Free Software Foundation.
|
|
||||||
|
|
||||||
If the Library as you received it specifies that a proxy can decide
|
If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General
|
||||||
whether future versions of the GNU Lesser General Public License shall
|
Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for
|
||||||
apply, that proxy's public statement of acceptance of any version is
|
you to choose that version for the Library.
|
||||||
permanent authorization for you to choose that version for the
|
|
||||||
Library.
|
|
||||||
|
|
23
README.md
23
README.md
|
@ -9,28 +9,34 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
### About
|
### About
|
||||||
The goal of this project is to provide tools for mod developers so they no longer have to worry about performance, or limitations of Minecraft's archaic rendering engine.
|
|
||||||
That said, this is primarily an outlet for me to have fun with graphics programming.
|
|
||||||
|
|
||||||
|
The goal of this project is to provide tools for mod developers so they no longer have to worry about performance, or
|
||||||
|
limitations of Minecraft's archaic rendering engine. That said, this is primarily an outlet for me to have fun with
|
||||||
|
graphics programming.
|
||||||
|
|
||||||
### Instancing
|
### Instancing
|
||||||
Flywheel provides an alternate, unified path for entity and tile entity rendering that takes advantage of GPU instancing. In doing so, Flywheel gives the developer the flexibility to define their own vertex and instance formats, and write custom shaders to ingest that data.
|
|
||||||
|
|
||||||
|
Flywheel provides an alternate, unified path for entity and tile entity rendering that takes advantage of GPU
|
||||||
|
instancing. In doing so, Flywheel gives the developer the flexibility to define their own vertex and instance formats,
|
||||||
|
and write custom shaders to ingest that data.
|
||||||
|
|
||||||
### Shaders
|
### Shaders
|
||||||
To accomodate the developer and leave more in the hands of the engine, Flywheel provides a custom shader loading and templating system to hide the details of the CPU/GPU interface. This system is a work in progress. There will be breaking changes, and I make no guarantees of backwards compatibility.
|
|
||||||
|
|
||||||
|
To accomodate the developer and leave more in the hands of the engine, Flywheel provides a custom shader loading and
|
||||||
|
templating system to hide the details of the CPU/GPU interface. This system is a work in progress. There will be
|
||||||
|
breaking changes, and I make no guarantees of backwards compatibility.
|
||||||
|
|
||||||
### Plans
|
### Plans
|
||||||
- Vanilla performance improvements
|
|
||||||
- Compute shader particles
|
|
||||||
- Deferred rendering
|
|
||||||
- Different renderers for differently aged hardware
|
|
||||||
|
|
||||||
|
- Vanilla performance improvements
|
||||||
|
- Compute shader particles
|
||||||
|
- Deferred rendering
|
||||||
|
- Different renderers for differently aged hardware
|
||||||
|
|
||||||
### Getting Started (For Developers)
|
### Getting Started (For Developers)
|
||||||
|
|
||||||
Add the following repo to your `build.gradle`:
|
Add the following repo to your `build.gradle`:
|
||||||
|
|
||||||
```groovy
|
```groovy
|
||||||
repositories {
|
repositories {
|
||||||
maven {
|
maven {
|
||||||
|
@ -41,6 +47,7 @@ repositories {
|
||||||
```
|
```
|
||||||
|
|
||||||
Then add Flywheel as a dependency:
|
Then add Flywheel as a dependency:
|
||||||
|
|
||||||
```groovy
|
```groovy
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation fg.deobf("com.jozufozu.flywheel:Flywheel:1.16-0.0.2.9")
|
implementation fg.deobf("com.jozufozu.flywheel:Flywheel:1.16-0.0.2.9")
|
||||||
|
|
|
@ -3,7 +3,7 @@ buildscript {
|
||||||
maven { url = 'https://files.minecraftforge.net/maven' }
|
maven { url = 'https://files.minecraftforge.net/maven' }
|
||||||
jcenter()
|
jcenter()
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
maven { url='https://repo.spongepowered.org/repository/maven-public/' }
|
maven { url = 'https://repo.spongepowered.org/repository/maven-public/' }
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '3.+', changing: true
|
classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '3.+', changing: true
|
||||||
|
@ -11,7 +11,6 @@ buildscript {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
plugins {
|
plugins {
|
||||||
id 'com.github.johnrengelman.shadow' version '5.2.0'
|
|
||||||
id 'com.matthewprenger.cursegradle' version '1.4.0'
|
id 'com.matthewprenger.cursegradle' version '1.4.0'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,9 +88,6 @@ mixin {
|
||||||
add sourceSets.main, "flywheel.refmap.json"
|
add sourceSets.main, "flywheel.refmap.json"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Include resources generated by data generators.
|
|
||||||
sourceSets.main.resources { srcDir 'src/generated/resources' }
|
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
maven {
|
maven {
|
||||||
name "tterrag maven"
|
name "tterrag maven"
|
||||||
|
|
|
@ -5,18 +5,10 @@ org.gradle.daemon=false
|
||||||
mod_version=0.0.3
|
mod_version=0.0.3
|
||||||
mc_update_version=1.16
|
mc_update_version=1.16
|
||||||
minecraft_version=1.16.5
|
minecraft_version=1.16.5
|
||||||
|
|
||||||
forge_version=36.0.42
|
forge_version=36.0.42
|
||||||
mcp_mappings=20200920-mixed-1.16.3
|
mcp_mappings=20200920-mixed-1.16.3
|
||||||
|
|
||||||
# dependency versions
|
|
||||||
registrate_version=1.0.4
|
|
||||||
jei_version=7.6.1.71
|
|
||||||
|
|
||||||
# curseforge information
|
|
||||||
# projectId=486392
|
|
||||||
# curse_type=beta
|
|
||||||
|
|
||||||
# github information
|
|
||||||
projectId=486392
|
projectId=486392
|
||||||
curse_type=beta
|
curse_type=beta
|
||||||
github_project=Jozufozu/Flywheel
|
github_project=Jozufozu/Flywheel
|
||||||
|
|
|
@ -1,34 +1,35 @@
|
||||||
package com.jozufozu.flywheel;
|
package com.jozufozu.flywheel;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.config.FlwConfig;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import com.jozufozu.flywheel.config.FlwCommands;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.config.FlwCommands;
|
||||||
|
import com.jozufozu.flywheel.config.FlwConfig;
|
||||||
import com.jozufozu.flywheel.config.FlwPackets;
|
import com.jozufozu.flywheel.config.FlwPackets;
|
||||||
|
|
||||||
import net.minecraftforge.api.distmarker.Dist;
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
import net.minecraftforge.common.MinecraftForge;
|
import net.minecraftforge.common.MinecraftForge;
|
||||||
import net.minecraftforge.eventbus.api.IEventBus;
|
|
||||||
import net.minecraftforge.fml.DistExecutor;
|
import net.minecraftforge.fml.DistExecutor;
|
||||||
import net.minecraftforge.fml.common.Mod;
|
import net.minecraftforge.fml.common.Mod;
|
||||||
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
|
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
|
||||||
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||||
import org.apache.logging.log4j.LogManager;
|
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
|
|
||||||
@Mod("flywheel")
|
@Mod("flywheel")
|
||||||
public class Flywheel {
|
public class Flywheel {
|
||||||
|
|
||||||
public static final String ID = "flywheel";
|
public static final String ID = "flywheel";
|
||||||
private static final Logger LOGGER = LogManager.getLogger();
|
private static final Logger LOGGER = LogManager.getLogger();
|
||||||
|
|
||||||
public Flywheel() {
|
public Flywheel() {
|
||||||
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::setup);
|
FMLJavaModLoadingContext.get()
|
||||||
|
.getModEventBus()
|
||||||
|
.addListener(this::setup);
|
||||||
|
|
||||||
MinecraftForge.EVENT_BUS.addListener(FlwCommands::onServerStarting);
|
MinecraftForge.EVENT_BUS.addListener(FlwCommands::onServerStarting);
|
||||||
|
|
||||||
FlwConfig.init();
|
FlwConfig.init();
|
||||||
|
|
||||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> Client::clientInit);
|
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> FlywheelClient::clientInit);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setup(final FMLCommonSetupEvent event) {
|
private void setup(final FMLCommonSetupEvent event) {
|
||||||
|
|
|
@ -2,20 +2,19 @@ package com.jozufozu.flywheel;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.Backend;
|
import com.jozufozu.flywheel.backend.Backend;
|
||||||
import com.jozufozu.flywheel.core.AtlasStitcher;
|
import com.jozufozu.flywheel.core.AtlasStitcher;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.core.Contexts;
|
import com.jozufozu.flywheel.core.Contexts;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.core.Materials;
|
import com.jozufozu.flywheel.core.Materials;
|
||||||
|
|
||||||
import net.minecraftforge.eventbus.api.IEventBus;
|
import net.minecraftforge.eventbus.api.IEventBus;
|
||||||
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||||
|
|
||||||
public class Client {
|
public class FlywheelClient {
|
||||||
|
|
||||||
public static void clientInit() {
|
public static void clientInit() {
|
||||||
|
|
||||||
Backend.init();
|
Backend.init();
|
||||||
IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus();
|
IEventBus modEventBus = FMLJavaModLoadingContext.get()
|
||||||
|
.getModEventBus();
|
||||||
|
|
||||||
modEventBus.addListener(AtlasStitcher.getInstance()::onTextureStitch);
|
modEventBus.addListener(AtlasStitcher.getInstance()::onTextureStitch);
|
||||||
|
|
|
@ -6,7 +6,7 @@ import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.config.FlwConfig;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
@ -16,6 +16,7 @@ import org.lwjgl.opengl.GLCapabilities;
|
||||||
import com.jozufozu.flywheel.backend.gl.versioned.GlCompat;
|
import com.jozufozu.flywheel.backend.gl.versioned.GlCompat;
|
||||||
import com.jozufozu.flywheel.backend.instancing.InstanceData;
|
import com.jozufozu.flywheel.backend.instancing.InstanceData;
|
||||||
import com.jozufozu.flywheel.backend.instancing.MaterialSpec;
|
import com.jozufozu.flywheel.backend.instancing.MaterialSpec;
|
||||||
|
import com.jozufozu.flywheel.config.FlwConfig;
|
||||||
import com.jozufozu.flywheel.core.shader.spec.ProgramSpec;
|
import com.jozufozu.flywheel.core.shader.spec.ProgramSpec;
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
|
@ -24,8 +25,6 @@ import net.minecraft.util.math.vector.Matrix4f;
|
||||||
import net.minecraft.world.IWorld;
|
import net.minecraft.world.IWorld;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
|
|
||||||
public class Backend {
|
public class Backend {
|
||||||
public static final Logger log = LogManager.getLogger(Backend.class);
|
public static final Logger log = LogManager.getLogger(Backend.class);
|
||||||
|
|
||||||
|
@ -111,7 +110,9 @@ public class Backend {
|
||||||
}
|
}
|
||||||
materialRegistry.put(name, spec);
|
materialRegistry.put(name, spec);
|
||||||
|
|
||||||
log.debug("registered material '" + name + "' with vertex size " + spec.getModelFormat().getStride() + " and instance size " + spec.getInstanceFormat().getStride());
|
log.debug("registered material '" + name + "' with vertex size " + spec.getModelFormat()
|
||||||
|
.getStride() + " and instance size " + spec.getInstanceFormat()
|
||||||
|
.getStride());
|
||||||
|
|
||||||
return spec;
|
return spec;
|
||||||
}
|
}
|
||||||
|
@ -146,11 +147,10 @@ public class Backend {
|
||||||
|
|
||||||
compat = new GlCompat(capabilities);
|
compat = new GlCompat(capabilities);
|
||||||
|
|
||||||
instancedArrays = compat.vertexArrayObjectsSupported() &&
|
instancedArrays = compat.vertexArrayObjectsSupported() && compat.drawInstancedSupported() && compat.instancedArraysSupported();
|
||||||
compat.drawInstancedSupported() &&
|
|
||||||
compat.instancedArraysSupported();
|
|
||||||
|
|
||||||
enabled = FlwConfig.get().enabled() && !OptifineHandler.usingShaders();
|
enabled = FlwConfig.get()
|
||||||
|
.enabled() && !OptifineHandler.usingShaders();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean canUseInstancing(World world) {
|
public boolean canUseInstancing(World world) {
|
||||||
|
@ -181,11 +181,9 @@ public class Backend {
|
||||||
* Used to avoid calling Flywheel functions on (fake) worlds that don't specifically support it.
|
* Used to avoid calling Flywheel functions on (fake) worlds that don't specifically support it.
|
||||||
*/
|
*/
|
||||||
public static boolean isFlywheelWorld(@Nullable IWorld world) {
|
public static boolean isFlywheelWorld(@Nullable IWorld world) {
|
||||||
if (world == null)
|
if (world == null) return false;
|
||||||
return false;
|
|
||||||
|
|
||||||
if (world instanceof IFlywheelWorld && ((IFlywheelWorld) world).supportsFlywheel())
|
if (world instanceof IFlywheelWorld && ((IFlywheelWorld) world).supportsFlywheel()) return true;
|
||||||
return true;
|
|
||||||
|
|
||||||
return world == Minecraft.getInstance().world;
|
return world == Minecraft.getInstance().world;
|
||||||
}
|
}
|
||||||
|
@ -198,5 +196,6 @@ public class Backend {
|
||||||
RenderWork.enqueue(Minecraft.getInstance().worldRenderer::loadRenderers);
|
RenderWork.enqueue(Minecraft.getInstance().worldRenderer::loadRenderers);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void init() { }
|
public static void init() {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,8 @@ import net.minecraft.util.ResourceLocation;
|
||||||
public interface IShaderContext<P extends GlProgram> {
|
public interface IShaderContext<P extends GlProgram> {
|
||||||
|
|
||||||
default P getProgram(ResourceLocation loc) {
|
default P getProgram(ResourceLocation loc) {
|
||||||
return this.getProgramSupplier(loc).get();
|
return this.getProgramSupplier(loc)
|
||||||
|
.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
Supplier<P> getProgramSupplier(ResourceLocation loc);
|
Supplier<P> getProgramSupplier(ResourceLocation loc);
|
||||||
|
|
|
@ -45,7 +45,8 @@ public class OptifineHandler {
|
||||||
|
|
||||||
if (optifine == null) {
|
if (optifine == null) {
|
||||||
Backend.log.info("Optifine not detected.");
|
Backend.log.info("Optifine not detected.");
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
Backend.log.info("Optifine detected.");
|
Backend.log.info("Optifine detected.");
|
||||||
|
|
||||||
refresh();
|
refresh();
|
||||||
|
|
|
@ -17,7 +17,8 @@ public class RenderWork {
|
||||||
@SubscribeEvent(priority = EventPriority.LOWEST)
|
@SubscribeEvent(priority = EventPriority.LOWEST)
|
||||||
public static void onRenderWorldLast(RenderWorldLastEvent event) {
|
public static void onRenderWorldLast(RenderWorldLastEvent event) {
|
||||||
while (!runs.isEmpty()) {
|
while (!runs.isEmpty()) {
|
||||||
runs.remove().run();
|
runs.remove()
|
||||||
|
.run();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,8 @@ public class ResourceUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ResourceLocation removePrefixUnchecked(ResourceLocation full, String root) {
|
public static ResourceLocation removePrefixUnchecked(ResourceLocation full, String root) {
|
||||||
return new ResourceLocation(full.getNamespace(), full.getPath().substring(root.length()));
|
return new ResourceLocation(full.getNamespace(), full.getPath()
|
||||||
|
.substring(root.length()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ResourceLocation trim(ResourceLocation loc, String prefix, String suffix) {
|
public static ResourceLocation trim(ResourceLocation loc, String prefix, String suffix) {
|
||||||
|
|
|
@ -57,7 +57,8 @@ public abstract class ShaderContext<P extends GlProgram> implements IShaderConte
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void delete() {
|
public void delete() {
|
||||||
programs.values().forEach(IMultiProgram::delete);
|
programs.values()
|
||||||
|
.forEach(IMultiProgram::delete);
|
||||||
programs.clear();
|
programs.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,15 +19,6 @@ import java.util.stream.Stream;
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.ParametersAreNonnullByDefault;
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
|
|
||||||
import com.jozufozu.flywheel.event.ForgeEvents;
|
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft;
|
|
||||||
|
|
||||||
import net.minecraft.client.world.ClientWorld;
|
|
||||||
|
|
||||||
import net.minecraftforge.event.world.WorldEvent;
|
|
||||||
|
|
||||||
import org.lwjgl.system.MemoryUtil;
|
import org.lwjgl.system.MemoryUtil;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
@ -35,6 +26,7 @@ import com.google.gson.Gson;
|
||||||
import com.google.gson.GsonBuilder;
|
import com.google.gson.GsonBuilder;
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
import com.jozufozu.flywheel.backend.gl.shader.ShaderType;
|
import com.jozufozu.flywheel.backend.gl.shader.ShaderType;
|
||||||
|
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
|
||||||
import com.jozufozu.flywheel.backend.loading.Shader;
|
import com.jozufozu.flywheel.backend.loading.Shader;
|
||||||
import com.jozufozu.flywheel.backend.loading.ShaderLoadingException;
|
import com.jozufozu.flywheel.backend.loading.ShaderLoadingException;
|
||||||
import com.jozufozu.flywheel.core.shader.spec.ProgramSpec;
|
import com.jozufozu.flywheel.core.shader.spec.ProgramSpec;
|
||||||
|
@ -44,6 +36,8 @@ import com.mojang.datafixers.util.Pair;
|
||||||
import com.mojang.serialization.DataResult;
|
import com.mojang.serialization.DataResult;
|
||||||
import com.mojang.serialization.JsonOps;
|
import com.mojang.serialization.JsonOps;
|
||||||
|
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.world.ClientWorld;
|
||||||
import net.minecraft.resources.IReloadableResourceManager;
|
import net.minecraft.resources.IReloadableResourceManager;
|
||||||
import net.minecraft.resources.IResource;
|
import net.minecraft.resources.IResource;
|
||||||
import net.minecraft.resources.IResourceManager;
|
import net.minecraft.resources.IResourceManager;
|
||||||
|
@ -84,7 +78,8 @@ public class ShaderSources implements ISelectiveResourceReloadListener {
|
||||||
shouldCrash = false;
|
shouldCrash = false;
|
||||||
|
|
||||||
backend.clearContexts();
|
backend.clearContexts();
|
||||||
ModLoader.get().postEvent(new GatherContextEvent(backend));
|
ModLoader.get()
|
||||||
|
.postEvent(new GatherContextEvent(backend));
|
||||||
|
|
||||||
loadProgramSpecs(manager);
|
loadProgramSpecs(manager);
|
||||||
loadShaderSources(manager);
|
loadShaderSources(manager);
|
||||||
|
@ -123,7 +118,9 @@ public class ShaderSources implements ISelectiveResourceReloadListener {
|
||||||
|
|
||||||
DataResult<Pair<ProgramSpec, JsonElement>> result = ProgramSpec.CODEC.decode(JsonOps.INSTANCE, GSON.fromJson(s, JsonElement.class));
|
DataResult<Pair<ProgramSpec, JsonElement>> result = ProgramSpec.CODEC.decode(JsonOps.INSTANCE, GSON.fromJson(s, JsonElement.class));
|
||||||
|
|
||||||
ProgramSpec spec = result.get().orThrow().getFirst();
|
ProgramSpec spec = result.get()
|
||||||
|
.orThrow()
|
||||||
|
.getFirst();
|
||||||
|
|
||||||
spec.setName(specName);
|
spec.setName(specName);
|
||||||
|
|
||||||
|
@ -210,7 +207,8 @@ public class ShaderSources implements ISelectiveResourceReloadListener {
|
||||||
|
|
||||||
while (filechannel.read(bytebuffer) != -1) {
|
while (filechannel.read(bytebuffer) != -1) {
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
bytebuffer = MemoryUtil.memAlloc(8192);
|
bytebuffer = MemoryUtil.memAlloc(8192);
|
||||||
ReadableByteChannel readablebytechannel = Channels.newChannel(is);
|
ReadableByteChannel readablebytechannel = Channels.newChannel(is);
|
||||||
|
|
||||||
|
|
|
@ -53,9 +53,11 @@ public enum GlNumericType {
|
||||||
public void castAndBuffer(ByteBuffer buf, int val) {
|
public void castAndBuffer(ByteBuffer buf, int val) {
|
||||||
if (this == UBYTE || this == BYTE) {
|
if (this == UBYTE || this == BYTE) {
|
||||||
buf.put((byte) val);
|
buf.put((byte) val);
|
||||||
} else if (this == USHORT || this == SHORT) {
|
}
|
||||||
|
else if (this == USHORT || this == SHORT) {
|
||||||
buf.putShort((short) val);
|
buf.putShort((short) val);
|
||||||
} else if (this == UINT || this == INT) {
|
}
|
||||||
|
else if (this == UINT || this == INT) {
|
||||||
buf.putInt(val);
|
buf.putInt(val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,7 +56,8 @@ public class GlBuffer extends GlObject {
|
||||||
public MappedBuffer getBuffer(int offset, int length) {
|
public MappedBuffer getBuffer(int offset, int length) {
|
||||||
if (Backend.getInstance().compat.mapBufferRange != MapBufferRange.UNSUPPORTED) {
|
if (Backend.getInstance().compat.mapBufferRange != MapBufferRange.UNSUPPORTED) {
|
||||||
return new MappedBufferRange(this, offset, length, GL30.GL_MAP_WRITE_BIT);
|
return new MappedBufferRange(this, offset, length, GL30.GL_MAP_WRITE_BIT);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
MappedFullBuffer fullBuffer = new MappedFullBuffer(this, MappedBufferUsage.WRITE_ONLY);
|
MappedFullBuffer fullBuffer = new MappedFullBuffer(this, MappedBufferUsage.WRITE_ONLY);
|
||||||
fullBuffer.position(offset);
|
fullBuffer.position(offset);
|
||||||
return fullBuffer;
|
return fullBuffer;
|
||||||
|
|
|
@ -39,8 +39,8 @@ public class VecBuffer {
|
||||||
for (float f : floats) {
|
for (float f : floats) {
|
||||||
internal.putFloat(f);
|
internal.putFloat(f);
|
||||||
}
|
}
|
||||||
// internal.asFloatBuffer().put(floats);
|
// internal.asFloatBuffer().put(floats);
|
||||||
// internal.position(internal.position() + floats.length * 4);
|
// internal.position(internal.position() + floats.length * 4);
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,7 +79,10 @@ public class GlCompat {
|
||||||
throw new IllegalStateException("");
|
throw new IllegalStateException("");
|
||||||
}
|
}
|
||||||
|
|
||||||
return Arrays.stream(constants).filter(it -> it.supported(caps)).findFirst().get();
|
return Arrays.stream(constants)
|
||||||
|
.filter(it -> it.supported(caps))
|
||||||
|
.findFirst()
|
||||||
|
.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -61,8 +61,7 @@ public abstract class InstanceManager<T> implements MaterialManager.OriginShiftL
|
||||||
int dY = pos.getY() - cY;
|
int dY = pos.getY() - cY;
|
||||||
int dZ = pos.getZ() - cZ;
|
int dZ = pos.getZ() - cZ;
|
||||||
|
|
||||||
if ((tick % getUpdateDivisor(dX, dY, dZ)) == 0)
|
if ((tick % getUpdateDivisor(dX, dY, dZ)) == 0) instance.tick();
|
||||||
instance.tick();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,16 +87,18 @@ public abstract class InstanceManager<T> implements MaterialManager.OriginShiftL
|
||||||
int cZ = (int) info.getProjectedView().z;
|
int cZ = (int) info.getProjectedView().z;
|
||||||
|
|
||||||
if (dynamicInstances.size() > 0) {
|
if (dynamicInstances.size() > 0) {
|
||||||
dynamicInstances.object2ObjectEntrySet().fastForEach(e -> {
|
dynamicInstances.object2ObjectEntrySet()
|
||||||
IDynamicInstance dyn = e.getValue();
|
.fastForEach(e -> {
|
||||||
if (!dyn.decreaseFramerateWithDistance() || shouldFrameUpdate(dyn.getWorldPosition(), lookX, lookY, lookZ, cX, cY, cZ))
|
IDynamicInstance dyn = e.getValue();
|
||||||
dyn.beginFrame();
|
if (!dyn.decreaseFramerateWithDistance() || shouldFrameUpdate(dyn.getWorldPosition(), lookX, lookY, lookZ, cX, cY, cZ))
|
||||||
});
|
dyn.beginFrame();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void add(T obj) {
|
public void add(T obj) {
|
||||||
if (!Backend.getInstance().canUseInstancing()) return;
|
if (!Backend.getInstance()
|
||||||
|
.canUseInstancing()) return;
|
||||||
|
|
||||||
if (obj instanceof IInstanceRendered) {
|
if (obj instanceof IInstanceRendered) {
|
||||||
addInternal(obj);
|
addInternal(obj);
|
||||||
|
@ -105,13 +106,15 @@ public abstract class InstanceManager<T> implements MaterialManager.OriginShiftL
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void queueAdd(T obj) {
|
public synchronized void queueAdd(T obj) {
|
||||||
if (!Backend.getInstance().canUseInstancing()) return;
|
if (!Backend.getInstance()
|
||||||
|
.canUseInstancing()) return;
|
||||||
|
|
||||||
queuedAdditions.add(obj);
|
queuedAdditions.add(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void update(T obj) {
|
public void update(T obj) {
|
||||||
if (!Backend.getInstance().canUseInstancing()) return;
|
if (!Backend.getInstance()
|
||||||
|
.canUseInstancing()) return;
|
||||||
|
|
||||||
if (obj instanceof IInstanceRendered) {
|
if (obj instanceof IInstanceRendered) {
|
||||||
IInstance instance = getInstance(obj, false);
|
IInstance instance = getInstance(obj, false);
|
||||||
|
@ -122,7 +125,8 @@ public abstract class InstanceManager<T> implements MaterialManager.OriginShiftL
|
||||||
removeInternal(obj, instance);
|
removeInternal(obj, instance);
|
||||||
|
|
||||||
createInternal(obj);
|
createInternal(obj);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
instance.update();
|
instance.update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -130,29 +134,30 @@ public abstract class InstanceManager<T> implements MaterialManager.OriginShiftL
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void queueUpdate(T obj) {
|
public synchronized void queueUpdate(T obj) {
|
||||||
if (!Backend.getInstance().canUseInstancing()) return;
|
if (!Backend.getInstance()
|
||||||
|
.canUseInstancing()) return;
|
||||||
|
|
||||||
queuedUpdates.add(obj);
|
queuedUpdates.add(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onLightUpdate(T obj) {
|
public void onLightUpdate(T obj) {
|
||||||
if (!Backend.getInstance().canUseInstancing()) return;
|
if (!Backend.getInstance()
|
||||||
|
.canUseInstancing()) return;
|
||||||
|
|
||||||
if (obj instanceof IInstanceRendered) {
|
if (obj instanceof IInstanceRendered) {
|
||||||
IInstance instance = getInstance(obj, false);
|
IInstance instance = getInstance(obj, false);
|
||||||
|
|
||||||
if (instance != null)
|
if (instance != null) instance.updateLight();
|
||||||
instance.updateLight();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void remove(T obj) {
|
public void remove(T obj) {
|
||||||
if (!Backend.getInstance().canUseInstancing()) return;
|
if (!Backend.getInstance()
|
||||||
|
.canUseInstancing()) return;
|
||||||
|
|
||||||
if (obj instanceof IInstanceRendered) {
|
if (obj instanceof IInstanceRendered) {
|
||||||
IInstance instance = getInstance(obj, false);
|
IInstance instance = getInstance(obj, false);
|
||||||
if (instance != null)
|
if (instance != null) removeInternal(obj, instance);
|
||||||
removeInternal(obj, instance);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,15 +170,18 @@ public abstract class InstanceManager<T> implements MaterialManager.OriginShiftL
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Nullable
|
@Nullable
|
||||||
protected <I extends T> IInstance getInstance(I obj, boolean create) {
|
protected <I extends T> IInstance getInstance(I obj, boolean create) {
|
||||||
if (!Backend.getInstance().canUseInstancing()) return null;
|
if (!Backend.getInstance()
|
||||||
|
.canUseInstancing()) return null;
|
||||||
|
|
||||||
IInstance instance = instances.get(obj);
|
IInstance instance = instances.get(obj);
|
||||||
|
|
||||||
if (instance != null) {
|
if (instance != null) {
|
||||||
return instance;
|
return instance;
|
||||||
} else if (create && canCreateInstance(obj)) {
|
}
|
||||||
|
else if (create && canCreateInstance(obj)) {
|
||||||
return createInternal(obj);
|
return createInternal(obj);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -222,11 +230,9 @@ public abstract class InstanceManager<T> implements MaterialManager.OriginShiftL
|
||||||
renderer.updateLight();
|
renderer.updateLight();
|
||||||
instances.put(obj, renderer);
|
instances.put(obj, renderer);
|
||||||
|
|
||||||
if (renderer instanceof IDynamicInstance)
|
if (renderer instanceof IDynamicInstance) dynamicInstances.put(obj, (IDynamicInstance) renderer);
|
||||||
dynamicInstances.put(obj, (IDynamicInstance) renderer);
|
|
||||||
|
|
||||||
if (renderer instanceof ITickableInstance)
|
if (renderer instanceof ITickableInstance) tickableInstances.put(obj, ((ITickableInstance) renderer));
|
||||||
tickableInstances.put(obj, ((ITickableInstance) renderer));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return renderer;
|
return renderer;
|
||||||
|
|
|
@ -55,7 +55,10 @@ public class InstanceMaterial<D extends InstanceData> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean nothingToRender() {
|
public boolean nothingToRender() {
|
||||||
return models.size() > 0 && models.asMap().values().stream().allMatch(Instancer::empty);
|
return models.size() > 0 && models.asMap()
|
||||||
|
.values()
|
||||||
|
.stream()
|
||||||
|
.allMatch(Instancer::empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void delete() {
|
public void delete() {
|
||||||
|
@ -66,11 +69,14 @@ public class InstanceMaterial<D extends InstanceData> {
|
||||||
* Clear all instance data without freeing resources.
|
* Clear all instance data without freeing resources.
|
||||||
*/
|
*/
|
||||||
public void clear() {
|
public void clear() {
|
||||||
models.asMap().values().forEach(Instancer::clear);
|
models.asMap()
|
||||||
|
.values()
|
||||||
|
.forEach(Instancer::clear);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void forEachInstancer(Consumer<Instancer<D>> f) {
|
public void forEachInstancer(Consumer<Instancer<D>> f) {
|
||||||
for (Instancer<D> model : models.asMap().values()) {
|
for (Instancer<D> model : models.asMap()
|
||||||
|
.values()) {
|
||||||
f.accept(model);
|
f.accept(model);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -84,8 +90,7 @@ public class InstanceMaterial<D extends InstanceData> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Instancer<D> getModel(PartialModel partial, BlockState referenceState, Direction dir, Supplier<MatrixStack> modelTransform) {
|
public Instancer<D> getModel(PartialModel partial, BlockState referenceState, Direction dir, Supplier<MatrixStack> modelTransform) {
|
||||||
return get(Pair.of(dir, partial),
|
return get(Pair.of(dir, partial), () -> buildModel(partial.get(), referenceState, modelTransform.get()));
|
||||||
() -> buildModel(partial.get(), referenceState, modelTransform.get()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Instancer<D> getModel(BlockState toRender) {
|
public Instancer<D> getModel(BlockState toRender) {
|
||||||
|
@ -102,7 +107,8 @@ public class InstanceMaterial<D extends InstanceData> {
|
||||||
}
|
}
|
||||||
|
|
||||||
private BufferedModel buildModel(BlockState renderedState) {
|
private BufferedModel buildModel(BlockState renderedState) {
|
||||||
BlockRendererDispatcher dispatcher = Minecraft.getInstance().getBlockRendererDispatcher();
|
BlockRendererDispatcher dispatcher = Minecraft.getInstance()
|
||||||
|
.getBlockRendererDispatcher();
|
||||||
return buildModel(dispatcher.getModelForState(renderedState), renderedState);
|
return buildModel(dispatcher.getModelForState(renderedState), renderedState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,16 +159,15 @@ public class InstanceMaterial<D extends InstanceData> {
|
||||||
BlockModelRenderer blockRenderer = dispatcher.getBlockModelRenderer();
|
BlockModelRenderer blockRenderer = dispatcher.getBlockModelRenderer();
|
||||||
BufferBuilder builder = new BufferBuilder(512);
|
BufferBuilder builder = new BufferBuilder(512);
|
||||||
|
|
||||||
// BakedQuadWrapper quadReader = new BakedQuadWrapper();
|
// BakedQuadWrapper quadReader = new BakedQuadWrapper();
|
||||||
//
|
//
|
||||||
// IModelData modelData = model.getModelData(mc.world, BlockPos.ZERO.up(255), referenceState, VirtualEmptyModelData.INSTANCE);
|
// IModelData modelData = model.getModelData(mc.world, BlockPos.ZERO.up(255), referenceState, VirtualEmptyModelData.INSTANCE);
|
||||||
// List<BakedQuad> quads = Arrays.stream(dirs)
|
// List<BakedQuad> quads = Arrays.stream(dirs)
|
||||||
// .flatMap(dir -> model.getQuads(referenceState, dir, mc.world.rand, modelData).stream())
|
// .flatMap(dir -> model.getQuads(referenceState, dir, mc.world.rand, modelData).stream())
|
||||||
// .collect(Collectors.toList());
|
// .collect(Collectors.toList());
|
||||||
|
|
||||||
builder.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK);
|
builder.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK);
|
||||||
blockRenderer.renderModel(mc.world, model, referenceState, BlockPos.ZERO.up(255), ms, builder, true,
|
blockRenderer.renderModel(mc.world, model, referenceState, BlockPos.ZERO.up(255), ms, builder, true, mc.world.rand, 42, OverlayTexture.DEFAULT_UV, VirtualEmptyModelData.INSTANCE);
|
||||||
mc.world.rand, 42, OverlayTexture.DEFAULT_UV, VirtualEmptyModelData.INSTANCE);
|
|
||||||
builder.finishDrawing();
|
builder.finishDrawing();
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,7 +109,8 @@ public class InstancedRenderDispatcher {
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public static void renderLayer(RenderLayerEvent event) {
|
public static void renderLayer(RenderLayerEvent event) {
|
||||||
ClientWorld world = event.getWorld();
|
ClientWorld world = event.getWorld();
|
||||||
if (!Backend.getInstance().canUseInstancing(world)) return;
|
if (!Backend.getInstance()
|
||||||
|
.canUseInstancing(world)) return;
|
||||||
|
|
||||||
event.type.startDrawing();
|
event.type.startDrawing();
|
||||||
|
|
||||||
|
@ -122,7 +123,8 @@ public class InstancedRenderDispatcher {
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public static void onReloadRenderers(ReloadRenderersEvent event) {
|
public static void onReloadRenderers(ReloadRenderersEvent event) {
|
||||||
ClientWorld world = event.getWorld();
|
ClientWorld world = event.getWorld();
|
||||||
if (Backend.getInstance().canUseInstancing() && world != null) {
|
if (Backend.getInstance()
|
||||||
|
.canUseInstancing() && world != null) {
|
||||||
loadAllInWorld(world);
|
loadAllInWorld(world);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -130,7 +132,8 @@ public class InstancedRenderDispatcher {
|
||||||
private static final RenderType crumblingLayer = ModelBakery.BLOCK_DESTRUCTION_RENDER_LAYERS.get(0);
|
private static final RenderType crumblingLayer = ModelBakery.BLOCK_DESTRUCTION_RENDER_LAYERS.get(0);
|
||||||
|
|
||||||
public static void renderBreaking(ClientWorld world, Matrix4f viewProjection, double cameraX, double cameraY, double cameraZ) {
|
public static void renderBreaking(ClientWorld world, Matrix4f viewProjection, double cameraX, double cameraY, double cameraZ) {
|
||||||
if (!Backend.getInstance().canUseInstancing(world)) return;
|
if (!Backend.getInstance()
|
||||||
|
.canUseInstancing(world)) return;
|
||||||
|
|
||||||
WorldRenderer worldRenderer = Minecraft.getInstance().worldRenderer;
|
WorldRenderer worldRenderer = Minecraft.getInstance().worldRenderer;
|
||||||
Long2ObjectMap<SortedSet<DestroyBlockProgress>> breakingProgressions = worldRenderer.blockBreakingProgressions;
|
Long2ObjectMap<SortedSet<DestroyBlockProgress>> breakingProgressions = worldRenderer.blockBreakingProgressions;
|
||||||
|
@ -145,9 +148,11 @@ public class InstancedRenderDispatcher {
|
||||||
|
|
||||||
SortedSet<DestroyBlockProgress> progresses = entry.getValue();
|
SortedSet<DestroyBlockProgress> progresses = entry.getValue();
|
||||||
if (progresses != null && !progresses.isEmpty()) {
|
if (progresses != null && !progresses.isEmpty()) {
|
||||||
int blockDamage = progresses.last().getPartialBlockDamage();
|
int blockDamage = progresses.last()
|
||||||
|
.getPartialBlockDamage();
|
||||||
bitSet.set(blockDamage);
|
bitSet.set(blockDamage);
|
||||||
renderers.get(blockDamage).add(world.getTileEntity(breakingPos));
|
renderers.get(blockDamage)
|
||||||
|
.add(world.getTileEntity(breakingPos));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,38 +160,41 @@ public class InstancedRenderDispatcher {
|
||||||
ActiveRenderInfo info = Minecraft.getInstance().gameRenderer.getActiveRenderInfo();
|
ActiveRenderInfo info = Minecraft.getInstance().gameRenderer.getActiveRenderInfo();
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_2D, textureManager.getTexture(PlayerContainer.BLOCK_ATLAS_TEXTURE).getGlTextureId());
|
glBindTexture(GL_TEXTURE_2D, textureManager.getTexture(PlayerContainer.BLOCK_ATLAS_TEXTURE)
|
||||||
|
.getGlTextureId());
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE4);
|
glActiveTexture(GL_TEXTURE4);
|
||||||
|
|
||||||
crumblingLayer.startDrawing();
|
crumblingLayer.startDrawing();
|
||||||
bitSet.stream().forEach(i -> {
|
bitSet.stream()
|
||||||
Texture breaking = textureManager.getTexture(ModelBakery.BLOCK_DESTRUCTION_STAGE_TEXTURES.get(i));
|
.forEach(i -> {
|
||||||
CrumblingInstanceManager renderer = renderers.get(i);
|
Texture breaking = textureManager.getTexture(ModelBakery.BLOCK_DESTRUCTION_STAGE_TEXTURES.get(i));
|
||||||
renderer.beginFrame(info);
|
CrumblingInstanceManager renderer = renderers.get(i);
|
||||||
|
renderer.beginFrame(info);
|
||||||
|
|
||||||
if (breaking != null) {
|
if (breaking != null) {
|
||||||
glBindTexture(GL_TEXTURE_2D, breaking.getGlTextureId());
|
glBindTexture(GL_TEXTURE_2D, breaking.getGlTextureId());
|
||||||
renderer.materialManager.render(RenderType.getCutoutMipped(), viewProjection, cameraX, cameraY, cameraZ);
|
renderer.materialManager.render(RenderType.getCutoutMipped(), viewProjection, cameraX, cameraY, cameraZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderer.invalidate();
|
renderer.invalidate();
|
||||||
});
|
});
|
||||||
crumblingLayer.endDrawing();
|
crumblingLayer.endDrawing();
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
Texture breaking = textureManager.getTexture(ModelBakery.BLOCK_DESTRUCTION_STAGE_TEXTURES.get(0));
|
Texture breaking = textureManager.getTexture(ModelBakery.BLOCK_DESTRUCTION_STAGE_TEXTURES.get(0));
|
||||||
if (breaking != null)
|
if (breaking != null) glBindTexture(GL_TEXTURE_2D, breaking.getGlTextureId());
|
||||||
glBindTexture(GL_TEXTURE_2D, breaking.getGlTextureId());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void loadAllInWorld(ClientWorld world) {
|
public static void loadAllInWorld(ClientWorld world) {
|
||||||
Contexts.WORLD.getMaterialManager(world).delete();
|
Contexts.WORLD.getMaterialManager(world)
|
||||||
|
.delete();
|
||||||
|
|
||||||
TileInstanceManager tiles = tileInstanceManager.replace(world);
|
TileInstanceManager tiles = tileInstanceManager.replace(world);
|
||||||
world.loadedTileEntityList.forEach(tiles::add);
|
world.loadedTileEntityList.forEach(tiles::add);
|
||||||
|
|
||||||
EntityInstanceManager entities = entityInstanceManager.replace(world);
|
EntityInstanceManager entities = entityInstanceManager.replace(world);
|
||||||
world.getAllEntities().forEach(entities::add);
|
world.getAllEntities()
|
||||||
|
.forEach(entities::add);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,8 +65,7 @@ public class Instancer<D extends InstanceData> {
|
||||||
vao.bind();
|
vao.bind();
|
||||||
renderSetup();
|
renderSetup();
|
||||||
|
|
||||||
if (glInstanceCount > 0)
|
if (glInstanceCount > 0) model.drawInstances(glInstanceCount);
|
||||||
model.drawInstances(glInstanceCount);
|
|
||||||
|
|
||||||
vao.unbind();
|
vao.unbind();
|
||||||
}
|
}
|
||||||
|
@ -160,12 +159,13 @@ public class Instancer<D extends InstanceData> {
|
||||||
if (length > 0) {
|
if (length > 0) {
|
||||||
MappedBuffer mapped = instanceVBO.getBuffer(offset, length);
|
MappedBuffer mapped = instanceVBO.getBuffer(offset, length);
|
||||||
|
|
||||||
dirtySet.stream().forEach(i -> {
|
dirtySet.stream()
|
||||||
final D d = data.get(i);
|
.forEach(i -> {
|
||||||
|
final D d = data.get(i);
|
||||||
|
|
||||||
mapped.position(i * stride);
|
mapped.position(i * stride);
|
||||||
d.write(mapped);
|
d.write(mapped);
|
||||||
});
|
});
|
||||||
mapped.flush();
|
mapped.flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -236,7 +236,8 @@ public class Instancer<D extends InstanceData> {
|
||||||
|
|
||||||
anyToUpdate = true;
|
anyToUpdate = true;
|
||||||
|
|
||||||
data.subList(newSize, oldSize).clear();
|
data.subList(newSize, oldSize)
|
||||||
|
.clear();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,9 @@ public class MaterialManager<P extends WorldProgram> {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
|
|
||||||
this.atlasMaterials = new HashMap<>();
|
this.atlasMaterials = new HashMap<>();
|
||||||
this.atlasRenderers = new ArrayList<>(Backend.getInstance().allMaterials().size());
|
this.atlasRenderers = new ArrayList<>(Backend.getInstance()
|
||||||
|
.allMaterials()
|
||||||
|
.size());
|
||||||
|
|
||||||
this.materials = new HashMap<>();
|
this.materials = new HashMap<>();
|
||||||
this.renderers = new HashMap<>();
|
this.renderers = new HashMap<>();
|
||||||
|
@ -90,8 +92,13 @@ public class MaterialManager<P extends WorldProgram> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void delete() {
|
public void delete() {
|
||||||
atlasMaterials.values().forEach(InstanceMaterial::delete);
|
atlasMaterials.values()
|
||||||
materials.values().stream().flatMap(m -> m.values().stream()).forEach(InstanceMaterial::delete);
|
.forEach(InstanceMaterial::delete);
|
||||||
|
materials.values()
|
||||||
|
.stream()
|
||||||
|
.flatMap(m -> m.values()
|
||||||
|
.stream())
|
||||||
|
.forEach(InstanceMaterial::delete);
|
||||||
|
|
||||||
atlasMaterials.clear();
|
atlasMaterials.clear();
|
||||||
atlasRenderers.clear();
|
atlasRenderers.clear();
|
||||||
|
@ -151,8 +158,13 @@ public class MaterialManager<P extends WorldProgram> {
|
||||||
|
|
||||||
originCoordinate = new BlockPos(cX, cY, cZ);
|
originCoordinate = new BlockPos(cX, cY, cZ);
|
||||||
|
|
||||||
materials.values().stream().flatMap(m -> m.values().stream()).forEach(InstanceMaterial::clear);
|
materials.values()
|
||||||
atlasMaterials.values().forEach(InstanceMaterial::clear);
|
.stream()
|
||||||
|
.flatMap(m -> m.values()
|
||||||
|
.stream())
|
||||||
|
.forEach(InstanceMaterial::clear);
|
||||||
|
atlasMaterials.values()
|
||||||
|
.forEach(InstanceMaterial::clear);
|
||||||
listeners.forEach(OriginShiftListener::onOriginShift);
|
listeners.forEach(OriginShiftListener::onOriginShift);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ import net.minecraft.world.World;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The layer between a {@link TileEntity} and the Flywheel backend.
|
* The layer between a {@link TileEntity} and the Flywheel backend.
|
||||||
**
|
* *
|
||||||
* <br><br> There are a few additional features that overriding classes can opt in to:
|
* <br><br> There are a few additional features that overriding classes can opt in to:
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>{@link IDynamicInstance}</li>
|
* <li>{@link IDynamicInstance}</li>
|
||||||
|
@ -94,11 +94,7 @@ public abstract class EntityInstance<E extends Entity> implements IInstance {
|
||||||
public Vector3f getInstancePosition() {
|
public Vector3f getInstancePosition() {
|
||||||
Vector3d pos = entity.getPositionVec();
|
Vector3d pos = entity.getPositionVec();
|
||||||
Vector3i origin = materialManager.getOriginCoordinate();
|
Vector3i origin = materialManager.getOriginCoordinate();
|
||||||
return new Vector3f(
|
return new Vector3f((float) (pos.x - origin.getX()), (float) (pos.y - origin.getY()), (float) (pos.z - origin.getZ()));
|
||||||
(float) (pos.x - origin.getX()),
|
|
||||||
(float) (pos.y - origin.getY()),
|
|
||||||
(float) (pos.z - origin.getZ())
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -119,7 +115,8 @@ public abstract class EntityInstance<E extends Entity> implements IInstance {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected <L extends IFlatLight<?>> void relight(int block, int sky, Stream<L> models) {
|
protected <L extends IFlatLight<?>> void relight(int block, int sky, Stream<L> models) {
|
||||||
models.forEach(model -> model.setBlockLight(block).setSkyLight(sky));
|
models.forEach(model -> model.setBlockLight(block)
|
||||||
|
.setSkyLight(sky));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected InstanceMaterial<ModelData> getTransformMaterial() {
|
protected InstanceMaterial<ModelData> getTransformMaterial() {
|
||||||
|
|
|
@ -19,7 +19,8 @@ public class EntityInstanceManager extends InstanceManager<Entity> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected IInstance createRaw(Entity obj) {
|
protected IInstance createRaw(Entity obj) {
|
||||||
return InstancedRenderRegistry.getInstance().create(materialManager, obj);
|
return InstancedRenderRegistry.getInstance()
|
||||||
|
.create(materialManager, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -117,7 +117,8 @@ public abstract class TileEntityInstance<T extends TileEntity> implements IInsta
|
||||||
}
|
}
|
||||||
|
|
||||||
protected <L extends IFlatLight<?>> void relight(int block, int sky, Stream<L> models) {
|
protected <L extends IFlatLight<?>> void relight(int block, int sky, Stream<L> models) {
|
||||||
models.forEach(model -> model.setBlockLight(block).setSkyLight(sky));
|
models.forEach(model -> model.setBlockLight(block)
|
||||||
|
.setSkyLight(sky));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected InstanceMaterial<ModelData> getTransformMaterial() {
|
protected InstanceMaterial<ModelData> getTransformMaterial() {
|
||||||
|
|
|
@ -19,7 +19,8 @@ public class TileInstanceManager extends InstanceManager<TileEntity> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected IInstance createRaw(TileEntity obj) {
|
protected IInstance createRaw(TileEntity obj) {
|
||||||
return InstancedRenderRegistry.getInstance().create(materialManager, obj);
|
return InstancedRenderRegistry.getInstance()
|
||||||
|
.create(materialManager, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -33,7 +33,9 @@ public class InstancedArraysTemplate extends ProgramTemplate {
|
||||||
public void attachAttributes(Program builder) {
|
public void attachAttributes(Program builder) {
|
||||||
Shader shader = builder.attached.get(ShaderType.VERTEX);
|
Shader shader = builder.attached.get(ShaderType.VERTEX);
|
||||||
|
|
||||||
shader.getTag(vertexData).addPrefixedAttributes(builder, vertexPrefix);
|
shader.getTag(vertexData)
|
||||||
shader.getTag(instanceData).addPrefixedAttributes(builder, instancePrefix);
|
.addPrefixedAttributes(builder, vertexPrefix);
|
||||||
|
shader.getTag(instanceData)
|
||||||
|
.addPrefixedAttributes(builder, instancePrefix);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@ public class ModelTemplate extends ProgramTemplate {
|
||||||
public void attachAttributes(Program builder) {
|
public void attachAttributes(Program builder) {
|
||||||
Shader shader = builder.attached.get(ShaderType.VERTEX);
|
Shader shader = builder.attached.get(ShaderType.VERTEX);
|
||||||
|
|
||||||
shader.getTag(vertexData).addPrefixedAttributes(builder, vertexPrefix);
|
shader.getTag(vertexData)
|
||||||
|
.addPrefixedAttributes(builder, vertexPrefix);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,7 +72,9 @@ public class Shader {
|
||||||
|
|
||||||
if (matcher.find()) {
|
if (matcher.find()) {
|
||||||
StringBuffer sourceWithDefines = new StringBuffer();
|
StringBuffer sourceWithDefines = new StringBuffer();
|
||||||
String lines = defines.stream().map(it -> "#define " + it).collect(Collectors.joining("\n"));
|
String lines = defines.stream()
|
||||||
|
.map(it -> "#define " + it)
|
||||||
|
.collect(Collectors.joining("\n"));
|
||||||
|
|
||||||
matcher.appendReplacement(sourceWithDefines, matcher.group() + '\n' + lines);
|
matcher.appendReplacement(sourceWithDefines, matcher.group() + '\n' + lines);
|
||||||
|
|
||||||
|
@ -92,7 +94,8 @@ public class Shader {
|
||||||
|
|
||||||
structs.add(struct);
|
structs.add(struct);
|
||||||
|
|
||||||
String replacement = decorator.matcher(struct.source).replaceFirst("");
|
String replacement = decorator.matcher(struct.source)
|
||||||
|
.replaceFirst("");
|
||||||
structMatcher.appendReplacement(strippedSrc, replacement);
|
structMatcher.appendReplacement(strippedSrc, replacement);
|
||||||
|
|
||||||
tag2Struct.put(struct.tag, struct);
|
tag2Struct.put(struct.tag, struct);
|
||||||
|
@ -138,12 +141,14 @@ public class Shader {
|
||||||
public String printSource() {
|
public String printSource() {
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
|
|
||||||
builder.append("Source for shader '").append(name).append("':\n");
|
builder.append("Source for shader '")
|
||||||
|
.append(name)
|
||||||
|
.append("':\n");
|
||||||
int i = 1;
|
int i = 1;
|
||||||
for (String s : source.split("\n")) {
|
for (String s : source.split("\n")) {
|
||||||
builder.append(String.format("%1$4s: ", i++))
|
builder.append(String.format("%1$4s: ", i++))
|
||||||
.append(s)
|
.append(s)
|
||||||
.append('\n');
|
.append('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
return builder.toString();
|
return builder.toString();
|
||||||
|
|
|
@ -47,7 +47,8 @@ public class ShaderTemplate {
|
||||||
|
|
||||||
if (struct != null) {
|
if (struct != null) {
|
||||||
s = s.replace(name, struct.name);
|
s = s.replace(name, struct.name);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
missing.add(name);
|
missing.add(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,9 +40,6 @@ public class TaggedField {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "TaggedField{" +
|
return "TaggedField{" + "name='" + name + '\'' + ", type='" + type + '\'' + '}';
|
||||||
"name='" + name + '\'' +
|
|
||||||
", type='" + type + '\'' +
|
|
||||||
'}';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,8 @@ public class IndexedModel extends BufferedModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IndexedModel fromSequentialQuads(VertexFormat modelFormat, ByteBuffer quads, int vertices) {
|
public static IndexedModel fromSequentialQuads(VertexFormat modelFormat, ByteBuffer quads, int vertices) {
|
||||||
return new IndexedModel(modelFormat, quads, vertices, QuadConverter.getInstance().quads2Tris(vertices / 4));
|
return new IndexedModel(modelFormat, quads, vertices, QuadConverter.getInstance()
|
||||||
|
.quads2Tris(vertices / 4));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
@ParametersAreNonnullByDefault
|
@ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault
|
||||||
@MethodsReturnNonnullByDefault
|
|
||||||
package com.jozufozu.flywheel.backend;
|
package com.jozufozu.flywheel.backend;
|
||||||
|
|
||||||
import mcp.MethodsReturnNonnullByDefault;
|
|
||||||
|
|
||||||
import javax.annotation.ParametersAreNonnullByDefault;
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
|
||||||
|
import mcp.MethodsReturnNonnullByDefault;
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
package com.jozufozu.flywheel.config;
|
package com.jozufozu.flywheel.config;
|
||||||
|
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.Backend;
|
import com.jozufozu.flywheel.backend.Backend;
|
||||||
import com.jozufozu.flywheel.backend.OptifineHandler;
|
import com.jozufozu.flywheel.backend.OptifineHandler;
|
||||||
|
|
||||||
|
@ -12,9 +15,6 @@ import net.minecraft.util.text.TextFormatting;
|
||||||
import net.minecraftforge.api.distmarker.Dist;
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
public enum BooleanConfig {
|
public enum BooleanConfig {
|
||||||
ENGINE(() -> BooleanConfig::enabled),
|
ENGINE(() -> BooleanConfig::enabled),
|
||||||
NORMAL_OVERLAY(() -> BooleanConfig::normalOverlay),
|
NORMAL_OVERLAY(() -> BooleanConfig::normalOverlay),
|
||||||
|
|
|
@ -22,28 +22,24 @@ public class BooleanConfigCommand {
|
||||||
public ArgumentBuilder<CommandSource, ?> register() {
|
public ArgumentBuilder<CommandSource, ?> register() {
|
||||||
return Commands.literal(name)
|
return Commands.literal(name)
|
||||||
.executes(context -> {
|
.executes(context -> {
|
||||||
ServerPlayerEntity player = context.getSource().asPlayer();
|
ServerPlayerEntity player = context.getSource()
|
||||||
FlwPackets.channel.send(
|
.asPlayer();
|
||||||
PacketDistributor.PLAYER.with(() -> player),
|
FlwPackets.channel.send(PacketDistributor.PLAYER.with(() -> player), new SConfigureBooleanPacket(value, BooleanDirective.DISPLAY));
|
||||||
new SConfigureBooleanPacket(value, BooleanDirective.DISPLAY)
|
|
||||||
);
|
|
||||||
return Command.SINGLE_SUCCESS;
|
return Command.SINGLE_SUCCESS;
|
||||||
})
|
})
|
||||||
.then(Commands.literal("on").executes(context -> {
|
.then(Commands.literal("on")
|
||||||
ServerPlayerEntity player = context.getSource().asPlayer();
|
.executes(context -> {
|
||||||
FlwPackets.channel.send(
|
ServerPlayerEntity player = context.getSource()
|
||||||
PacketDistributor.PLAYER.with(() -> player),
|
.asPlayer();
|
||||||
new SConfigureBooleanPacket(value, BooleanDirective.TRUE)
|
FlwPackets.channel.send(PacketDistributor.PLAYER.with(() -> player), new SConfigureBooleanPacket(value, BooleanDirective.TRUE));
|
||||||
);
|
return Command.SINGLE_SUCCESS;
|
||||||
return Command.SINGLE_SUCCESS;
|
}))
|
||||||
}))
|
.then(Commands.literal("off")
|
||||||
.then(Commands.literal("off").executes(context -> {
|
.executes(context -> {
|
||||||
ServerPlayerEntity player = context.getSource().asPlayer();
|
ServerPlayerEntity player = context.getSource()
|
||||||
FlwPackets.channel.send(
|
.asPlayer();
|
||||||
PacketDistributor.PLAYER.with(() -> player),
|
FlwPackets.channel.send(PacketDistributor.PLAYER.with(() -> player), new SConfigureBooleanPacket(value, BooleanDirective.FALSE));
|
||||||
new SConfigureBooleanPacket(value, BooleanDirective.FALSE)
|
return Command.SINGLE_SUCCESS;
|
||||||
);
|
}));
|
||||||
return Command.SINGLE_SUCCESS;
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,18 @@
|
||||||
package com.jozufozu.flywheel.config;
|
package com.jozufozu.flywheel.config;
|
||||||
|
|
||||||
import com.mojang.brigadier.Command;
|
|
||||||
import com.mojang.brigadier.CommandDispatcher;
|
import com.mojang.brigadier.CommandDispatcher;
|
||||||
|
|
||||||
import net.minecraft.command.CommandSource;
|
import net.minecraft.command.CommandSource;
|
||||||
import net.minecraft.command.Commands;
|
import net.minecraft.command.Commands;
|
||||||
import net.minecraft.entity.player.ServerPlayerEntity;
|
|
||||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
import net.minecraftforge.fml.event.server.FMLServerStartingEvent;
|
import net.minecraftforge.fml.event.server.FMLServerStartingEvent;
|
||||||
import net.minecraftforge.fml.network.PacketDistributor;
|
|
||||||
|
|
||||||
public class FlwCommands {
|
public class FlwCommands {
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public static void onServerStarting(FMLServerStartingEvent event) {
|
public static void onServerStarting(FMLServerStartingEvent event) {
|
||||||
CommandDispatcher<CommandSource> dispatcher = event.getServer().getCommandManager().getDispatcher();
|
CommandDispatcher<CommandSource> dispatcher = event.getServer()
|
||||||
|
.getCommandManager()
|
||||||
|
.getDispatcher();
|
||||||
|
|
||||||
dispatcher.register(Commands.literal("flywheel")
|
dispatcher.register(Commands.literal("flywheel")
|
||||||
.then(new BooleanConfigCommand("backend", BooleanConfig.ENGINE).register())
|
.then(new BooleanConfigCommand("backend", BooleanConfig.ENGINE).register())
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
package com.jozufozu.flywheel.config;
|
package com.jozufozu.flywheel.config;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
|
||||||
import net.minecraftforge.common.ForgeConfigSpec;
|
import net.minecraftforge.common.ForgeConfigSpec;
|
||||||
import net.minecraftforge.common.ForgeConfigSpec.BooleanValue;
|
import net.minecraftforge.common.ForgeConfigSpec.BooleanValue;
|
||||||
import net.minecraftforge.fml.ModLoadingContext;
|
import net.minecraftforge.fml.ModLoadingContext;
|
||||||
|
|
||||||
import net.minecraftforge.fml.config.ModConfig;
|
import net.minecraftforge.fml.config.ModConfig;
|
||||||
|
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
|
||||||
|
|
||||||
public class FlwConfig {
|
public class FlwConfig {
|
||||||
|
|
||||||
private static final FlwConfig INSTANCE = new FlwConfig();
|
private static final FlwConfig INSTANCE = new FlwConfig();
|
||||||
|
@ -19,7 +18,8 @@ public class FlwConfig {
|
||||||
|
|
||||||
this.client = client.getLeft();
|
this.client = client.getLeft();
|
||||||
|
|
||||||
ModLoadingContext.get().registerConfig(ModConfig.Type.CLIENT, client.getRight());
|
ModLoadingContext.get()
|
||||||
|
.registerConfig(ModConfig.Type.CLIENT, client.getRight());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static FlwConfig get() {
|
public static FlwConfig get() {
|
||||||
|
@ -34,7 +34,8 @@ public class FlwConfig {
|
||||||
return client.normalDebug.get();
|
return client.normalDebug.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void init() { }
|
public static void init() {
|
||||||
|
}
|
||||||
|
|
||||||
public static class ClientConfig {
|
public static class ClientConfig {
|
||||||
public final BooleanValue enabled;
|
public final BooleanValue enabled;
|
||||||
|
@ -43,10 +44,10 @@ public class FlwConfig {
|
||||||
public ClientConfig(ForgeConfigSpec.Builder builder) {
|
public ClientConfig(ForgeConfigSpec.Builder builder) {
|
||||||
|
|
||||||
enabled = builder.comment("Enable or disable the entire engine")
|
enabled = builder.comment("Enable or disable the entire engine")
|
||||||
.define("enabled", true);
|
.define("enabled", true);
|
||||||
|
|
||||||
normalDebug = builder.comment("Enable or disable a debug overlay that colors pixels by their normal")
|
normalDebug = builder.comment("Enable or disable a debug overlay that colors pixels by their normal")
|
||||||
.define("normalDebug", false);
|
.define("normalDebug", false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,15 +14,15 @@ public class FlwPackets {
|
||||||
|
|
||||||
public static void registerPackets() {
|
public static void registerPackets() {
|
||||||
channel = NetworkRegistry.ChannelBuilder.named(CHANNEL_NAME)
|
channel = NetworkRegistry.ChannelBuilder.named(CHANNEL_NAME)
|
||||||
.serverAcceptedVersions(NETWORK_VERSION::equals)
|
.serverAcceptedVersions(NETWORK_VERSION::equals)
|
||||||
.clientAcceptedVersions(NETWORK_VERSION::equals)
|
.clientAcceptedVersions(NETWORK_VERSION::equals)
|
||||||
.networkProtocolVersion(() -> NETWORK_VERSION)
|
.networkProtocolVersion(() -> NETWORK_VERSION)
|
||||||
.simpleChannel();
|
.simpleChannel();
|
||||||
|
|
||||||
channel.messageBuilder(SConfigureBooleanPacket.class, 0, NetworkDirection.PLAY_TO_CLIENT)
|
channel.messageBuilder(SConfigureBooleanPacket.class, 0, NetworkDirection.PLAY_TO_CLIENT)
|
||||||
.decoder(SConfigureBooleanPacket::new)
|
.decoder(SConfigureBooleanPacket::new)
|
||||||
.encoder(SConfigureBooleanPacket::encode)
|
.encoder(SConfigureBooleanPacket::encode)
|
||||||
.consumer(SConfigureBooleanPacket::execute)
|
.consumer(SConfigureBooleanPacket::execute)
|
||||||
.add();
|
.add();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
package com.jozufozu.flywheel.config;
|
package com.jozufozu.flywheel.config;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import net.minecraft.network.PacketBuffer;
|
import net.minecraft.network.PacketBuffer;
|
||||||
import net.minecraftforge.fml.network.NetworkEvent;
|
import net.minecraftforge.fml.network.NetworkEvent;
|
||||||
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Thanks, @zelophed
|
* Thanks, @zelophed
|
||||||
*/
|
*/
|
||||||
|
@ -29,8 +29,10 @@ public class SConfigureBooleanPacket {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void execute(Supplier<NetworkEvent.Context> ctx) {
|
public void execute(Supplier<NetworkEvent.Context> ctx) {
|
||||||
target.receiver.get().accept(directive);
|
target.receiver.get()
|
||||||
ctx.get().setPacketHandled(true);
|
.accept(directive);
|
||||||
|
ctx.get()
|
||||||
|
.setPacketHandled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,8 +30,7 @@ public class AtlasStitcher {
|
||||||
public void onTextureStitch(TextureStitchEvent.Pre event) {
|
public void onTextureStitch(TextureStitchEvent.Pre event) {
|
||||||
if (!event.getMap()
|
if (!event.getMap()
|
||||||
.getId()
|
.getId()
|
||||||
.equals(PlayerContainer.BLOCK_ATLAS_TEXTURE))
|
.equals(PlayerContainer.BLOCK_ATLAS_TEXTURE)) return;
|
||||||
return;
|
|
||||||
|
|
||||||
sprites.forEach(StitchedSprite::reset);
|
sprites.forEach(StitchedSprite::reset);
|
||||||
sprites.stream()
|
sprites.stream()
|
||||||
|
|
|
@ -13,8 +13,6 @@ import com.jozufozu.flywheel.event.GatherContextEvent;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
import net.minecraftforge.api.distmarker.Dist;
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
|
||||||
import net.minecraftforge.fml.common.Mod;
|
|
||||||
|
|
||||||
@OnlyIn(Dist.CLIENT)
|
@OnlyIn(Dist.CLIENT)
|
||||||
public class Contexts {
|
public class Contexts {
|
||||||
|
@ -31,15 +29,13 @@ public class Contexts {
|
||||||
SpecMetaRegistry.register(WorldFog.LINEAR);
|
SpecMetaRegistry.register(WorldFog.LINEAR);
|
||||||
SpecMetaRegistry.register(WorldFog.EXP2);
|
SpecMetaRegistry.register(WorldFog.EXP2);
|
||||||
|
|
||||||
CRUMBLING = backend.register(new WorldContext<>(backend, CrumblingProgram::new)
|
CRUMBLING = backend.register(new WorldContext<>(backend, CrumblingProgram::new).withName(Names.CRUMBLING)
|
||||||
.withName(Names.CRUMBLING)
|
.withBuiltin(ShaderType.FRAGMENT, Names.CRUMBLING, "/builtin.frag")
|
||||||
.withBuiltin(ShaderType.FRAGMENT, Names.CRUMBLING, "/builtin.frag")
|
.withBuiltin(ShaderType.VERTEX, Names.CRUMBLING, "/builtin.vert"));
|
||||||
.withBuiltin(ShaderType.VERTEX, Names.CRUMBLING, "/builtin.vert"));
|
|
||||||
|
|
||||||
WORLD = backend.register(new WorldContext<>(backend, WorldProgram::new)
|
WORLD = backend.register(new WorldContext<>(backend, WorldProgram::new).withName(Names.WORLD)
|
||||||
.withName(Names.WORLD)
|
.withBuiltin(ShaderType.FRAGMENT, Names.WORLD, "/builtin.frag")
|
||||||
.withBuiltin(ShaderType.FRAGMENT, Names.WORLD, "/builtin.frag")
|
.withBuiltin(ShaderType.VERTEX, Names.WORLD, "/builtin.vert"));
|
||||||
.withBuiltin(ShaderType.VERTEX, Names.WORLD, "/builtin.vert"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Names {
|
public static class Names {
|
||||||
|
|
|
@ -9,12 +9,9 @@ public class Formats {
|
||||||
.addAttributes(CommonAttributes.VEC3, CommonAttributes.NORMAL, CommonAttributes.UV)
|
.addAttributes(CommonAttributes.VEC3, CommonAttributes.NORMAL, CommonAttributes.UV)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
public static final VertexFormat TRANSFORMED = litInstance()
|
public static final VertexFormat TRANSFORMED = litInstance().addAttributes(MatrixAttributes.MAT4, MatrixAttributes.MAT3)
|
||||||
.addAttributes(MatrixAttributes.MAT4,
|
|
||||||
MatrixAttributes.MAT3)
|
|
||||||
.build();
|
.build();
|
||||||
public static final VertexFormat ORIENTED = litInstance()
|
public static final VertexFormat ORIENTED = litInstance().addAttributes(CommonAttributes.VEC3, CommonAttributes.VEC3, CommonAttributes.QUATERNION)
|
||||||
.addAttributes(CommonAttributes.VEC3, CommonAttributes.VEC3, CommonAttributes.QUATERNION)
|
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
public static VertexFormat.Builder litInstance() {
|
public static VertexFormat.Builder litInstance() {
|
||||||
|
|
|
@ -15,14 +15,9 @@ public class FullscreenQuad {
|
||||||
|
|
||||||
private static final float[] vertices = {
|
private static final float[] vertices = {
|
||||||
// pos // tex
|
// pos // tex
|
||||||
-1.0f, -1.0f, 0.0f, 0.0f,
|
-1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f,
|
||||||
1.0f, 1.0f, 1.0f, 1.0f,
|
|
||||||
-1.0f, 1.0f, 0.0f, 1.0f,
|
|
||||||
|
|
||||||
-1.0f, -1.0f, 0.0f, 0.0f,
|
-1.0f, -1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f};
|
||||||
1.0f, -1.0f, 1.0f, 0.0f,
|
|
||||||
1.0f, 1.0f, 1.0f, 1.0f
|
|
||||||
};
|
|
||||||
|
|
||||||
private static final int bufferSize = vertices.length * 4;
|
private static final int bufferSize = vertices.length * 4;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package com.jozufozu.flywheel.core;
|
package com.jozufozu.flywheel.core;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.Backend;
|
|
||||||
import com.jozufozu.flywheel.backend.instancing.MaterialSpec;
|
import com.jozufozu.flywheel.backend.instancing.MaterialSpec;
|
||||||
import com.jozufozu.flywheel.core.materials.ModelData;
|
import com.jozufozu.flywheel.core.materials.ModelData;
|
||||||
import com.jozufozu.flywheel.core.materials.OrientedData;
|
import com.jozufozu.flywheel.core.materials.OrientedData;
|
||||||
|
@ -16,8 +15,10 @@ public class Materials {
|
||||||
public static final MaterialSpec<ModelData> TRANSFORMED = new MaterialSpec<>(Locations.MODEL, Programs.TRANSFORMED, Formats.UNLIT_MODEL, Formats.TRANSFORMED, ModelData::new);
|
public static final MaterialSpec<ModelData> TRANSFORMED = new MaterialSpec<>(Locations.MODEL, Programs.TRANSFORMED, Formats.UNLIT_MODEL, Formats.TRANSFORMED, ModelData::new);
|
||||||
|
|
||||||
public static void flwInit(GatherContextEvent event) {
|
public static void flwInit(GatherContextEvent event) {
|
||||||
event.getBackend().register(ORIENTED);
|
event.getBackend()
|
||||||
event.getBackend().register(TRANSFORMED);
|
.register(ORIENTED);
|
||||||
|
event.getBackend()
|
||||||
|
.register(TRANSFORMED);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Locations {
|
public static class Locations {
|
||||||
|
|
|
@ -82,7 +82,8 @@ public class QuadConverter {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void free() {
|
public void free() {
|
||||||
ebos.values().forEach(GlBuffer::delete);
|
ebos.values()
|
||||||
|
.forEach(GlBuffer::delete);
|
||||||
ebos.clear();
|
ebos.clear();
|
||||||
initCapacities();
|
initCapacities();
|
||||||
}
|
}
|
||||||
|
@ -100,7 +101,8 @@ public class QuadConverter {
|
||||||
ByteBuffer indices;
|
ByteBuffer indices;
|
||||||
if (bytes > stack.getSize()) {
|
if (bytes > stack.getSize()) {
|
||||||
indices = MemoryUtil.memAlloc(bytes); // not enough space on the preallocated stack
|
indices = MemoryUtil.memAlloc(bytes); // not enough space on the preallocated stack
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
stack.push();
|
stack.push();
|
||||||
indices = stack.malloc(bytes);
|
indices = stack.malloc(bytes);
|
||||||
}
|
}
|
||||||
|
@ -117,7 +119,8 @@ public class QuadConverter {
|
||||||
|
|
||||||
if (bytes > stack.getSize()) {
|
if (bytes > stack.getSize()) {
|
||||||
MemoryUtil.memFree(indices);
|
MemoryUtil.memFree(indices);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
stack.pop();
|
stack.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -102,8 +102,7 @@ public class WorldContext<P extends WorldProgram> extends ShaderContext<P> {
|
||||||
}
|
}
|
||||||
|
|
||||||
template = templateFactory.create(backend.sources);
|
template = templateFactory.create(backend.sources);
|
||||||
transformer = new ShaderTransformer()
|
transformer = new ShaderTransformer().pushStage(this::injectBuiltins)
|
||||||
.pushStage(this::injectBuiltins)
|
|
||||||
.pushStage(Shader::processIncludes)
|
.pushStage(Shader::processIncludes)
|
||||||
.pushStage(template)
|
.pushStage(template)
|
||||||
.pushStage(Shader::processIncludes);
|
.pushStage(Shader::processIncludes);
|
||||||
|
@ -150,8 +149,7 @@ public class WorldContext<P extends WorldProgram> extends ShaderContext<P> {
|
||||||
public void injectBuiltins(Shader shader) {
|
public void injectBuiltins(Shader shader) {
|
||||||
Matcher matcher = builtinPattern.matcher(shader.getSource());
|
Matcher matcher = builtinPattern.matcher(shader.getSource());
|
||||||
|
|
||||||
if (matcher.find())
|
if (matcher.find()) shader.setSource(matcher.replaceFirst(builtinSources.get(shader.type)));
|
||||||
shader.setSource(matcher.replaceFirst(builtinSources.get(shader.type)));
|
|
||||||
else
|
else
|
||||||
throw new ShaderLoadingException(String.format("%s is missing %s, cannot use in World Context", shader.type.name, declaration));
|
throw new ShaderLoadingException(String.format("%s is missing %s, cannot use in World Context", shader.type.name, declaration));
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,8 @@ public class ConditionalInstance<D extends InstanceData> {
|
||||||
if (shouldShow && instance == null) {
|
if (shouldShow && instance == null) {
|
||||||
instance = model.createInstance();
|
instance = model.createInstance();
|
||||||
if (setupFunc != null) setupFunc.accept(instance);
|
if (setupFunc != null) setupFunc.accept(instance);
|
||||||
} else if (!shouldShow && instance != null) {
|
}
|
||||||
|
else if (!shouldShow && instance != null) {
|
||||||
instance.delete();
|
instance.delete();
|
||||||
instance = null;
|
instance = null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,8 @@ public class GroupInstance<D extends InstanceData> extends AbstractCollection<D>
|
||||||
for (int i = size; i < count; i++) {
|
for (int i = size; i < count; i++) {
|
||||||
addInstance();
|
addInstance();
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
List<D> unnecessary = backing.subList(count, size);
|
List<D> unnecessary = backing.subList(count, size);
|
||||||
unnecessary.forEach(InstanceData::delete);
|
unnecessary.forEach(InstanceData::delete);
|
||||||
unnecessary.clear();
|
unnecessary.clear();
|
||||||
|
|
|
@ -37,10 +37,12 @@ public class SelectInstance<D extends InstanceData> {
|
||||||
current.delete();
|
current.delete();
|
||||||
current = null;
|
current = null;
|
||||||
}
|
}
|
||||||
} else if (i != last) {
|
}
|
||||||
|
else if (i != last) {
|
||||||
if (current != null) current.delete();
|
if (current != null) current.delete();
|
||||||
|
|
||||||
current = models.get(i).createInstance();
|
current = models.get(i)
|
||||||
|
.createInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
last = i;
|
last = i;
|
||||||
|
|
|
@ -44,7 +44,8 @@ public abstract class BasicData extends InstanceData implements IFlatLight<Basic
|
||||||
if (alpha) {
|
if (alpha) {
|
||||||
byte a = (byte) ((color >> 24) & 0xFF);
|
byte a = (byte) ((color >> 24) & 0xFF);
|
||||||
return setColor(r, g, b, a);
|
return setColor(r, g, b, a);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return setColor(r, g, b);
|
return setColor(r, g, b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,18 +82,7 @@ public class OrientedData extends BasicData {
|
||||||
public void write(MappedBuffer buf) {
|
public void write(MappedBuffer buf) {
|
||||||
super.write(buf);
|
super.write(buf);
|
||||||
|
|
||||||
buf.putFloatArray(new float[]{
|
buf.putFloatArray(new float[]{posX, posY, posZ, pivotX, pivotY, pivotZ, qX, qY, qZ, qW});
|
||||||
posX,
|
|
||||||
posY,
|
|
||||||
posZ,
|
|
||||||
pivotX,
|
|
||||||
pivotY,
|
|
||||||
pivotZ,
|
|
||||||
qX,
|
|
||||||
qY,
|
|
||||||
qZ,
|
|
||||||
qW
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,8 @@ public class ExtensibleGlProgram extends GlProgram {
|
||||||
list.add(extension);
|
list.add(extension);
|
||||||
}
|
}
|
||||||
this.extensions = list;
|
this.extensions = list;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
this.extensions = Collections.emptyList();
|
this.extensions = Collections.emptyList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -51,12 +52,12 @@ public class ExtensibleGlProgram extends GlProgram {
|
||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
builder.append("program ")
|
builder.append("program ")
|
||||||
.append(name)
|
.append(name)
|
||||||
.append('[');
|
.append('[');
|
||||||
|
|
||||||
for (IExtensionInstance extension : extensions) {
|
for (IExtensionInstance extension : extensions) {
|
||||||
builder.append(extension)
|
builder.append(extension)
|
||||||
.append('+');
|
.append('+');
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.append(']');
|
builder.append(']');
|
||||||
|
|
|
@ -35,13 +35,13 @@ public class GlFog {
|
||||||
int mode = getFogModeGlEnum();
|
int mode = getFogModeGlEnum();
|
||||||
|
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case GL11.GL_EXP2:
|
case GL11.GL_EXP2:
|
||||||
case GL11.GL_EXP:
|
case GL11.GL_EXP:
|
||||||
return WorldFog.EXP2;
|
return WorldFog.EXP2;
|
||||||
case GL11.GL_LINEAR:
|
case GL11.GL_LINEAR:
|
||||||
return WorldFog.LINEAR;
|
return WorldFog.LINEAR;
|
||||||
default:
|
default:
|
||||||
throw new UnsupportedOperationException("Unknown fog mode: " + mode);
|
throw new UnsupportedOperationException("Unknown fog mode: " + mode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,8 +34,8 @@ public class StateSensitiveMultiProgram<P extends GlProgram> implements IMultiPr
|
||||||
@Override
|
@Override
|
||||||
public P get() {
|
public P get() {
|
||||||
for (Pair<IContextCondition, P> variant : variants) {
|
for (Pair<IContextCondition, P> variant : variants) {
|
||||||
if (variant.getFirst().get())
|
if (variant.getFirst()
|
||||||
return variant.getSecond();
|
.get()) return variant.getSecond();
|
||||||
}
|
}
|
||||||
|
|
||||||
return fallback;
|
return fallback;
|
||||||
|
@ -44,7 +44,8 @@ public class StateSensitiveMultiProgram<P extends GlProgram> implements IMultiPr
|
||||||
@Override
|
@Override
|
||||||
public void delete() {
|
public void delete() {
|
||||||
for (Pair<IContextCondition, P> variant : variants) {
|
for (Pair<IContextCondition, P> variant : variants) {
|
||||||
variant.getSecond().delete();
|
variant.getSecond()
|
||||||
|
.delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
fallback.delete();
|
fallback.delete();
|
||||||
|
|
|
@ -7,8 +7,8 @@ import java.util.List;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.loading.Program;
|
import com.jozufozu.flywheel.backend.loading.Program;
|
||||||
import com.jozufozu.flywheel.core.shader.extension.IProgramExtension;
|
import com.jozufozu.flywheel.core.shader.extension.IProgramExtension;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.util.AnimationTickHolder;
|
import com.jozufozu.flywheel.util.AnimationTickHolder;
|
||||||
|
|
||||||
import net.minecraft.util.math.vector.Matrix4f;
|
import net.minecraft.util.math.vector.Matrix4f;
|
||||||
|
|
||||||
public class WorldProgram extends ExtensibleGlProgram {
|
public class WorldProgram extends ExtensibleGlProgram {
|
||||||
|
|
|
@ -9,7 +9,8 @@ public class UnitExtensionInstance implements IExtensionInstance {
|
||||||
|
|
||||||
public static final ResourceLocation NAME = new ResourceLocation(Flywheel.ID, "unit");
|
public static final ResourceLocation NAME = new ResourceLocation(Flywheel.ID, "unit");
|
||||||
|
|
||||||
public UnitExtensionInstance(GlProgram program) { }
|
public UnitExtensionInstance(GlProgram program) {
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void bind() {
|
public void bind() {
|
||||||
|
|
|
@ -17,7 +17,8 @@ public class NormalDebugStateProvider implements IBooleanStateProvider {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isTrue() {
|
public boolean isTrue() {
|
||||||
return FlwConfig.get().normalOverlayEnabled();
|
return FlwConfig.get()
|
||||||
|
.normalOverlayEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -12,16 +12,12 @@ import net.minecraft.util.ResourceLocation;
|
||||||
public class ProgramSpec {
|
public class ProgramSpec {
|
||||||
|
|
||||||
// TODO: Block model style inheritance?
|
// TODO: Block model style inheritance?
|
||||||
public static final Codec<ProgramSpec> CODEC = RecordCodecBuilder.create(instance ->
|
public static final Codec<ProgramSpec> CODEC = RecordCodecBuilder.create(instance -> instance.group(ResourceLocation.CODEC.fieldOf("vert")
|
||||||
instance.group(
|
.forGetter(ProgramSpec::getVert), ResourceLocation.CODEC.fieldOf("frag")
|
||||||
ResourceLocation.CODEC.fieldOf("vert")
|
.forGetter(ProgramSpec::getFrag), ProgramState.CODEC.listOf()
|
||||||
.forGetter(ProgramSpec::getVert),
|
.optionalFieldOf("states", Collections.emptyList())
|
||||||
ResourceLocation.CODEC.fieldOf("frag")
|
.forGetter(ProgramSpec::getStates))
|
||||||
.forGetter(ProgramSpec::getFrag),
|
.apply(instance, ProgramSpec::new));
|
||||||
ProgramState.CODEC.listOf()
|
|
||||||
.optionalFieldOf("states", Collections.emptyList())
|
|
||||||
.forGetter(ProgramSpec::getStates)
|
|
||||||
).apply(instance, ProgramSpec::new));
|
|
||||||
|
|
||||||
public ResourceLocation name;
|
public ResourceLocation name;
|
||||||
public final ResourceLocation vert;
|
public final ResourceLocation vert;
|
||||||
|
|
|
@ -13,35 +13,26 @@ import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
public class ProgramState {
|
public class ProgramState {
|
||||||
|
|
||||||
// TODO: Use Codec.dispatch
|
// TODO: Use Codec.dispatch
|
||||||
private static final Codec<IContextCondition> WHEN = Codec.either(
|
private static final Codec<IContextCondition> WHEN = Codec.either(BooleanContextCondition.BOOLEAN_SUGAR, SpecificValueCondition.CODEC)
|
||||||
BooleanContextCondition.BOOLEAN_SUGAR,
|
.flatXmap(either -> either.map(DataResult::success, DataResult::success), any -> {
|
||||||
SpecificValueCondition.CODEC
|
if (any instanceof BooleanContextCondition) {
|
||||||
).flatXmap(
|
return DataResult.success(Either.left((BooleanContextCondition) any));
|
||||||
either -> either.map(DataResult::success, DataResult::success),
|
}
|
||||||
any -> {
|
|
||||||
if (any instanceof BooleanContextCondition) {
|
|
||||||
return DataResult.success(Either.left((BooleanContextCondition) any));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (any instanceof SpecificValueCondition) {
|
if (any instanceof SpecificValueCondition) {
|
||||||
return DataResult.success(Either.right((SpecificValueCondition) any));
|
return DataResult.success(Either.right((SpecificValueCondition) any));
|
||||||
}
|
}
|
||||||
|
|
||||||
return DataResult.error("unknown context condition");
|
return DataResult.error("unknown context condition");
|
||||||
}
|
});
|
||||||
);
|
|
||||||
|
|
||||||
public static final Codec<ProgramState> CODEC = RecordCodecBuilder.create(state ->
|
public static final Codec<ProgramState> CODEC = RecordCodecBuilder.create(state -> state.group(WHEN.fieldOf("when")
|
||||||
state.group(
|
.forGetter(ProgramState::getContext), CodecUtil.oneOrMore(Codec.STRING)
|
||||||
WHEN.fieldOf("when")
|
.optionalFieldOf("define", Collections.emptyList())
|
||||||
.forGetter(ProgramState::getContext),
|
.forGetter(ProgramState::getDefines), CodecUtil.oneOrMore(IProgramExtension.CODEC)
|
||||||
CodecUtil.oneOrMore(Codec.STRING)
|
.optionalFieldOf("extend", Collections.emptyList())
|
||||||
.optionalFieldOf("define", Collections.emptyList())
|
.forGetter(ProgramState::getExtensions))
|
||||||
.forGetter(ProgramState::getDefines),
|
.apply(state, ProgramState::new));
|
||||||
CodecUtil.oneOrMore(IProgramExtension.CODEC)
|
|
||||||
.optionalFieldOf("extend", Collections.emptyList())
|
|
||||||
.forGetter(ProgramState::getExtensions)
|
|
||||||
).apply(state, ProgramState::new));
|
|
||||||
|
|
||||||
private final IContextCondition context;
|
private final IContextCondition context;
|
||||||
private final List<String> defines;
|
private final List<String> defines;
|
||||||
|
|
|
@ -8,10 +8,10 @@ import net.minecraft.util.ResourceLocation;
|
||||||
|
|
||||||
public class SpecificValueCondition implements IContextCondition {
|
public class SpecificValueCondition implements IContextCondition {
|
||||||
|
|
||||||
public static final Codec<SpecificValueCondition> CODEC = RecordCodecBuilder.create(condition -> condition.group(
|
public static final Codec<SpecificValueCondition> CODEC = RecordCodecBuilder.create(condition -> condition.group(IGameStateProvider.CODEC.fieldOf("provider")
|
||||||
IGameStateProvider.CODEC.fieldOf("provider").forGetter(SpecificValueCondition::contextProvider),
|
.forGetter(SpecificValueCondition::contextProvider), Codec.STRING.fieldOf("value")
|
||||||
Codec.STRING.fieldOf("value").forGetter(SpecificValueCondition::getValue)
|
.forGetter(SpecificValueCondition::getValue))
|
||||||
).apply(condition, SpecificValueCondition::new));
|
.apply(condition, SpecificValueCondition::new));
|
||||||
|
|
||||||
private final String required;
|
private final String required;
|
||||||
private final IGameStateProvider context;
|
private final IGameStateProvider context;
|
||||||
|
@ -37,6 +37,7 @@ public class SpecificValueCondition implements IContextCondition {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean get() {
|
public boolean get() {
|
||||||
return required.equals(context.getValue().toString());
|
return required.equals(context.getValue()
|
||||||
|
.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,15 +13,13 @@ public class EntityWorldHandler {
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public static void onEntityJoinWorld(EntityJoinWorldEvent event) {
|
public static void onEntityJoinWorld(EntityJoinWorldEvent event) {
|
||||||
if (event.getWorld().isRemote)
|
if (event.getWorld().isRemote) InstancedRenderDispatcher.getEntities(event.getWorld())
|
||||||
InstancedRenderDispatcher.getEntities(event.getWorld())
|
.queueAdd(event.getEntity());
|
||||||
.queueAdd(event.getEntity());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public static void onEntityLeaveWorld(EntityLeaveWorldEvent event) {
|
public static void onEntityLeaveWorld(EntityLeaveWorldEvent event) {
|
||||||
if (event.getWorld().isRemote)
|
if (event.getWorld().isRemote) InstancedRenderDispatcher.getEntities(event.getWorld())
|
||||||
InstancedRenderDispatcher.getEntities(event.getWorld())
|
.remove(event.getEntity());
|
||||||
.remove(event.getEntity());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,11 +24,13 @@ public class ForgeEvents {
|
||||||
|
|
||||||
ArrayList<String> right = event.getRight();
|
ArrayList<String> right = event.getRight();
|
||||||
|
|
||||||
String text = "Flywheel: " + Backend.getInstance().getBackendDescriptor();
|
String text = "Flywheel: " + Backend.getInstance()
|
||||||
|
.getBackendDescriptor();
|
||||||
if (right.size() < 10) {
|
if (right.size() < 10) {
|
||||||
right.add("");
|
right.add("");
|
||||||
right.add(text);
|
right.add(text);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
right.add(9, "");
|
right.add(9, "");
|
||||||
right.add(10, text);
|
right.add(10, text);
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,32 +46,17 @@ public class GridAlignedBB {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GridAlignedBB from(SectionPos pos) {
|
public static GridAlignedBB from(SectionPos pos) {
|
||||||
return new GridAlignedBB(pos.getWorldStartX(),
|
return new GridAlignedBB(pos.getWorldStartX(), pos.getWorldStartY(), pos.getWorldStartZ(), pos.getWorldEndX() + 1, pos.getWorldEndY() + 1, pos.getWorldEndZ() + 1);
|
||||||
pos.getWorldStartY(),
|
|
||||||
pos.getWorldStartZ(),
|
|
||||||
pos.getWorldEndX() + 1,
|
|
||||||
pos.getWorldEndY() + 1,
|
|
||||||
pos.getWorldEndZ() + 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GridAlignedBB from(BlockPos start, BlockPos end) {
|
public static GridAlignedBB from(BlockPos start, BlockPos end) {
|
||||||
return new GridAlignedBB(start.getX(),
|
return new GridAlignedBB(start.getX(), start.getY(), start.getZ(), end.getX() + 1, end.getY() + 1, end.getZ() + 1);
|
||||||
start.getY(),
|
|
||||||
start.getZ(),
|
|
||||||
end.getX() + 1,
|
|
||||||
end.getY() + 1,
|
|
||||||
end.getZ() + 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GridAlignedBB from(int sectionX, int sectionZ) {
|
public static GridAlignedBB from(int sectionX, int sectionZ) {
|
||||||
int startX = sectionX << 4;
|
int startX = sectionX << 4;
|
||||||
int startZ = sectionZ << 4;
|
int startZ = sectionZ << 4;
|
||||||
return new GridAlignedBB(startX,
|
return new GridAlignedBB(startX, 0, startZ, startX + 16, 256, startZ + 16);
|
||||||
0,
|
|
||||||
startZ,
|
|
||||||
startX + 16,
|
|
||||||
256,
|
|
||||||
startZ + 16);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static AxisAlignedBB toAABB(GridAlignedBB bb) {
|
public static AxisAlignedBB toAABB(GridAlignedBB bb) {
|
||||||
|
@ -83,12 +68,7 @@ public class GridAlignedBB {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean sameAs(GridAlignedBB other) {
|
public boolean sameAs(GridAlignedBB other) {
|
||||||
return minX == other.minX &&
|
return minX == other.minX && minY == other.minY && minZ == other.minZ && maxX == other.maxX && maxY == other.maxY && maxZ == other.maxZ;
|
||||||
minY == other.minY &&
|
|
||||||
minZ == other.minZ &&
|
|
||||||
maxX == other.maxX &&
|
|
||||||
maxY == other.maxY &&
|
|
||||||
maxZ == other.maxZ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void fixMinMax() {
|
public void fixMinMax() {
|
||||||
|
@ -125,9 +105,7 @@ public class GridAlignedBB {
|
||||||
|
|
||||||
public boolean empty() {
|
public boolean empty() {
|
||||||
// if any dimension has side length 0 this box contains no volume
|
// if any dimension has side length 0 this box contains no volume
|
||||||
return minX == maxX ||
|
return minX == maxX || minY == maxY || minZ == maxZ;
|
||||||
minY == maxY ||
|
|
||||||
minZ == maxZ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void translate(Vector3i by) {
|
public void translate(Vector3i by) {
|
||||||
|
@ -144,7 +122,8 @@ public class GridAlignedBB {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void mirrorAbout(Direction.Axis axis) {
|
public void mirrorAbout(Direction.Axis axis) {
|
||||||
Vector3i axisVec = Direction.getFacingFromAxis(Direction.AxisDirection.POSITIVE, axis).getDirectionVec();
|
Vector3i axisVec = Direction.getFacingFromAxis(Direction.AxisDirection.POSITIVE, axis)
|
||||||
|
.getDirectionVec();
|
||||||
int flipX = axisVec.getX() - 1;
|
int flipX = axisVec.getX() - 1;
|
||||||
int flipY = axisVec.getY() - 1;
|
int flipY = axisVec.getY() - 1;
|
||||||
int flipZ = axisVec.getZ() - 1;
|
int flipZ = axisVec.getZ() - 1;
|
||||||
|
@ -267,12 +246,7 @@ public class GridAlignedBB {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean contains(GridAlignedBB other) {
|
public boolean contains(GridAlignedBB other) {
|
||||||
return other.minX >= this.minX &&
|
return other.minX >= this.minX && other.maxX <= this.maxX && other.minY >= this.minY && other.maxY <= this.maxY && other.minZ >= this.minZ && other.maxZ <= this.maxZ;
|
||||||
other.maxX <= this.maxX &&
|
|
||||||
other.minY >= this.minY &&
|
|
||||||
other.maxY <= this.maxY &&
|
|
||||||
other.minZ >= this.minZ &&
|
|
||||||
other.maxZ <= this.maxZ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isContainedBy(GridAlignedBB other) {
|
public boolean isContainedBy(GridAlignedBB other) {
|
||||||
|
|
|
@ -24,8 +24,7 @@ public interface ILightUpdateListener {
|
||||||
default boolean onLightPacket(IBlockDisplayReader world, int chunkX, int chunkZ) {
|
default boolean onLightPacket(IBlockDisplayReader world, int chunkX, int chunkZ) {
|
||||||
GridAlignedBB changedVolume = GridAlignedBB.from(chunkX, chunkZ);
|
GridAlignedBB changedVolume = GridAlignedBB.from(chunkX, chunkZ);
|
||||||
|
|
||||||
if (onLightUpdate(world, LightType.BLOCK, changedVolume))
|
if (onLightUpdate(world, LightType.BLOCK, changedVolume)) return true;
|
||||||
return true;
|
|
||||||
|
|
||||||
return onLightUpdate(world, LightType.SKY, changedVolume);
|
return onLightUpdate(world, LightType.SKY, changedVolume);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,8 +27,7 @@ public class LightUpdater {
|
||||||
private static LightUpdater instance;
|
private static LightUpdater instance;
|
||||||
|
|
||||||
public static LightUpdater getInstance() {
|
public static LightUpdater getInstance() {
|
||||||
if (instance == null)
|
if (instance == null) instance = new LightUpdater();
|
||||||
instance = new LightUpdater();
|
|
||||||
|
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
@ -151,7 +150,8 @@ public class LightUpdater {
|
||||||
if (set == null) {
|
if (set == null) {
|
||||||
set = new LongRBTreeSet();
|
set = new LongRBTreeSet();
|
||||||
listeners.put(listener, set);
|
listeners.put(listener, set);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
set.forEach((LongConsumer) l -> {
|
set.forEach((LongConsumer) l -> {
|
||||||
WeakHashSet<ILightUpdateListener> listeningSections = lookup.get(l);
|
WeakHashSet<ILightUpdateListener> listeningSections = lookup.get(l);
|
||||||
|
|
||||||
|
|
|
@ -126,11 +126,13 @@ public class LightVolume {
|
||||||
sampleVolume = newSampleVolume;
|
sampleVolume = newSampleVolume;
|
||||||
|
|
||||||
copyLight(world, newArea);
|
copyLight(world, newArea);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
sampleVolume = newSampleVolume;
|
sampleVolume = newSampleVolume;
|
||||||
initialize(world);
|
initialize(world);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
setSampleVolume(newSampleVolume);
|
setSampleVolume(newSampleVolume);
|
||||||
int volume = textureVolume.volume();
|
int volume = textureVolume.volume();
|
||||||
if (volume * 2 > lightData.capacity()) {
|
if (volume * 2 > lightData.capacity()) {
|
||||||
|
@ -141,11 +143,9 @@ public class LightVolume {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void notifyLightUpdate(IBlockDisplayReader world, LightType type, GridAlignedBB changedVolume) {
|
public void notifyLightUpdate(IBlockDisplayReader world, LightType type, GridAlignedBB changedVolume) {
|
||||||
if (removed)
|
if (removed) return;
|
||||||
return;
|
|
||||||
|
|
||||||
if (!changedVolume.intersects(sampleVolume))
|
if (!changedVolume.intersects(sampleVolume)) return;
|
||||||
return;
|
|
||||||
changedVolume = changedVolume.intersect(sampleVolume); // compute the region contained by us that has dirty lighting data.
|
changedVolume = changedVolume.intersect(sampleVolume); // compute the region contained by us that has dirty lighting data.
|
||||||
|
|
||||||
if (type == LightType.BLOCK) copyBlock(world, changedVolume);
|
if (type == LightType.BLOCK) copyBlock(world, changedVolume);
|
||||||
|
@ -156,8 +156,7 @@ public class LightVolume {
|
||||||
if (removed) return;
|
if (removed) return;
|
||||||
|
|
||||||
GridAlignedBB changedVolume = GridAlignedBB.from(chunkX, chunkZ);
|
GridAlignedBB changedVolume = GridAlignedBB.from(chunkX, chunkZ);
|
||||||
if (!changedVolume.intersects(sampleVolume))
|
if (!changedVolume.intersects(sampleVolume)) return;
|
||||||
return;
|
|
||||||
changedVolume.intersectAssign(sampleVolume); // compute the region contained by us that has dirty lighting data.
|
changedVolume.intersectAssign(sampleVolume); // compute the region contained by us that has dirty lighting data.
|
||||||
|
|
||||||
copyLight(world, changedVolume);
|
copyLight(world, changedVolume);
|
||||||
|
|
|
@ -24,7 +24,8 @@ public class CancelEntityRenderMixin {
|
||||||
@Redirect(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/world/ClientWorld;getAllEntities()Ljava/lang/Iterable;"))
|
@Redirect(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/world/ClientWorld;getAllEntities()Ljava/lang/Iterable;"))
|
||||||
private Iterable<Entity> filterEntities(ClientWorld world) {
|
private Iterable<Entity> filterEntities(ClientWorld world) {
|
||||||
Iterable<Entity> entities = world.getAllEntities();
|
Iterable<Entity> entities = world.getAllEntities();
|
||||||
if (Backend.getInstance().canUseInstancing()) {
|
if (Backend.getInstance()
|
||||||
|
.canUseInstancing()) {
|
||||||
|
|
||||||
ArrayList<Entity> filtered = Lists.newArrayList(entities);
|
ArrayList<Entity> filtered = Lists.newArrayList(entities);
|
||||||
filtered.removeIf(entity -> entity instanceof IInstanceRendered && !((IInstanceRendered) entity).shouldRenderNormally());
|
filtered.removeIf(entity -> entity instanceof IInstanceRendered && !((IInstanceRendered) entity).shouldRenderNormally());
|
||||||
|
@ -37,7 +38,8 @@ public class CancelEntityRenderMixin {
|
||||||
@Group(name = "entityFilter")
|
@Group(name = "entityFilter")
|
||||||
@Redirect(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/ClassInheritanceMultiMap;iterator()Ljava/util/Iterator;"))
|
@Redirect(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/ClassInheritanceMultiMap;iterator()Ljava/util/Iterator;"))
|
||||||
private Iterator<Entity> filterEntitiesOF(ClassInheritanceMultiMap<Entity> classInheritanceMultiMap) {
|
private Iterator<Entity> filterEntitiesOF(ClassInheritanceMultiMap<Entity> classInheritanceMultiMap) {
|
||||||
if (Backend.getInstance().canUseInstancing()) {
|
if (Backend.getInstance()
|
||||||
|
.canUseInstancing()) {
|
||||||
|
|
||||||
ArrayList<Entity> filtered = Lists.newArrayList(classInheritanceMultiMap);
|
ArrayList<Entity> filtered = Lists.newArrayList(classInheritanceMultiMap);
|
||||||
filtered.removeIf(entity -> entity instanceof IInstanceRendered && !((IInstanceRendered) entity).shouldRenderNormally());
|
filtered.removeIf(entity -> entity instanceof IInstanceRendered && !((IInstanceRendered) entity).shouldRenderNormally());
|
||||||
|
|
|
@ -27,7 +27,8 @@ public class CancelTileEntityRenderMixin {
|
||||||
*/
|
*/
|
||||||
@Inject(at = @At("RETURN"), method = "getTileEntities", cancellable = true)
|
@Inject(at = @At("RETURN"), method = "getTileEntities", cancellable = true)
|
||||||
private void noRenderInstancedTiles(CallbackInfoReturnable<List<TileEntity>> cir) {
|
private void noRenderInstancedTiles(CallbackInfoReturnable<List<TileEntity>> cir) {
|
||||||
if (Backend.getInstance().canUseInstancing()) {
|
if (Backend.getInstance()
|
||||||
|
.canUseInstancing()) {
|
||||||
List<TileEntity> tiles = cir.getReturnValue();
|
List<TileEntity> tiles = cir.getReturnValue();
|
||||||
|
|
||||||
tiles.removeIf(tile -> tile instanceof IInstanceRendered && !((IInstanceRendered) tile).shouldRenderNormally());
|
tiles.removeIf(tile -> tile instanceof IInstanceRendered && !((IInstanceRendered) tile).shouldRenderNormally());
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
package com.jozufozu.flywheel.mixin;
|
package com.jozufozu.flywheel.mixin;
|
||||||
|
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||||
import com.mojang.blaze3d.platform.GlStateManager;
|
import com.mojang.blaze3d.platform.GlStateManager;
|
||||||
|
|
||||||
|
@ -11,11 +16,6 @@ import net.minecraft.util.math.vector.Matrix4f;
|
||||||
import net.minecraftforge.api.distmarker.Dist;
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|
||||||
|
|
||||||
@OnlyIn(Dist.CLIENT)
|
@OnlyIn(Dist.CLIENT)
|
||||||
@Mixin(WorldRenderer.class)
|
@Mixin(WorldRenderer.class)
|
||||||
public class FixFabulousDepthMixin {
|
public class FixFabulousDepthMixin {
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package com.jozufozu.flywheel.mixin;
|
package com.jozufozu.flywheel.mixin;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.backend.OptifineHandler;
|
||||||
|
|
||||||
import org.lwjgl.opengl.GL20;
|
import org.lwjgl.opengl.GL20;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
@ -36,9 +38,7 @@ public class RenderHooksMixin {
|
||||||
private ClientWorld world;
|
private ClientWorld world;
|
||||||
|
|
||||||
@Inject(at = @At(value = "INVOKE", target = "net.minecraft.client.renderer.WorldRenderer.updateChunks(J)V"), method = "render")
|
@Inject(at = @At(value = "INVOKE", target = "net.minecraft.client.renderer.WorldRenderer.updateChunks(J)V"), method = "render")
|
||||||
private void setupFrame(MatrixStack stack, float p_228426_2_, long p_228426_3_, boolean p_228426_5_,
|
private void setupFrame(MatrixStack stack, float p_228426_2_, long p_228426_3_, boolean p_228426_5_, ActiveRenderInfo info, GameRenderer gameRenderer, LightTexture lightTexture, Matrix4f p_228426_9_, CallbackInfo ci) {
|
||||||
ActiveRenderInfo info, GameRenderer gameRenderer, LightTexture lightTexture, Matrix4f p_228426_9_,
|
|
||||||
CallbackInfo ci) {
|
|
||||||
MinecraftForge.EVENT_BUS.post(new BeginFrameEvent(world, stack, info, gameRenderer, lightTexture));
|
MinecraftForge.EVENT_BUS.post(new BeginFrameEvent(world, stack, info, gameRenderer, lightTexture));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,12 +48,12 @@ public class RenderHooksMixin {
|
||||||
* This should probably be a forge event.
|
* This should probably be a forge event.
|
||||||
*/
|
*/
|
||||||
@Inject(at = @At("TAIL"), method = "renderLayer")
|
@Inject(at = @At("TAIL"), method = "renderLayer")
|
||||||
private void renderLayer(RenderType type, MatrixStack stack, double camX, double camY, double camZ,
|
private void renderLayer(RenderType type, MatrixStack stack, double camX, double camY, double camZ, CallbackInfo ci) {
|
||||||
CallbackInfo ci) {
|
|
||||||
Matrix4f view = stack.peek()
|
Matrix4f view = stack.peek()
|
||||||
.getModel();
|
.getModel();
|
||||||
Matrix4f viewProjection = view.copy();
|
Matrix4f viewProjection = view.copy();
|
||||||
viewProjection.multiplyBackward(Backend.getInstance().getProjectionMatrix());
|
viewProjection.multiplyBackward(Backend.getInstance()
|
||||||
|
.getProjectionMatrix());
|
||||||
|
|
||||||
MinecraftForge.EVENT_BUS.post(new RenderLayerEvent(world, type, viewProjection, camX, camY, camZ));
|
MinecraftForge.EVENT_BUS.post(new RenderLayerEvent(world, type, viewProjection, camX, camY, camZ));
|
||||||
GL20.glUseProgram(0);
|
GL20.glUseProgram(0);
|
||||||
|
@ -61,33 +61,30 @@ public class RenderHooksMixin {
|
||||||
|
|
||||||
@Inject(at = @At("TAIL"), method = "loadRenderers")
|
@Inject(at = @At("TAIL"), method = "loadRenderers")
|
||||||
private void refresh(CallbackInfo ci) {
|
private void refresh(CallbackInfo ci) {
|
||||||
Backend.getInstance().refresh();
|
Backend.getInstance()
|
||||||
|
.refresh();
|
||||||
|
|
||||||
MinecraftForge.EVENT_BUS.post(new ReloadRenderersEvent(world));
|
MinecraftForge.EVENT_BUS.post(new ReloadRenderersEvent(world));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Inject(at =
|
@Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/WorldRenderer;checkEmpty(Lcom/mojang/blaze3d/matrix/MatrixStack;)V", ordinal = 2 // after the game renders the breaking overlay normally
|
||||||
@At(
|
), method = "render")
|
||||||
value = "INVOKE",
|
private void renderBlockBreaking(MatrixStack stack, float p_228426_2_, long p_228426_3_, boolean p_228426_5_, ActiveRenderInfo info, GameRenderer gameRenderer, LightTexture lightTexture, Matrix4f p_228426_9_, CallbackInfo ci) {
|
||||||
target = "Lnet/minecraft/client/renderer/WorldRenderer;checkEmpty(Lcom/mojang/blaze3d/matrix/MatrixStack;)V",
|
if (!Backend.getInstance()
|
||||||
ordinal = 2 // after the game renders the breaking overlay normally
|
.available()) return;
|
||||||
),
|
|
||||||
method = "render")
|
|
||||||
private void renderBlockBreaking(MatrixStack stack, float p_228426_2_, long p_228426_3_, boolean p_228426_5_,
|
|
||||||
ActiveRenderInfo info, GameRenderer gameRenderer, LightTexture lightTexture, Matrix4f p_228426_9_,
|
|
||||||
CallbackInfo ci) {
|
|
||||||
if (!Backend.getInstance().available())
|
|
||||||
return;
|
|
||||||
|
|
||||||
Matrix4f view = stack.peek()
|
Matrix4f view = stack.peek()
|
||||||
.getModel();
|
.getModel();
|
||||||
Matrix4f viewProjection = view.copy();
|
Matrix4f viewProjection = view.copy();
|
||||||
viewProjection.multiplyBackward(Backend.getInstance().getProjectionMatrix());
|
viewProjection.multiplyBackward(Backend.getInstance()
|
||||||
|
.getProjectionMatrix());
|
||||||
|
|
||||||
Vector3d cameraPos = info.getProjectedView();
|
Vector3d cameraPos = info.getProjectedView();
|
||||||
InstancedRenderDispatcher.renderBreaking(world, viewProjection, cameraPos.x, cameraPos.y, cameraPos.z);
|
InstancedRenderDispatcher.renderBreaking(world, viewProjection, cameraPos.x, cameraPos.y, cameraPos.z);
|
||||||
GL20.glUseProgram(0);
|
|
||||||
|
if (!OptifineHandler.usingShaders())
|
||||||
|
GL20.glUseProgram(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Instancing
|
// Instancing
|
||||||
|
|
|
@ -26,8 +26,8 @@ public class ShaderCloseMixin {
|
||||||
if (OptifineHandler.optifineInstalled() && screen instanceof VideoSettingsScreen) {
|
if (OptifineHandler.optifineInstalled() && screen instanceof VideoSettingsScreen) {
|
||||||
Screen old = this.currentScreen;
|
Screen old = this.currentScreen;
|
||||||
if (old != null && old.getClass()
|
if (old != null && old.getClass()
|
||||||
.getName()
|
.getName()
|
||||||
.startsWith(OptifineHandler.SHADER_PACKAGE)) {
|
.startsWith(OptifineHandler.SHADER_PACKAGE)) {
|
||||||
OptifineHandler.refresh();
|
OptifineHandler.refresh();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,8 @@ public abstract class StoreProjectionMatrixMixin {
|
||||||
@Inject(method = "loadProjectionMatrix", at = @At("TAIL"))
|
@Inject(method = "loadProjectionMatrix", at = @At("TAIL"))
|
||||||
private void onProjectionMatrixLoad(Matrix4f projection, CallbackInfo ci) {
|
private void onProjectionMatrixLoad(Matrix4f projection, CallbackInfo ci) {
|
||||||
if (shouldCopy) {
|
if (shouldCopy) {
|
||||||
Backend.getInstance().setProjectionMatrix(projection.copy());
|
Backend.getInstance()
|
||||||
|
.setProjectionMatrix(projection.copy());
|
||||||
shouldCopy = false;
|
shouldCopy = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,8 +23,7 @@ public class TileRemoveMixin {
|
||||||
|
|
||||||
@Inject(at = @At("TAIL"), method = "remove")
|
@Inject(at = @At("TAIL"), method = "remove")
|
||||||
private void onRemove(CallbackInfo ci) {
|
private void onRemove(CallbackInfo ci) {
|
||||||
if (world instanceof ClientWorld)
|
if (world instanceof ClientWorld) InstancedRenderDispatcher.getTiles(this.world)
|
||||||
InstancedRenderDispatcher.getTiles(this.world)
|
.remove((TileEntity) (Object) this);
|
||||||
.remove((TileEntity) (Object) this);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,16 +43,15 @@ public abstract class LightUpdateMixin extends AbstractChunkProvider {
|
||||||
.entrySet()
|
.entrySet()
|
||||||
.stream()
|
.stream()
|
||||||
.filter(entry -> SectionPos.toChunk(entry.getKey()
|
.filter(entry -> SectionPos.toChunk(entry.getKey()
|
||||||
.getY()) == sectionY)
|
.getY()) == sectionY)
|
||||||
.map(Map.Entry::getValue)
|
.map(Map.Entry::getValue)
|
||||||
.forEach(InstancedRenderDispatcher.getTiles(world)::onLightUpdate);
|
.forEach(InstancedRenderDispatcher.getTiles(world)::onLightUpdate);
|
||||||
|
|
||||||
if (sectionY >= 0) // TODO: 1.17
|
if (sectionY >= 0) // TODO: 1.17
|
||||||
chunk.getEntityLists()[sectionY]
|
chunk.getEntityLists()[sectionY].forEach(InstancedRenderDispatcher.getEntities(world)::onLightUpdate);
|
||||||
.forEach(InstancedRenderDispatcher.getEntities(world)::onLightUpdate);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LightUpdater.getInstance()
|
LightUpdater.getInstance()
|
||||||
.onLightUpdate(world, type, pos.asLong());
|
.onLightUpdate(world, type, pos.asLong());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,14 +26,13 @@ public class NetworkLightUpdateMixin {
|
||||||
RenderWork.enqueue(() -> {
|
RenderWork.enqueue(() -> {
|
||||||
ClientWorld world = Minecraft.getInstance().world;
|
ClientWorld world = Minecraft.getInstance().world;
|
||||||
|
|
||||||
if (world == null)
|
if (world == null) return;
|
||||||
return;
|
|
||||||
|
|
||||||
int chunkX = packet.getChunkX();
|
int chunkX = packet.getChunkX();
|
||||||
int chunkZ = packet.getChunkZ();
|
int chunkZ = packet.getChunkZ();
|
||||||
|
|
||||||
Chunk chunk = world.getChunkProvider()
|
Chunk chunk = world.getChunkProvider()
|
||||||
.getChunk(chunkX, chunkZ, false);
|
.getChunk(chunkX, chunkZ, false);
|
||||||
|
|
||||||
if (chunk != null) {
|
if (chunk != null) {
|
||||||
chunk.getTileEntityMap()
|
chunk.getTileEntityMap()
|
||||||
|
@ -46,7 +45,7 @@ public class NetworkLightUpdateMixin {
|
||||||
}
|
}
|
||||||
|
|
||||||
LightUpdater.getInstance()
|
LightUpdater.getInstance()
|
||||||
.onLightPacket(world, chunkX, chunkZ);
|
.onLightPacket(world, chunkX, chunkZ);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,8 +10,7 @@ public class AngleHelper {
|
||||||
*/
|
*/
|
||||||
public static float horizontalAngle(Direction facing) {
|
public static float horizontalAngle(Direction facing) {
|
||||||
float angle = facing.getHorizontalAngle();
|
float angle = facing.getHorizontalAngle();
|
||||||
if (facing.getAxis() == Axis.X)
|
if (facing.getAxis() == Axis.X) angle = -angle;
|
||||||
angle = -angle;
|
|
||||||
return angle;
|
return angle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,12 +18,12 @@ public class AngleHelper {
|
||||||
* Same as {@link #horizontalAngle(Direction)}, but returns 0 instead of -90 for vertical directions.
|
* Same as {@link #horizontalAngle(Direction)}, but returns 0 instead of -90 for vertical directions.
|
||||||
*/
|
*/
|
||||||
public static float horizontalAngleNew(Direction facing) {
|
public static float horizontalAngleNew(Direction facing) {
|
||||||
if (facing.getAxis().isVertical()) {
|
if (facing.getAxis()
|
||||||
|
.isVertical()) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
float angle = facing.getHorizontalAngle();
|
float angle = facing.getHorizontalAngle();
|
||||||
if (facing.getAxis() == Axis.X)
|
if (facing.getAxis() == Axis.X) angle = -angle;
|
||||||
angle = -angle;
|
|
||||||
return angle;
|
return angle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,14 +32,12 @@ public class AngleHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float rad(double angle) {
|
public static float rad(double angle) {
|
||||||
if (angle == 0)
|
if (angle == 0) return 0;
|
||||||
return 0;
|
|
||||||
return (float) (angle / 180 * Math.PI);
|
return (float) (angle / 180 * Math.PI);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float deg(double angle) {
|
public static float deg(double angle) {
|
||||||
if (angle == 0)
|
if (angle == 0) return 0;
|
||||||
return 0;
|
|
||||||
return (float) (angle * 180 / Math.PI);
|
return (float) (angle * 180 / Math.PI);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,41 +1,41 @@
|
||||||
package com.jozufozu.flywheel.util;
|
package com.jozufozu.flywheel.util;
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.world.IWorld;
|
|
||||||
|
|
||||||
public class AnimationTickHolder {
|
public class AnimationTickHolder {
|
||||||
|
|
||||||
private static int ticks;
|
private static int ticks;
|
||||||
private static int paused_ticks;
|
private static int paused_ticks;
|
||||||
|
|
||||||
public static void reset() {
|
public static void reset() {
|
||||||
ticks = 0;
|
ticks = 0;
|
||||||
paused_ticks = 0;
|
paused_ticks = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void tick() {
|
public static void tick() {
|
||||||
if (!Minecraft.getInstance()
|
if (!Minecraft.getInstance()
|
||||||
.isGamePaused()) {
|
.isGamePaused()) {
|
||||||
ticks = (ticks + 1) % 1_728_000; // wrap around every 24 hours so we maintain enough floating point precision
|
ticks = (ticks + 1) % 1_728_000; // wrap around every 24 hours so we maintain enough floating point precision
|
||||||
} else {
|
}
|
||||||
paused_ticks = (paused_ticks + 1) % 1_728_000;
|
else {
|
||||||
}
|
paused_ticks = (paused_ticks + 1) % 1_728_000;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static int getTicks() {
|
public static int getTicks() {
|
||||||
return getTicks(false);
|
return getTicks(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getTicks(boolean includePaused) {
|
public static int getTicks(boolean includePaused) {
|
||||||
return includePaused ? ticks + paused_ticks : ticks;
|
return includePaused ? ticks + paused_ticks : ticks;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float getRenderTime() {
|
public static float getRenderTime() {
|
||||||
return getTicks() + getPartialTicks();
|
return getTicks() + getPartialTicks();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float getPartialTicks() {
|
public static float getPartialTicks() {
|
||||||
Minecraft mc = Minecraft.getInstance();
|
Minecraft mc = Minecraft.getInstance();
|
||||||
return (mc.isGamePaused() ? mc.renderPartialTicksPaused : mc.getRenderPartialTicks());
|
return (mc.isGamePaused() ? mc.renderPartialTicksPaused : mc.getRenderPartialTicks());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -194,20 +194,26 @@ public class BakedQuadWrapper {
|
||||||
|
|
||||||
public void refresh() {
|
public void refresh() {
|
||||||
vertexSize = FORMAT.getIntegerSize();
|
vertexSize = FORMAT.getIntegerSize();
|
||||||
for (int elementId = 0; elementId < FORMAT.getElements().size(); elementId++) {
|
for (int elementId = 0; elementId < FORMAT.getElements()
|
||||||
VertexFormatElement element = FORMAT.getElements().get(elementId);
|
.size(); elementId++) {
|
||||||
|
VertexFormatElement element = FORMAT.getElements()
|
||||||
|
.get(elementId);
|
||||||
int intOffset = FORMAT.getOffset(elementId) / Integer.BYTES;
|
int intOffset = FORMAT.getOffset(elementId) / Integer.BYTES;
|
||||||
if (element.getUsage() == VertexFormatElement.Usage.POSITION) {
|
if (element.getUsage() == VertexFormatElement.Usage.POSITION) {
|
||||||
position = intOffset;
|
position = intOffset;
|
||||||
} else if (element.getUsage() == VertexFormatElement.Usage.COLOR) {
|
}
|
||||||
|
else if (element.getUsage() == VertexFormatElement.Usage.COLOR) {
|
||||||
color = intOffset;
|
color = intOffset;
|
||||||
} else if (element.getUsage() == VertexFormatElement.Usage.UV) {
|
}
|
||||||
|
else if (element.getUsage() == VertexFormatElement.Usage.UV) {
|
||||||
if (element.getIndex() == 0) {
|
if (element.getIndex() == 0) {
|
||||||
texture = intOffset;
|
texture = intOffset;
|
||||||
} else if (element.getIndex() == 2) {
|
}
|
||||||
|
else if (element.getIndex() == 2) {
|
||||||
light = intOffset;
|
light = intOffset;
|
||||||
}
|
}
|
||||||
} else if (element.getUsage() == VertexFormatElement.Usage.NORMAL) {
|
}
|
||||||
|
else if (element.getUsage() == VertexFormatElement.Usage.NORMAL) {
|
||||||
normal = intOffset;
|
normal = intOffset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,13 +27,13 @@ public class BufferBuilderReader {
|
||||||
size = vertexCount * formatSize;
|
size = vertexCount * formatSize;
|
||||||
|
|
||||||
// TODO: adjust the getters based on the input format
|
// TODO: adjust the getters based on the input format
|
||||||
// ImmutableList<VertexFormatElement> elements = vertexFormat.getElements();
|
// ImmutableList<VertexFormatElement> elements = vertexFormat.getElements();
|
||||||
// for (int i = 0, size = elements.size(); i < size; i++) {
|
// for (int i = 0, size = elements.size(); i < size; i++) {
|
||||||
// VertexFormatElement element = elements.get(i);
|
// VertexFormatElement element = elements.get(i);
|
||||||
// int offset = vertexFormat.getOffset(i);
|
// int offset = vertexFormat.getOffset(i);
|
||||||
//
|
//
|
||||||
// element.getUsage()
|
// element.getUsage()
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isEmpty() {
|
public boolean isEmpty() {
|
||||||
|
|
|
@ -13,14 +13,13 @@ public class CodecUtil {
|
||||||
*/
|
*/
|
||||||
public static <T> Codec<List<T>> oneOrMore(Codec<T> codec) {
|
public static <T> Codec<List<T>> oneOrMore(Codec<T> codec) {
|
||||||
return Codec.either(codec.listOf(), codec)
|
return Codec.either(codec.listOf(), codec)
|
||||||
.xmap(
|
.xmap(either -> either.map(l -> l, Collections::singletonList), list -> {
|
||||||
either -> either.map(l -> l, Collections::singletonList),
|
if (list.size() == 1) {
|
||||||
list -> {
|
return Either.right(list.get(0));
|
||||||
if (list.size() == 1) {
|
}
|
||||||
return Either.right(list.get(0));
|
else {
|
||||||
} else {
|
return Either.left(list);
|
||||||
return Either.left(list);
|
}
|
||||||
}
|
});
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,8 +38,7 @@ public class Pair<F, S> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(final Object obj) {
|
public boolean equals(final Object obj) {
|
||||||
if (obj == this)
|
if (obj == this) return true;
|
||||||
return true;
|
|
||||||
if (obj instanceof Pair) {
|
if (obj instanceof Pair) {
|
||||||
final Pair<?, ?> other = (Pair<?, ?>) obj;
|
final Pair<?, ?> other = (Pair<?, ?>) obj;
|
||||||
return Objects.equals(first, other.first) && Objects.equals(second, other.second);
|
return Objects.equals(first, other.first) && Objects.equals(second, other.second);
|
||||||
|
|
|
@ -29,70 +29,31 @@ public class RenderUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float[] writeMatrixStack(MatrixStack stack) {
|
public static float[] writeMatrixStack(MatrixStack stack) {
|
||||||
return writeMatrixStack(stack.peek().getModel(), stack.peek().getNormal());
|
return writeMatrixStack(stack.peek()
|
||||||
|
.getModel(), stack.peek()
|
||||||
|
.getNormal());
|
||||||
}
|
}
|
||||||
|
|
||||||
// GPUs want matrices in column major order.
|
// GPUs want matrices in column major order.
|
||||||
public static float[] writeMatrixStack(Matrix4f model, Matrix3f normal) {
|
public static float[] writeMatrixStack(Matrix4f model, Matrix3f normal) {
|
||||||
return new float[]{
|
return new float[]{model.a00, model.a10, model.a20, model.a30, model.a01, model.a11, model.a21, model.a31, model.a02, model.a12, model.a22, model.a32, model.a03, model.a13, model.a23, model.a33, normal.a00, normal.a10, normal.a20, normal.a01, normal.a11, normal.a21, normal.a02, normal.a12, normal.a22,};
|
||||||
model.a00,
|
|
||||||
model.a10,
|
|
||||||
model.a20,
|
|
||||||
model.a30,
|
|
||||||
model.a01,
|
|
||||||
model.a11,
|
|
||||||
model.a21,
|
|
||||||
model.a31,
|
|
||||||
model.a02,
|
|
||||||
model.a12,
|
|
||||||
model.a22,
|
|
||||||
model.a32,
|
|
||||||
model.a03,
|
|
||||||
model.a13,
|
|
||||||
model.a23,
|
|
||||||
model.a33,
|
|
||||||
normal.a00,
|
|
||||||
normal.a10,
|
|
||||||
normal.a20,
|
|
||||||
normal.a01,
|
|
||||||
normal.a11,
|
|
||||||
normal.a21,
|
|
||||||
normal.a02,
|
|
||||||
normal.a12,
|
|
||||||
normal.a22,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float[] writeMatrix(Matrix4f model) {
|
public static float[] writeMatrix(Matrix4f model) {
|
||||||
return new float[]{
|
return new float[]{model.a00, model.a10, model.a20, model.a30, model.a01, model.a11, model.a21, model.a31, model.a02, model.a12, model.a22, model.a32, model.a03, model.a13, model.a23, model.a33,};
|
||||||
model.a00,
|
|
||||||
model.a10,
|
|
||||||
model.a20,
|
|
||||||
model.a30,
|
|
||||||
model.a01,
|
|
||||||
model.a11,
|
|
||||||
model.a21,
|
|
||||||
model.a31,
|
|
||||||
model.a02,
|
|
||||||
model.a12,
|
|
||||||
model.a22,
|
|
||||||
model.a32,
|
|
||||||
model.a03,
|
|
||||||
model.a13,
|
|
||||||
model.a23,
|
|
||||||
model.a33,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Supplier<MatrixStack> rotateToFace(Direction facing) {
|
public static Supplier<MatrixStack> rotateToFace(Direction facing) {
|
||||||
return () -> {
|
return () -> {
|
||||||
MatrixStack stack = new MatrixStack();
|
MatrixStack stack = new MatrixStack();
|
||||||
// MatrixStacker.of(stack)
|
// MatrixStacker.of(stack)
|
||||||
// .centre()
|
// .centre()
|
||||||
// .rotateY(AngleHelper.horizontalAngle(facing))
|
// .rotateY(AngleHelper.horizontalAngle(facing))
|
||||||
// .rotateX(AngleHelper.verticalAngle(facing))
|
// .rotateX(AngleHelper.verticalAngle(facing))
|
||||||
// .unCentre();
|
// .unCentre();
|
||||||
stack.peek().getModel().setTranslation(0.5f, 0.5f, 0.5f);
|
stack.peek()
|
||||||
|
.getModel()
|
||||||
|
.setTranslation(0.5f, 0.5f, 0.5f);
|
||||||
stack.multiply(Vector3f.POSITIVE_Y.getDegreesQuaternion(AngleHelper.horizontalAngle(facing)));
|
stack.multiply(Vector3f.POSITIVE_Y.getDegreesQuaternion(AngleHelper.horizontalAngle(facing)));
|
||||||
stack.multiply(Vector3f.POSITIVE_X.getDegreesQuaternion(AngleHelper.verticalAngle(facing)));
|
stack.multiply(Vector3f.POSITIVE_X.getDegreesQuaternion(AngleHelper.verticalAngle(facing)));
|
||||||
stack.translate(-0.5f, -0.5f, -0.5f);
|
stack.translate(-0.5f, -0.5f, -0.5f);
|
||||||
|
|
|
@ -57,7 +57,7 @@ public class WeakHashSet<T> extends AbstractSet<T> {
|
||||||
@Override
|
@Override
|
||||||
public Iterator<T> iterator() {
|
public Iterator<T> iterator() {
|
||||||
return map.keySet()
|
return map.keySet()
|
||||||
.iterator();
|
.iterator();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -88,13 +88,12 @@ public class WeakHashSet<T> extends AbstractSet<T> {
|
||||||
@Override
|
@Override
|
||||||
public Object[] toArray() {
|
public Object[] toArray() {
|
||||||
return map.keySet()
|
return map.keySet()
|
||||||
.toArray();
|
.toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean containsAll(Collection<?> c) {
|
public boolean containsAll(Collection<?> c) {
|
||||||
return stream()
|
return stream().allMatch(map::containsKey);
|
||||||
.allMatch(map::containsKey);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -7,7 +7,6 @@ import java.util.function.Consumer;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
|
||||||
|
|
||||||
import net.minecraft.world.IWorld;
|
import net.minecraft.world.IWorld;
|
||||||
|
|
||||||
|
@ -24,8 +23,7 @@ public class WorldAttached<T> {
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public T get(IWorld world) {
|
public T get(IWorld world) {
|
||||||
T t = attached.get(world);
|
T t = attached.get(world);
|
||||||
if (t != null)
|
if (t != null) return t;
|
||||||
return t;
|
|
||||||
T entry = factory.apply(world);
|
T entry = factory.apply(world);
|
||||||
put(world, entry);
|
put(world, entry);
|
||||||
return entry;
|
return entry;
|
||||||
|
|
Loading…
Reference in a new issue